React Tile Manager 개요
Ignite UI for React Tile Manager 구성 요소를 사용하면 개별 타일에 콘텐츠를 표시할 수 있습니다. 이를 통해 사용자는 이러한 타일을 재정렬하고 크기를 조정하여 상호 작용할 수 있으므로 기본 설정에 따라 콘텐츠의 레이아웃과 모양을 자유롭게 사용자 지정할 수 있습니다. 이러한 유연성은 콘텐츠를 보다 개인화되고 효율적인 방식으로 보고 관리할 수 있도록 하여 사용자 환경을 향상시킵니다.
React 타일 관리자 예제
다음 Ignite UI for React Tile Manager Example은 작동 중인 컴포넌트를 보여줍니다.
EXAMPLE
TSX
index.css
layout.css
import React from "react" ;
import ReactDOM from "react-dom/client" ;
import "./index.css" ;
import "./layout.css" ;
import { IgrCard, IgrCardHeader, IgrCardContent, IgrTileManager, IgrTile, IgrIcon, IgrList, IgrListItem, IgrAvatar, registerIconFromText } from "@infragistics/igniteui-react" ;
import "igniteui-webcomponents/themes/light/bootstrap.css" ;
const home = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>' ;
const search = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"><path d="M0 0h24v24H0z" fill="none"/><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>' ;
const favorite = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>' ;
registerIconFromText("home" , home, "material" );
registerIconFromText("search" , search, "material" );
registerIconFromText("favorite" , favorite, "material" );
export default class Overview extends React.Component <any, any> {
constructor (props: any ) {
super (props);
}
public render (): JSX .Element {
return (
<div className ="container sample center" >
<IgrTileManager id ="tile-manager1" columnCount ={3} gap ="20px" resizeMode ="always" dragMode ="tile-header" >
<IgrTile rowSpan ={3} >
<h3 slot ="title" > Order info</h3 >
<IgrList className ="list" >
<IgrListItem >
<IgrAvatar slot ="start" shape ="circle" className ="avatar" >
<IgrIcon name ="list" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
<div slot ="title" className ="content" >
<p > OrderID</p >
<p > 10293 </p >
</div >
</IgrListItem >
<IgrListItem >
<IgrAvatar slot ="start" shape ="circle" className ="avatar" >
<IgrIcon name ="list" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
<div slot ="title" className ="content" >
<p > Customer Name</p >
<p > Tortuga Restaurante</p >
</div >
</IgrListItem >
<IgrListItem >
<IgrAvatar slot ="start" shape ="circle" className ="avatar" >
<IgrIcon name ="calendar" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
<div slot ="title" className ="content" >
<p > Order Date</p >
<p > August 29 , 1996 </p >
</div >
</IgrListItem >
<IgrListItem >
<IgrAvatar slot ="start" shape ="circle" className ="avatar" >
<IgrIcon name ="calendar" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
<div slot ="title" className ="content" >
<p > Shipped Date</p >
<p > September 11 , 1996 </p >
</div >
</IgrListItem >
<IgrListItem >
<IgrAvatar slot ="start" shape ="circle" className ="avatar" >
<IgrIcon name ="list" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
<div slot ="title" className ="content" >
<p > Product Name</p >
<p > Carnavon Tigers</p >
</div >
</IgrListItem >
<IgrListItem >
<IgrAvatar slot ="start" shape ="circle" className ="avatar" >
<IgrIcon name ="list" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
<div slot ="title" className ="content" >
<p > Ship Country</p >
<p > Mexico</p >
</div >
</IgrListItem >
</IgrList >
</IgrTile >
<IgrTile col-span ="2" row-span ="2" >
<h3 slot ="title" > Order Line Items</h3 >
<div className ="group" >
<IgrCard className ="card" >
<div className ="group_1" >
<IgrCardHeader >
<div slot ="thumbnail" >
<IgrAvatar shape ="circle" >
<IgrIcon name ="product" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
</div >
<h3 slot ="title" > Carnavon Tigers</h3 >
</IgrCardHeader >
<IgrCardContent className ="column" >
<div className ="body-content" >
<span > Quantity</span > <span > 12 </span >
</div >
<div className ="body-content" >
<span > Unit Price</span > <span > $50 </span >
</div >
</IgrCardContent >
</div >
</IgrCard >
<IgrCard className ="card" >
<div className ="group_1" >
<IgrCardHeader >
<div slot ="thumbnail" >
<IgrAvatar shape ="circle" >
<IgrIcon name ="product" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
</div >
<h3 slot ="title" > Guarana Fantastica</h3 >
</IgrCardHeader >
<IgrCardContent className ="column" >
<div className ="body-content" >
<span > Quantity</span > <span > 10 </span >
</div >
<div className ="body-content" >
<span > Unit Price</span > <span > $4 </span >
</div >
</IgrCardContent >
</div >
</IgrCard >
<IgrCard className ="card" >
<div className ="group_1" >
<IgrCardHeader >
<div slot ="thumbnail" >
<IgrAvatar shape ="circle" >
<IgrIcon name ="product" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
</div >
<h3 slot ="title" > Vegie-spread</h3 >
</IgrCardHeader >
<IgrCardContent className ="column" >
<div className ="body-content" >
<span > Quantity</span > <span > 5 </span >
</div >
<div className ="body-content" >
<span > Unit Price</span > <span > $35 </span >
</div >
</IgrCardContent >
</div >
</IgrCard >
<IgrCard className ="card" >
<div className ="group_1" >
<IgrCardHeader >
<div slot ="thumbnail" >
<IgrAvatar shape ="circle" >
<IgrIcon name ="product" collection ="material" className ="material-icons" > </IgrIcon >
</IgrAvatar >
</div >
<h3 slot ="title" > Rhonbrau Klosterbier</h3 >
</IgrCardHeader >
<IgrCardContent className ="column" >
<div className ="body-content" >
<span > Quantity</span > <span > 7 </span >
</div >
<div className ="body-content" >
<span > Unit Price</span > <span > $6 </span >
</div >
</IgrCardContent >
</div >
</IgrCard >
</div >
</IgrTile >
<IgrTile >
<h3 slot ="title" > Order Value</h3 >
<div className ="string" >
<h1 > $8.66 K</h1 >
</div >
</IgrTile >
<IgrTile >
<h3 slot ="title" > Item quantity</h3 >
<div className ="string" >
<h1 > 4 </h1 >
</div >
</IgrTile >
</IgrTileManager >
</div >
);
}
}
const root = ReactDOM.createRoot (document.getElementById("root" ));
root.render (<Overview /> );
tsx コピー igc-tile-manager {
margin-bottom : 5px ;
}
.group {
display : flex;
flex-direction : row;
flex-wrap : wrap;
margin-top : 15px ;
}
.card {
min-height : 30px ;
width : calc (50% - 30px );
margin : 0 15px 15px 15px
}
igc-card-content {
color : var (--content-text-color);
}
.body-content {
width : 100% ;
display : flex;
flex-direction : row;
justify-content : space-between;
align-items : center;
}
.string {
text-align : center;
margin-top : 50px ;
color : var (--ig-gray-800 );
}
.sample {
overflow : auto;
}css コピー
iframe 권한 정책으로 인해 이 예제의 전체 화면 버튼은 오른쪽 상단 모서리에 있는 '전체 화면으로 확장' 버튼을 클릭하여 예제를 독립 실행형 모드로 열 때만 작동합니다.
용법
기본 IgrTileManager 타일 레이아웃 동작을 제공하여 최대화 또는 일반 상태의 타일 배치를 관리합니다. 타일은 서로 독립적으로 크기를 조정할 수 있으며 복잡한 레이아웃을 형성하는 데 사용할 수 있습니다. 최종 사용자는 타일을 끌어다 놓아 순서를 변경할 수 있으므로 유연하고 직관적인 환경을 제공할 수 있습니다.
타일 매니저는 사용할 수 있는 두 가지 컴포넌트를 제공합니다.
IgrTile - 이 컴포넌트는 타일 매니저 내에 표시되는 개별 타일을 나타냅니다.
IgrTileManager - 모든 타일 구성 요소를 포함하는 기본 구성 요소로, 전체 타일 레이아웃의 컨테이너 역할을 합니다.
시작하기
Tile Manager를 사용하려면 먼저 다음 명령을 실행하여 Ignite UI for React 설치해야 합니다.
npm install igniteui-react
cmd
타일 매니저를 사용하기 전에 다음과 같이 가져와야 합니다.
import { IgrTile, IgrTileManager } from 'igniteui-react' ;
import 'igniteui-webcomponents/themes/light/bootstrap.css' ;
tsx
이제 React Tile Manager의 기본 구성부터 시작할 수 있습니다.
<IgrTileManager >
<IgrTile >
<p > Tile 1 </p >
</IgrTile >
<IgrTile >
<p > Tile 2 </p >
</IgrTile >
<IgrTile >
<p > Tile 3 </p >
</IgrTile >
</IgrTileManager >
tsx
Ignite UI for React에 대한 전체 소개를 보려면 시작하기 항목을 읽어보세요.
공들여 나열한 것
열과 행
Tile Manager의 그리드 열 수를 지정할 수 있습니다. 이렇게 하려면 속성을 원하는 열 수로 설정 columnCount 하기만 하면 됩니다. 숫자가 1보다 작거나 속성이 설정되지 않은 경우 타일 관리자는 각 열의 너비가 200px 이상이고 사용 가능한 공간을 균등하게 공유하도록 확장되는 가능한 한 많은 열을 만듭니다. 뷰포트 치수가 변경되면 공간 사용을 최대화하기 위해 타일도 재정렬됩니다.
<IgrTileManager columnCount ={2} >
<IgrTile >
<span slot ="title" > Tile 1 header</span >
<p > Tile 1 Content</p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Tile 2 Content</p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 3 header</span >
<p > Tile 3 Content</p >
</IgrTile >
...
</IgrTileManager >
tsx
이 코드 스니펫에서 타일 관리자의 3개 타일은 2개의 행과 2개의 열로 정렬됩니다.
간격
타일 매니저에서 사용할 수 있는 또 다른 속성은 타일 사이의 공간을 정의하는 속성입니다 gap . 속성의 값은 gap 숫자 뒤에 길이 단위가 오는 것이어야 합니다(예: px, rem, em, ...). 이 값은 타일 사이의 수평 간격(너비)과 수직 간격(높이) 모두에 적용됩니다.
<IgrTileManager gap ="20px" >
<IgrTile >
<span slot ="title" > Tile 1 header</span >
<p > Tile 1 Content</p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Tile 2 Content</p >
</IgrTile >
...
</IgrTileManager >
tsx
최소 너비 및 높이
또한 Tile Manager에서 열()의 최소 너비와 minColumnWidth 행(minRowHeight )의 최소 높이를 설정하는 속성도 있습니다. gap 속성과 마찬가지로 이러한 속성의 값은 숫자 뒤에 길이 단위가 와야 합니다. 이 값은 Tile Manager에서 모든 열의 최소 너비와 모든 행의 최소 높이를 정의합니다.
<IgrTileManager minColumnWidth ="200px" minRowHeight ="150px" >
<IgrTile >
<span slot ="title" > Tile 1 header</span >
<p > Tile 1 Content</p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Tile 2 Content</p >
</IgrTile >
...
</IgrTileManager >
tsx
예
EXAMPLE
TSX
index.css
layout.css
import React from "react" ;
import ReactDOM from "react-dom/client" ;
import "./index.css" ;
import "./layout.css" ;
import { IgrTileManager, IgrTile, IgrInput } from "@infragistics/igniteui-react" ;
import "igniteui-webcomponents/themes/light/bootstrap.css" ;
export default class ColumnGap extends React.Component <any, any> {
private tileManagerRef = React .createRef<IgrTileManager > ();
constructor (props: any ) {
super (props);
}
private onInputChange = (event: CustomEvent) => {
const tileManager = this .tileManagerRef.current;
const input = event.target as IgrInput;
switch (input.label) {
case 'Columns Number' : tileManager.columnCount = parseInt(input.value);
break ;
case 'Gap Size' : tileManager.gap = input.value;
break ;
}
}
public render (): JSX .Element {
return (
<div className ="container sample center" >
<div className ="inputWrapper" >
<IgrInput label ="Columns Number" id ="rowIn" onChange ={this.onInputChange} > </IgrInput >
<IgrInput label ="Gap Size" placeholder ="10px" onChange ={this.onInputChange} > </IgrInput >
</div >
<IgrTileManager id ="tile-manager1" gap ="10px" ref ={this.tileManagerRef} >
<IgrTile disableFullscreen disableMaximize >
<div className ="picture" >
<img src ="https://picsum.photos/1048/998" alt ="picture" />
</div >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<div className ="picture" >
<img src ="https://picsum.photos/1049/999" alt ="picture" />
</div >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<div className ="picture" >
<img src ="https://picsum.photos/1050/1000" alt ="picture" />
</div >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<div className ="picture" >
<img src ="https://picsum.photos/1051/1001" alt ="picture" />
</div >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<div className ="picture" >
<img src ="https://picsum.photos/1052/1002" alt ="picture" />
</div >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<div className ="picture" >
<img src ="https://picsum.photos/1053/1003" alt ="picture" />
</div >
</IgrTile >
</IgrTileManager >
</div >
);
}
}
const root = ReactDOM.createRoot (document.getElementById("root" ));
root.render (<ColumnGap /> );
tsx コピー p {
font-size : 20px ;
padding : 10px ;
}
.sample {
overflow : auto;
}
igc-input {
width : min-content;
--ig-size: var (--ig-size-small);
margin-right : 50px ;
}
img {
height : 100% ;
width : 100% ;
}
.inputWrapper {
display : flex;
margin-left : 22px ;
margin-bottom : 12px ;
}
css コピー
타일 구성 요소
Tile 구성 요소에는 각 타일에 대해 개별적으로 설정할 수 있는 속성이 있습니다. 이러한 속성 중 일부는 다음과 같습니다.
<IgrTileManager >
<IgrTile colSpan ={2} disableResize ={true} >
<span slot ="title" > Tile 1 header</span >
<p > Tile 1 Content</p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Tile 2 Content</p >
</IgrTile >
...
</IgrTileManager >
tsx
Tile 컴포넌트는 또한 사용할 수 있는 여러 슬롯을 노출합니다.
슬롯 이름
설명
title
타일 헤더에 대한 콘텐츠입니다.
fullscreen-action
기본 전체 화면 작업 내용을 덮어씁니다.
maximize-action
Overwrite the default maximize action content.
actions
기본 작업 후에 렌더링된 사용자 지정 콘텐츠.
side-adorner
Overwrite the default horizontal resize adorner.
corner-adorner
Overwrite the default diagonal resize adorner.
bottom-adorner
Overwrite the default vertical resize adorner.
기본적으로 헤더 섹션에는 두 개의 작업 버튼이 포함되어 있습니다.
이 단추는 maximize 타일의 콘텐츠를 확대하여 타일 관리자의 전체 너비를 채우므로 콘텐츠를 더 넓게 볼 수 있습니다.
이 fullscreen 단추를 사용하면 타일을 사용자의 브라우저에서 전체 화면 모드로 열 수 있습니다.
두 버튼 중 하나만 표시하려면 또는 disableFullscreen 속성을 설정할 disableMaximize 수 있습니다. 모양을 사용자 지정하려면 최대화 단추 fullscreen-action에 슬롯을 사용하거나 전체 화면 단추에 슬롯을 사용할 maximize-action 수 있습니다.
<IgrTileManager >
<IgrTile disableFullscreen ={true} >
<IgrIconButton slot ="maximize-actions" name ="north_east" collection ="material" >
</IgrIconButton >
<p > Tile 1 Content</p >
</IgrTile >
</IgrTileManager >
tsx
또한 두 작업 버튼을 모두 비활성화하고 기본 설정에 따라 사용자 지정 버튼을 만들 수 있는 옵션도 있습니다.
EXAMPLE
TSX
index.css
layout.css
import React from "react" ;
import ReactDOM from "react-dom/client" ;
import "./index.css" ;
import "./layout.css" ;
import { IgrTileManager, IgrTile, IgrIconButton, registerIconFromText } from "@infragistics/igniteui-react" ;
import "igniteui-webcomponents/themes/light/bootstrap.css" ;
export default class Actions extends React.Component <any, any> {
constructor (props: any ) {
super (props);
const northEast =
'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="m216-160-56-56 464-464H360v-80h400v400h-80v-264L216-160Z"/></svg>' ;
registerIconFromText('north_east' , northEast, 'material' );
const southWest =
'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M200-200v-400h80v264l464-464 56 56-464 464h264v80H200Z"/></svg>' ;
registerIconFromText('south_west' , southWest, 'material' );
const more =
'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M480-160q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm0-240q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm0-240q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Z"/></svg>' ;
registerIconFromText('more' , more, 'material' );
const chart =
'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M640-160v-280h160v280H640Zm-240 0v-640h160v640H400Zm-240 0v-440h160v440H160Z"/></svg>' ;
registerIconFromText('chart' , chart, 'material' );
}
private onCustomOneClick = (event: React .MouseEvent) => {
const tile = (event.currentTarget as HTMLElement).closest('igc-tile' );
if (tile) {
tile.maximized = !tile.maximized;
const actionsSlot = tile.querySelector('[slot="actions"]' ) as HTMLElement;
const currentBtn = event.currentTarget as HTMLElement;
if (currentBtn) {
if (
tile.maximized
) {
currentBtn.setAttribute('name' , 'south_west' );
currentBtn.setAttribute('aria-label' , 'collapse' );
const chartBtn = document.createElement('igc-icon-button' );
chartBtn.classList.add('additional-action' );
chartBtn.setAttribute('slot' , 'actions' );
chartBtn.setAttribute('variant' , 'flat' );
chartBtn.setAttribute('collection' , 'material' );
chartBtn.setAttribute('name' , 'chart' );
chartBtn.setAttribute('aria-label' , 'chart' );
const moreBtn = document.createElement('igc-icon-button' );
moreBtn.classList.add('additional-action' );
moreBtn.setAttribute('slot' , 'actions' );
moreBtn.setAttribute('variant' , 'flat' );
moreBtn.setAttribute('collection' , 'material' );
moreBtn.setAttribute('name' , 'more' );
moreBtn.setAttribute('aria-label' , 'more' );
tile.append(chartBtn);
tile.append(moreBtn);
} else {
currentBtn.setAttribute('name' , 'north_east' );
currentBtn.setAttribute('aria-label' , 'expand' );
const additionalButtons =
actionsSlot.parentElement?.querySelectorAll('.additional-action' );
additionalButtons?.forEach((btn) => btn.remove());
}
}
}
};
private onCustomTwoClick = (event: React .MouseEvent) => {
const tile = (event.currentTarget as HTMLElement).closest('igc-tile' );
if (tile) {
tile.maximized = !tile.maximized;
const currentBtn = event.currentTarget as HTMLElement;
if (currentBtn) {
if (
tile.maximized
) {
currentBtn.setAttribute('name' , 'south_west' );
currentBtn.setAttribute('aria-label' , 'collapse' );
}
else {
currentBtn.setAttribute('name' , 'north_east' );
currentBtn.setAttribute('aria-label' , 'expand' );
}
}
}
};
public render (): JSX .Element {
return (
<div className ="container sample center" >
<IgrTileManager id ="tile-manager1" columnCount ={2} gap ="20px" >
<IgrTile >
<h3 slot ="title" > Default Actions</h3 >
<p > This tile has default actions and title.</p >
</IgrTile >
<IgrTile disableFullscreen >
<h3 slot ="title" > No Fullscreen Action</h3 >
<p > Fullscreen is disabled via property.</p >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<h3 slot ="title" > Custom Actions</h3 >
<IgrIconButton id ="customOne" onClick ={this.onCustomOneClick} slot ="actions" variant ="flat" collection ="material" name ="north_east"
aria-label ="north_east" > </IgrIconButton >
<p > Replace the default actions with custom ones, and include extra actions when the tile is maximized.</p >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<IgrIconButton id ="customTwo" onClick ={this.onCustomTwoClick} slot ="actions" variant ="flat" collection ="material"
name ="north_east" aria-label ="north_east" > </IgrIconButton >
<p > Display only custom actions in the header.</p >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<h3 slot ="title" > Only title</h3 >
<p > Display only title in the header.</p >
</IgrTile >
<IgrTile disableFullscreen disableMaximize >
<p > Content only.</p >
</IgrTile >
</IgrTileManager >
</div >
);
}
}
const root = ReactDOM.createRoot (document.getElementById("root" ));
root.render (<Actions /> );
tsx コピー igc-tile-manager {
margin-bottom : 5px ;
}
igc-tile:nth-child (n + 3 ):nth-child (-n + 4 )::part (actions) {
padding : 13px 16px ;
}
igc-tile:nth-child (n+3 )::part (header ) {
padding : 0px ;
}
igc-tile:nth-child (5 )::part (header ) {
padding : 18px 0 18px 0 ;
}
p , igc-tile:nth-child (3 ) h3 , igc-tile:nth-child (5 ) h3 {
margin-left : 20px ;
}
igc-tile:nth-last-child (1 ) p {
margin-top : 30px ;
}css コピー
이 예에서는 Ignite UI Icon Button 구성 요소를 사용하여 사용자 지정 작업 버튼을 만들었습니다.
크기 조정
타일 관리자의 크기 조정은 세 가지 다른 크기 조정 표시기를 사용하여 타일 크기를 조정할 수 있는 기능입니다.
Side Adorner : 열 범위를 수정하여 너비를 조정합니다.
아래쪽 표시기 : 행 범위를 수정하여 높이를 조정합니다.
모서리 표시기 : 너비와 높이를 동시에 조정합니다.
부드러운 크기 조정을 위해 타일의 크기를 직접 수정하는 대신 고스트 요소가 사용됩니다. 이 요소는 원래 타일 위에 나타나 크기 조정이 시작될 때 현재 크기를 표시하며 사용자가 크기 조정 핸들을 드래그하면 실시간으로 업데이트됩니다.
고스트 요소가 사용 가능한 그리드 공간을 초과하면 그리드 한계 내에서 가능한 가장 큰 스팬으로 자동 조정됩니다.
Tile Manager는 타일의 크기가 변경될 때 자동으로 재정렬되어 빈 공간이 최소화되도록 합니다. 그렇기 때문에 타일을 확장하면 인접한 타일이 새로운 위치로 밀려날 수 있고, 축소하면 다른 타일이 동적으로 채울 수 있는 틈이 생깁니다. 이렇게 하면 Tile Manager가 겹치는 타일 없이 가능한 한 컴팩트하게 유지되고 모든 이동이 정의된 그리드 구조 내에서 유지됩니다.
이 resizeMode 속성을 사용하여 Tile Manager에서 크기 조정이 적용되는 방식을 제어할 수 있습니다. or로 none 설정할 수 있으며, hover always 이는 크기 조정 표시기가 표시되는 시기를 결정합니다. 기본값은 none 타일의 크기를 조정할 수 없습니다.
<IgrTileManager resizeMode ="hover" >
<IgrTile >
<p > Tile 1 </p >
</IgrTile >
<IgrTile >
<p > Tile 2 </p >
</IgrTile >
</IgrTileManager >
tsx
아래 예에서 세 가지 상태의 차이점을 볼 수 있습니다.
EXAMPLE
TSX
index.css
layout.css
import React from "react" ;
import ReactDOM from "react-dom/client" ;
import "./index.css" ;
import "./layout.css" ;
import { IgrTileManager, IgrTile, IgrRadio, IgrRadioGroup, IgrInput } from "@infragistics/igniteui-react" ;
import "igniteui-webcomponents/themes/light/bootstrap.css" ;
import { IgcRadioChangeEventArgs } from "igniteui-webcomponents/components/radio/radio" ;
export default class Actions extends React.Component <any, any> {
private tileManagerRef = React .createRef<IgrTileManager > ();
constructor (props: any ) {
super (props);
}
private onRadioChange = (event: CustomEvent<IgcRadioChangeEventArgs > ) => {
const radio = event.target as IgrRadio;
(this .tileManagerRef.current as IgrTileManager).resizeMode = radio.value as any ;
};
private onInputChange = (event: CustomEvent) => {
const tileManager = this .tileManagerRef.current;
const input = event.target as IgrInput;
switch (input.label) {
case 'Minimum Column Width' : tileManager.minColumnWidth = input.value;
break ;
case 'Minimum Row Height' : tileManager.minRowHeight = input.value;
break ;
}
}
public render (): JSX .Element {
return (
<div className ="container sample center" >
<div className ="inputWrapper" >
<IgrRadioGroup id ="resize" alignment ="horizontal" onChange ={this.onRadioChange} >
<IgrRadio name ="resize" value ="always" checked > Always</IgrRadio >
<IgrRadio name ="resize" value ="hover" > Hover</IgrRadio >
<IgrRadio name ="resize" value ="none" > None</IgrRadio >
</IgrRadioGroup >
<IgrInput label ="Minimum Column Width" placeholder ="200px" type ={ "text "} onChange ={this.onInputChange} > </IgrInput >
<IgrInput label ="Minimum Row Height" placeholder ="200px" type ={ "text "} onChange ={this.onInputChange} > </IgrInput >
</div >
<IgrTileManager resize-mode ="always" gap ="20px" ref ={this.tileManagerRef} >
<IgrTile >
<span slot ="title" > Tile 1 header</span >
<p > Content for Tile 1 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Content for Tile 2 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 3 header</span >
<p > Content for Tile 3 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 4 header</span >
<p > Content for Tile 4 </p >
</IgrTile >
</IgrTileManager >
</div >
);
}
}
const root = ReactDOM.createRoot (document.getElementById("root" ));
root.render (<Actions /> );
tsx コピー span {
font-size : 30px ;
}
p {
font-size : 18px ;
padding-left : 20px ;
}
igc-radio-group {
margin : 0 50px 0 22px ;
width : fit-content;
padding : 4px 15px ;
border : 2px solid var (--ig-primary-700 );
background-color : var (--ig-gray-300 );
align-self : end;
}
.sample {
overflow : auto;
}
.inputWrapper {
display : flex;
margin-bottom : 12px ;
}
igc-input {
width : min-content;
--ig-size: var (--ig-size-small);
margin-right : 50px ;
}css コピー
맞추기
타일은 전체 그리드 단위로 크기가 조정되므로 전체 열 또는 행에 의해서만 확장되거나 축소될 수 있습니다. 고스트 요소는 중간 지점을 지나 확장될 때 다음 열 또는 행으로 스냅되고 중간 지점을 지나 축소될 때 이전 열 또는 행으로 스냅됩니다. 이는 모든 표시기(아래쪽, 측면 및 모서리)에 적용되어 타일이 항상 그리드에 정렬된 상태로 유지되도록 합니다.
그리드 간격도 고려하여 크기를 조정하는 동안 레이아웃을 일관되게 유지합니다.
제한 사항
크기 조정 프로세스에는 몇 가지 제약 조건과 제한 사항이 있습니다.
재주문
드래그 앤 드롭 기능을 사용하여 Tile Manager에서 타일을 재정렬할 수 있습니다. 기본적으로 타일은 드래그할 수 없습니다. 이 기능을 활성화하려면 dragMode 속성을 Tile Manager의 tile 또는 tile-header.
이 tile 옵션을 사용하면 개별 타일의 아무 곳이나 길게 클릭하여 드래그를 시작할 수 있습니다.
이 tile-header 옵션을 사용하면 타일의 헤더 섹션을 길게 클릭하여 드래그 프로세스를 시작할 수 있습니다.
타일이 최대화 또는 전체 화면 상태일 때는 타일을 드래그할 수 없습니다.
크기 조정과 유사하게, 드래그 앤 드롭 프로세스를 시작하면 잡은 타일 아래에 고스트 요소가 나타납니다. 타일을 드래그하면 고스트 요소가 함께 이동하여 다른 타일의 순서를 실시간으로 동적으로 변경합니다. 이렇게 하면 타일을 놓을 때 타일 그리드가 어떻게 보이는지 미리 볼 수 있습니다.
<IgrTileManager dragMode ="tile-header" >
<IgrTile >
<span slot ="title" > Tile 1 header</span >
<p > Tile 1 Content</p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Tile 2 Content</p >
</IgrTile >
</IgrTileManager >
tsx
EXAMPLE
TSX
index.css
layout.css
import React from "react" ;
import ReactDOM from "react-dom/client" ;
import "./index.css" ;
import "./layout.css" ;
import { IgrTileManager, IgrTile, IgrRadio, IgrRadioGroup } from "@infragistics/igniteui-react" ;
import "igniteui-webcomponents/themes/light/bootstrap.css" ;
import { IgcRadioChangeEventArgs } from "igniteui-webcomponents/components/radio/radio" ;
export default class DragNDrop extends React.Component <any, any> {
private tileManagerRef = React .createRef<IgrTileManager > ();
constructor (props: any ) {
super (props);
}
private onRadioChange = (event: CustomEvent<IgcRadioChangeEventArgs > ) => {
const radio = event.target as IgrRadio;
this .tileManagerRef.current.dragMode = radio.value as any ;
};
public render (): JSX .Element {
return (
<div className ="container sample center" >
<div className ="radioWrapper" >
<IgrRadioGroup id ="dragMode" alignment ="horizontal" onChange ={this.onRadioChange} >
<IgrRadio name ="dragMode" value ="tile-header" checked > Tile-header</IgrRadio >
<IgrRadio name ="dragMode" value ="tile" > Tile</IgrRadio >
<IgrRadio name ="dragMode" value ="none" > None</IgrRadio >
</IgrRadioGroup >
</div >
<IgrTileManager drag-mode ="tile-header" drag-action ="slide" column-count ="2" gap ="20px" ref ={this.tileManagerRef} >
<IgrTile >
<span slot ="title" > Tile 1 header</span >
<p > Content for Tile 1 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Content for Tile 2 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 3 header</span >
<p > Content for Tile 3 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 4 header</span >
<p > Content for Tile 4 </p >
</IgrTile >
</IgrTileManager >
</div >
);
}
}
const root = ReactDOM.createRoot (document.getElementById("root" ));
root.render (<DragNDrop /> );
tsx コピー span {
font-size : 30px ;
}
igc-tile::part (header ) {
border-bottom : 2px solid var (--ig-primary-700 );
}
p {
font-size : 18px ;
margin-left : 20px ;
padding-top : 10px ;
}
igc-radio-group {
margin-left : 22px ;
width : fit-content;
padding : 4px 15px ;
margin-bottom : 8px ;
border : 2px solid var (--ig-primary-700 );
background-color : var (--ig-gray-300 );
}
igc-tile::part (dragging) {
color : yellow;
}
.radioWrapper {
display : flex;
}
css コピー
직렬화
타일 관리자는 타일의 레이아웃을 관리하는 데 도움이 되는 메서드를 제공합니다.
이 saveLayout 방법을 사용하면 타일 관리자에 타일의 현재 배열을 저장할 수 있으며 모든 타일의 현재 순서, 크기 및 위치를 캡처하므로 나중에 이 정확한 구성으로 복원할 수 있습니다.
이 loadLayout 방법을 사용하면 이전에 저장된 레이아웃을 로드할 수 있습니다. 호출되면 타일을 순서, 크기 및 위치를 포함하여 레이아웃이 저장되었을 때의 정확한 상태로 복원합니다.
EXAMPLE
TSX
index.css
layout.css
import React , { Component, createRef } from "react" ;
import ReactDOM from "react-dom/client" ;
import "./index.css" ;
import "./layout.css" ;
import { IgrTileManager, IgrTile, IgrButton } from "@infragistics/igniteui-react" ;
import "igniteui-webcomponents/themes/light/bootstrap.css" ;
export default class Layout extends Component<any, any> {
private tileManagerRef = createRef<IgrTileManager > ();
state = {
serializedData: '' ,
};
constructor (props: any ) {
super (props);
}
private onAddTileClick = () => {
const newTile = document.createElement("igc-tile" );
const contentHeader = document.createElement('span' );
const content = document.createElement('p' );
const index = this .tileManagerRef.current.tiles.length + 1 ;
contentHeader.textContent = `Tile ${index} header`;
content.textContent = `Content for Tile ${index}`;
contentHeader.setAttribute('slot' , 'title' );
newTile.position = 0 ;
newTile.append(contentHeader);
newTile.append(content);
(this .tileManagerRef.current as IgrTileManager).appendChild(newTile);
}
public render (): JSX .Element {
return (
<div className ="container sample center" >
<div className ="btnWrapper" >
<IgrButton id ="saveL" onClick ={() => this .setState({ serializedData: this .tileManagerRef?.current.saveLayout()})}>Save Layout</IgrButton >
<IgrButton id ="loadL" onClick ={() => this .tileManagerRef.current.loadLayout(this .state.serializedData)}>Load Layout</IgrButton >
<IgrButton id ="addT" onClick ={this.onAddTileClick} > Add Tile</IgrButton >
<IgrButton id ="remT" onClick ={() => this .tileManagerRef.current.querySelector('igc-tile:first-of-type' )?.remove()}>Remove Tile</IgrButton >
</div >
<IgrTileManager ref ={this.tileManagerRef} resize-mode ="always" drag-mode ="tile" column-count ="2" gap ="20px" >
<IgrTile >
<span slot ="title" > Tile 1 header</span >
<p > Content for Tile 1 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Content for Tile 2 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 3 header</span >
<p > Content for Tile 3 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 4 header</span >
<p > Content for Tile 4 </p >
</IgrTile >
</IgrTileManager >
</div >
);
}
}
const root = ReactDOM.createRoot (document.getElementById("root" ));
root.render (<Layout /> );
tsx コピー span {
font-size : 30px ;
}
p {
font-size : 18px ;
margin-left : 20px ;
}
.btnWrapper {
margin : 0 0 8px 22px ;
}
igc-button :nth-of-type (-n+3 ) {
margin-right : 5px ;;
}
.sample {
overflow : auto;
}
css コピー
스타일링
두 구성 요소의 IgrTileManager 모양을 사용자 지정할 수도 있습니다 IgrTile . IgrTileManager Tile Manager의 기본 래퍼 스타일을 지정하는 데 사용할 수 있는 CSS 속성이 base 하나만 노출됩니다. 사용할 수 있는 몇 가지 CSS 속성을 노출합니다 IgrTile .
부품명
설명
base
타일 구성 요소의 래핑 컨테이너입니다.
header
title 및 actions 부분을 포함하는 타일의 헤더 컨테이너입니다.
title
제목 컨테이너입니다.
actions
actions 컨테이너입니다.
content-container
타일 기본 슬롯을 래핑하는 컨테이너입니다.
trigger-side
The horizontal adorner.
trigger
The diagonal adorner
trigger-bottom
The vertical adorner.
이러한 CSS 부분을 사용하여 다음과 같이 두 구성 요소의 모양을 사용자 지정할 수 있습니다.
igc-tile-manager::part (base) {
background-color : var (--ig-surface-900 );
}
igc-tile::part (content -container) {
color : var (--ig-secondary-200 );
}
igc-tile::part (header ) {
background-color : var (--ig-gray-300 );
}
igc-tile::part (title) {
color : var (--ig-primary-400 );
}
igc-tile:nth-child (n+2 )::part (trigger-side),
igc-tile:nth-child (n+2 )::part (trigger-bottom ) {
background-color : var (--ig-success-500 );
}
igc-tile:nth-child (n+2 )::part (trigger) {
background-color : var (--ig-error-500 );
}
css
표시기의 아이콘을 , corner-adorner, 및 bottom-adorner slots를 사용하여 side-adorner 사용자 지정 아이콘으로 변경할 수도 있습니다. 예컨대:
<IgrTile >
<IgrIcon slot ="side-adorner" className ="side" name ="indicator" > </IgrIcon >
<IgrIcon slot ="corner-adorner" className ="corner" name ="indicator" > </IgrIcon >
<IgrIcon slot ="bottom-adorner" className ="bottom" name ="indicator" > </IgrIcon >
<span slot ="title" > Tile header</span >
</IgrTile >
tsx
EXAMPLE
TSX
index.css
layout.css
styles.css
import React from "react" ;
import ReactDOM from "react-dom/client" ;
import "./index.css" ;
import "./layout.css" ;
import "./styles.css" ;
import { IgrTileManager, IgrTile, IgrIcon, registerIconFromText } from "@infragistics/igniteui-react" ;
import "igniteui-webcomponents/themes/light/bootstrap.css" ;
export default class Styling extends React.Component <any, any> {
constructor (props: any ) {
super (props);
const indicatorIcon =
'<svg xmlns="http://www.w3.org/2000/svg" fill="none"><path d="M3.993 12.508V.765h-.979v11.743h.979ZM1.54 10.06V3.21H.56v6.85h.98Z" fill="#09F"/></svg>' ;
registerIconFromText('indicator' , indicatorIcon);
}
public render (): JSX .Element {
return (
<div className ="container sample center" >
<IgrTileManager column-count ="2" gap ="20px" resize-mode ="always" >
<IgrTile >
<IgrIcon slot ="side-adorner" className ="side" name ="indicator" > </IgrIcon >
<IgrIcon slot ="corner-adorner" className ="corner" name ="indicator" > </IgrIcon >
<IgrIcon slot ="bottom-adorner" className ="bottom" name ="indicator" > </IgrIcon >
<span slot ="title" > Tile 1 header</span >
<p > Content for Tile 1 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 2 header</span >
<p > Content for Tile 2 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 3 header</span >
<p > Content for Tile 3 </p >
</IgrTile >
<IgrTile >
<span slot ="title" > Tile 4 header</span >
<p > Content for Tile 4 </p >
</IgrTile >
</IgrTileManager >
</div >
);
}
}
const root = ReactDOM.createRoot (document.getElementById("root" ));
root.render (<Styling /> );
tsx コピー span {
font-size : 30px ;
}
p {
font-size : 18px ;
margin : 10px 0 0 20px ;
}
.sample {
overflow : auto;
}css コピー igc-tile-manager::part (base) {
background-color : var (--ig-surface-900 );
}
igc-tile::part (content -container) {
color : var (--ig-secondary-200 );
}
igc-tile::part (header ) {
background-color : var (--ig-gray-300 );
}
igc-tile::part (title) {
color : var (--ig-primary-400 );
}
igc-tile:nth-child (n+2 )::part (trigger-side), igc-tile:nth-child (n+2 )::part (trigger-bottom ) {
background-color : var (--ig-success-500 );
}
igc-tile:nth-child (n+2 )::part (trigger) {
background-color : var (--ig-error-500 );
}
.side ,
.corner ,
.bottom {
display : inline;
width : 100% ;
height : 100% ;
}
.corner {
transform : rotate (220deg );
bottom : 8px ;
right : 8px ;
}
.bottom {
transform : rotate (90deg );
}css コピー
API 참조
추가 리소스