From bc602f484180b6f4934e33a0cdf9ea1cc17ceb43 Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Fri, 27 Feb 2026 15:08:07 +0200 Subject: [PATCH] Refactor grid-lite samples to use Ignite UI React components and improve code consistency --- .../column-config-basic/src/index.tsx | 97 ++++---- .../column-config-dynamic/src/index.tsx | 212 +++++++++++------- .../column-config-headers/src/index.tsx | 72 ++++-- .../filtering-config-remote/src/index.css | 13 +- .../filtering-config-remote/src/index.tsx | 122 ++++++---- .../grid-lite/filtering-config/src/index.tsx | 77 ++++--- .../overview/src/GridLiteDataService.ts | 8 +- .../grids/grid-lite/overview/src/index.css | 50 +++++ .../grids/grid-lite/overview/src/index.tsx | 183 ++++++++++----- .../grid-lite/sort-config-grid/src/index.tsx | 124 +++++----- .../styling-custom-theme/src/index.scss | 22 +- .../styling-custom-theme/src/index.tsx | 65 +++--- 12 files changed, 678 insertions(+), 367 deletions(-) diff --git a/samples/grids/grid-lite/column-config-basic/src/index.tsx b/samples/grids/grid-lite/column-config-basic/src/index.tsx index 00118c27f8..1a7dc3d582 100644 --- a/samples/grids/grid-lite/column-config-basic/src/index.tsx +++ b/samples/grids/grid-lite/column-config-basic/src/index.tsx @@ -1,67 +1,78 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import { GridLiteDataService, ProductInfo } from './GridLiteDataService'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import { GridLiteDataService, ProductInfo } from "./GridLiteDataService"; -// Import the web component -import { IgcGridLite } from 'igniteui-grid-lite'; -import { - defineComponents, - IgcRatingComponent -} from 'igniteui-webcomponents'; +import { IgrRating } from "igniteui-react"; +import { + IgrGridLite, + IgrGridLiteColumn, + type IgrCellContext, +} from "igniteui-react/grid-lite"; import "igniteui-webcomponents/themes/light/bootstrap.css"; import "./index.css"; -// Register components -IgcGridLite.register(); -defineComponents(IgcRatingComponent); - -const formatter = new Intl.NumberFormat('en-EN', { - style: 'currency', - currency: 'EUR' +const formatter = new Intl.NumberFormat("en-150", { + style: "currency", + currency: "EUR", }); +const formatCurrency = (value: number) => formatter.format(value); + // Define cellTemplate functions outside component -const currencyCellTemplate = (params: any) => { - const span = document.createElement('span'); - span.textContent = formatter.format(params.value); - return span; -}; +const currencyCellTemplate = (ctx: IgrCellContext) => ( + {formatCurrency(ctx.value)} +); -const ratingCellTemplate = (params: any) => { - const rating = document.createElement('igc-rating'); - rating.setAttribute('readonly', ''); - rating.setAttribute('step', '0.01'); - rating.setAttribute('value', params.value.toString()); - return rating; -}; +const ratingCellTemplate = (ctx: IgrCellContext) => ( + +); export default function Sample() { - const gridRef = React.useRef(null); + const [data, setData] = React.useState([]); React.useEffect(() => { - if (gridRef.current) { - const dataService = new GridLiteDataService(); - const data: ProductInfo[] = dataService.generateProducts(50); - gridRef.current.data = data; - } + const dataService = new GridLiteDataService(); + const items: ProductInfo[] = dataService.generateProducts(50); + setData(items); }, []); return (
- - - - - - - + + + + + + +
); } // rendering above component in the React DOM -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render(); +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render(); diff --git a/samples/grids/grid-lite/column-config-dynamic/src/index.tsx b/samples/grids/grid-lite/column-config-dynamic/src/index.tsx index cf8ef750ab..6f1cce918d 100644 --- a/samples/grids/grid-lite/column-config-dynamic/src/index.tsx +++ b/samples/grids/grid-lite/column-config-dynamic/src/index.tsx @@ -1,102 +1,109 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import ReactDOM from 'react-dom/client'; -import { GridLiteDataService, ProductInfo } from './GridLiteDataService'; +import React, { useCallback, useEffect, useState } from "react"; +import ReactDOM from "react-dom/client"; +import { GridLiteDataService, ProductInfo } from "./GridLiteDataService"; -import { IgrButton, IgrCheckbox, IgrDropdown, IgrDropdownItem, IgrSwitch } from 'igniteui-react'; - -// Import the web component -import { IgcGridLite } from 'igniteui-grid-lite'; import { - defineComponents, - IgcRatingComponent -} from 'igniteui-webcomponents'; + IgrButton, + IgrCheckbox, + IgrDropdown, + IgrDropdownItem, + IgrDropdownItemComponentEventArgs, + IgrRating, + IgrSwitch, +} from "igniteui-react"; +import { + IgrGridLite, + IgrGridLiteColumn, + type IgrCellContext, +} from "igniteui-react/grid-lite"; import "igniteui-webcomponents/themes/light/bootstrap.css"; import "./index.css"; -// Register components -IgcGridLite.register(); -defineComponents(IgcRatingComponent); - -const formatter = new Intl.NumberFormat('en-EN', { - style: 'currency', - currency: 'EUR', +const formatter = new Intl.NumberFormat("en-150", { + style: "currency", + currency: "EUR", }); // Define cellTemplate functions outside component -const currencyCellTemplate = (params: any) => { - const span = document.createElement('span'); - span.textContent = formatter.format(params.value); - return span; -}; +const currencyCellTemplate = (ctx: IgrCellContext) => ( + {formatter.format(ctx.value)} +); -const ratingCellTemplate = (params: any) => { - const rating = document.createElement('igc-rating'); - rating.setAttribute('readonly', ''); - rating.setAttribute('step', '0.01'); - rating.setAttribute('value', params.value.toString()); - return rating; +const ratingCellTemplate = (ctx: IgrCellContext) => ( + +); + +type GridColumnConfig = { + field: string; + header: string; + dataType?: "number" | "string" | "boolean"; + hidden?: boolean; + resizable: boolean; + sortable: boolean; + filterable: boolean; + cellTemplate?: (ctx: IgrCellContext) => React.ReactNode; }; -const initialColumns = [ +const initialColumns: GridColumnConfig[] = [ { - field: 'id', + field: "id", hidden: true, - header: 'ID', + header: "ID", + dataType: "string", resizable: true, sortable: false, filterable: false, - cellTemplate: undefined }, { - field: 'name', - header: 'Product Name', + field: "name", + header: "Product Name", + dataType: "string", resizable: true, sortable: false, filterable: false, - cellTemplate: undefined }, { - field: 'price', - header: 'Price', - dataType: 'number', + field: "price", + header: "Price", + dataType: "number", cellTemplate: currencyCellTemplate, resizable: true, sortable: false, - filterable: false + filterable: false, }, { - field: 'sold', - dataType: 'number', - header: 'Units sold', + field: "sold", + dataType: "number", + header: "Units Sold", resizable: true, sortable: false, filterable: false, - cellTemplate: undefined }, { - field: 'total', - header: 'Total sold', + field: "total", + header: "Total Sold", + dataType: "number", cellTemplate: currencyCellTemplate, resizable: true, sortable: false, - filterable: false + filterable: false, }, { - field: 'rating', - dataType: 'number', - header: 'Customer rating', + field: "rating", + dataType: "number", + header: "Customer Rating", cellTemplate: ratingCellTemplate, resizable: true, sortable: false, - filterable: false - } + filterable: false, + }, ]; export default function Sample() { const dropdownRef = React.useRef(null); - const [columns, setColumns] = useState(initialColumns); - const [data, setData] = useState([]); + const [columns, setColumns] = useState(initialColumns); + const [data, setData] = useState([]); const [hasFormatters, setHasFormatters] = useState(true); useEffect(() => { @@ -106,24 +113,25 @@ export default function Sample() { }, []); const toggleFormatters = useCallback((checked: boolean) => { - setColumns(prevColumns => - prevColumns.map(col => - col.field === 'price' || col.field === 'total' + setColumns((prevColumns) => + prevColumns.map((col) => + col.field === "price" || col.field === "total" ? { ...col, cellTemplate: checked ? currencyCellTemplate : undefined } - : col - ) + : col, + ), ); }, []); - const toggleColumnProperty = React.useCallback((columnField: string, property: string, value: boolean) => { - setColumns(prevColumns => - prevColumns.map(col => - col.field === columnField - ? { ...col, [property]: value } - : col - ) - ); - }, []); + const toggleColumnProperty = React.useCallback( + (columnField: string, property: string, value: boolean) => { + setColumns((prevColumns) => + prevColumns.map((col) => + col.field === columnField ? { ...col, [property]: value } : col, + ), + ); + }, + [], + ); return (
@@ -132,39 +140,70 @@ export default function Sample() { ref={dropdownRef} keepOpenOnSelect={true} flip={true} - onChange={(e: any) => { + onChange={(e: IgrDropdownItemComponentEventArgs) => { dropdownRef.current?.clearSelection(); }} - id="column-select"> + id="column-select" + >
- Column Properties + + Column Properties +
- {columns.map((column: any) => ( + {columns.map((column) => (
{column.header} toggleColumnProperty(column.field, 'hidden', e.target.checked)}> + onChange={(e: any) => + toggleColumnProperty( + column.field, + "hidden", + e.target.checked, + ) + } + > Hidden toggleColumnProperty(column.field, 'resizable', e.target.checked)}> + onChange={(e: any) => + toggleColumnProperty( + column.field, + "resizable", + e.target.checked, + ) + } + > Resizable toggleColumnProperty(column.field, 'filterable', e.target.checked)}> + onChange={(e: any) => + toggleColumnProperty( + column.field, + "filterable", + e.target.checked, + ) + } + > Filter toggleColumnProperty(column.field, 'sortable', e.target.checked)}> + onChange={(e: any) => + toggleColumnProperty( + column.field, + "sortable", + e.target.checked, + ) + } + > Sort
@@ -178,31 +217,34 @@ export default function Sample() { onChange={(e: any) => { setHasFormatters(e.target.checked); toggleFormatters(e.target.checked); - }}> + }} + > Value formatters:
- - {columns.map((column: any) => ( - + {columns.map((column) => ( + + {...(column.cellTemplate + ? { cellTemplate: column.cellTemplate } + : {})} + > ))} - +
-
+ ); } // rendering above component in the React DOM -const root = ReactDOM.createRoot(document.getElementById('root')); +const root = ReactDOM.createRoot(document.getElementById("root")); root.render(); diff --git a/samples/grids/grid-lite/column-config-headers/src/index.tsx b/samples/grids/grid-lite/column-config-headers/src/index.tsx index da335033be..befd2edbf1 100644 --- a/samples/grids/grid-lite/column-config-headers/src/index.tsx +++ b/samples/grids/grid-lite/column-config-headers/src/index.tsx @@ -1,41 +1,69 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import { GridLiteDataService, User } from './GridLiteDataService'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import { GridLiteDataService, ProductInfo } from "./GridLiteDataService"; +import { IgrRating } from "igniteui-react"; +import { + IgrGridLite, + IgrGridLiteColumn, + type IgrCellContext, + type IgrHeaderContext, +} from "igniteui-react/grid-lite"; -// Import the web component -import { IgcGridLite } from 'igniteui-grid-lite'; import "igniteui-webcomponents/themes/light/bootstrap.css"; import "./index.css"; -// Register components -IgcGridLite.register(); +const ratingHeaderTemplate = (_ctx: IgrHeaderContext) => ( +

{"\u2B50 Rating \u2B50"}

+); + +const ratingCellTemplate = (ctx: IgrCellContext) => ( + +); export default function Sample() { - const gridRef = React.useRef(null); + const [data, setData] = React.useState([]); React.useEffect(() => { - if (gridRef.current) { - const dataService = new GridLiteDataService(); - const data: User[] = dataService.generateUsers(50); - gridRef.current.data = data; - } + const dataService = new GridLiteDataService(); + const items: ProductInfo[] = dataService.generateProducts(50); + setData(items); }, []); return (
- - - - - - - + + + + + + +
); } // rendering above component in the React DOM -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render(); +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render(); diff --git a/samples/grids/grid-lite/filtering-config-remote/src/index.css b/samples/grids/grid-lite/filtering-config-remote/src/index.css index a04c50eec0..35ea9d629a 100644 --- a/samples/grids/grid-lite/filtering-config-remote/src/index.css +++ b/samples/grids/grid-lite/filtering-config-remote/src/index.css @@ -24,7 +24,18 @@ code { height: calc(100% - 1rem); } +.grid-section { + position: relative; +} + +.pipeline-loader { + position: absolute; + z-index: 2; + top: 0.75rem; + right: 0.75rem; +} + igc-grid-lite { min-height: 65vh; --ig-size: 2; -} \ No newline at end of file +} diff --git a/samples/grids/grid-lite/filtering-config-remote/src/index.tsx b/samples/grids/grid-lite/filtering-config-remote/src/index.tsx index 663a31eb54..eaaa91c249 100644 --- a/samples/grids/grid-lite/filtering-config-remote/src/index.tsx +++ b/samples/grids/grid-lite/filtering-config-remote/src/index.tsx @@ -1,16 +1,16 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import { GridLiteDataService, User } from './GridLiteDataService'; - -// Import the web component -import { IgcGridLite } from 'igniteui-grid-lite'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import { GridLiteDataService, User } from "./GridLiteDataService"; +import { IgrCheckbox, IgrCircularProgress } from "igniteui-react"; +import { + IgrGridLite, + IgrGridLiteColumn, + type IgrCellContext, +} from "igniteui-react/grid-lite"; import "igniteui-webcomponents/themes/light/bootstrap.css"; import "./index.css"; -// Register components -IgcGridLite.register(); - function groupBy(arr: T[], key: keyof T) { const out: Record = {}; for (const each of arr) { @@ -26,10 +26,10 @@ function groupBy(arr: T[], key: keyof T) { const mapExpressions = (arr: any[]) => { return arr .map(({ searchTerm, criteria, condition }: any, idx: number) => { - const c = condition; + const normalizedSearchTerm = !searchTerm ? condition.name : searchTerm; return idx < 1 - ? `${c.name}("${searchTerm}")` - : `${criteria?.toUpperCase()} ${c.name}("${searchTerm}")`; + ? `${condition.name}("${normalizedSearchTerm}")` + : `${criteria?.toUpperCase()} ${condition.name}("${normalizedSearchTerm}")`; }) .join(' '); }; @@ -43,46 +43,86 @@ const buildUri = (state: any[], setQueryString: (qs: string) => void) => { setQueryString(`GET: /data?filter=${out.join('&')}`); }; +const activeCellTemplate = (ctx: IgrCellContext) => ( + +); + export default function Sample() { - const gridRef = React.useRef(null); - const [queryString, setQueryString] = React.useState(''); + const [data, setData] = React.useState([]); + const [queryString, setQueryString] = React.useState(""); + const [inOperation, setInOperation] = React.useState(false); - const dataPipelineConfiguration = React.useMemo(() => ({ - filter: async ({ data, grid }: any) => { - buildUri(grid.filterExpressions, setQueryString); - await new Promise((resolve) => setTimeout(resolve, 250)); - return data; - }, - }), []); + const dataPipelineConfiguration = React.useMemo( + () => ({ + filter: async ({ data, grid }: any) => { + setInOperation(true); + buildUri(grid.filterExpressions, setQueryString); + await new Promise((resolve) => setTimeout(resolve, 250)); + setInOperation(false); + return data; + }, + }), + [], + ); React.useEffect(() => { - if (gridRef.current) { - const dataService = new GridLiteDataService(); - const allData: User[] = dataService.generateUsers(100); - gridRef.current.data = allData; - gridRef.current.dataPipelineConfiguration = dataPipelineConfiguration; - } - }, [dataPipelineConfiguration]); + const dataService = new GridLiteDataService(); + const allData: User[] = dataService.generateUsers(500); + setData(allData); + }, []); return (
-
-
-

{queryString}

-
-
- - - - - - +
+
Generated request
+

+ {queryString} +

+
+
+ {inOperation && ( + + )} + + + + + + +
); } // rendering above component in the React DOM -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render(); +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render(); diff --git a/samples/grids/grid-lite/filtering-config/src/index.tsx b/samples/grids/grid-lite/filtering-config/src/index.tsx index c4a8c77c0c..c7fb462621 100644 --- a/samples/grids/grid-lite/filtering-config/src/index.tsx +++ b/samples/grids/grid-lite/filtering-config/src/index.tsx @@ -1,55 +1,64 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import { GridLiteDataService, User } from './GridLiteDataService'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import { GridLiteDataService, User } from "./GridLiteDataService"; -// Import the web component -import { IgcGridLite } from 'igniteui-grid-lite'; -import { - defineComponents, - IgcCheckboxComponent -} from 'igniteui-webcomponents'; +import { IgrCheckbox } from "igniteui-react"; +import { + IgrGridLite, + IgrGridLiteColumn, + type IgrCellContext, +} from "igniteui-react/grid-lite"; import "igniteui-webcomponents/themes/light/bootstrap.css"; import "./index.css"; -// Register components -IgcGridLite.register(); -defineComponents(IgcCheckboxComponent); - // Define cellTemplate function outside component -const activeCellTemplate = (params: any) => { - const checkbox = document.createElement('igc-checkbox'); - if (params.value) { - checkbox.setAttribute('checked', ''); - } - return checkbox; -}; +const activeCellTemplate = (ctx: IgrCellContext) => ( + +); export default function Sample() { - const gridRef = React.useRef(null); + const [data, setData] = React.useState([]); React.useEffect(() => { - if (gridRef.current) { - const dataService = new GridLiteDataService(); - const data: User[] = dataService.generateUsers(50); - gridRef.current.data = data; - } + const dataService = new GridLiteDataService(); + const items: User[] = dataService.generateUsers(50); + setData(items); }, []); return (
- - - - - - + + + + + +
); } // rendering above component in the React DOM -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render(); +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render(); diff --git a/samples/grids/grid-lite/overview/src/GridLiteDataService.ts b/samples/grids/grid-lite/overview/src/GridLiteDataService.ts index 64ad97a673..fc9fd7e553 100644 --- a/samples/grids/grid-lite/overview/src/GridLiteDataService.ts +++ b/samples/grids/grid-lite/overview/src/GridLiteDataService.ts @@ -23,6 +23,8 @@ export type User = { avatar: string; active: boolean; priority: 'Low' | 'Standard' | 'High'; + employmentType: 'Full-Time' | 'Part-Time' | 'Contract'; + department: 'Engineering' | 'Marketing' | 'Sales' | 'Finance'; satisfaction: number; registeredAt: Date; }; @@ -36,6 +38,8 @@ export class GridLiteDataService { private productNames = ['Widget', 'Gadget', 'Gizmo', 'Device', 'Tool', 'Instrument', 'Machine', 'Equipment']; private productModels = ['Pro', 'Plus', 'Max', 'Ultra', 'Mini', 'Lite']; private priorities: ('Low' | 'Standard' | 'High')[] = ['Low', 'Standard', 'High']; + private employmentTypes: ('Full-Time' | 'Part-Time' | 'Contract')[] = ['Full-Time', 'Part-Time', 'Contract']; + private departments: ('Engineering' | 'Marketing' | 'Sales' | 'Finance')[] = ['Engineering', 'Marketing', 'Sales', 'Finance']; private randomInt(min: number, max: number): number { return Math.floor(Math.random() * (max - min + 1)) + min; @@ -114,6 +118,8 @@ export class GridLiteDataService { avatar: imagePath, active: this.randomBoolean(), priority: this.randomElement(this.priorities), + employmentType: this.randomElement(this.employmentTypes), + department: this.randomElement(this.departments), satisfaction: this.randomInt(0, 5), registeredAt: new Date(Date.now() - this.randomInt(0, 365 * 24 * 60 * 60 * 1000)) }; @@ -130,4 +136,4 @@ export class GridLiteDataService { generateSimpleUsers(count: number): UserSimple[] { return Array.from({ length: count }, () => this.createUserSimple()); } -} \ No newline at end of file +} diff --git a/samples/grids/grid-lite/overview/src/index.css b/samples/grids/grid-lite/overview/src/index.css index 6518297463..a085e7987b 100644 --- a/samples/grids/grid-lite/overview/src/index.css +++ b/samples/grids/grid-lite/overview/src/index.css @@ -7,3 +7,53 @@ igc-grid-lite { min-height: 75vh; --ig-size: 1; } + +/* Badge spacing tokens are scale multipliers; 2.6667 = 0.5rem target inline padding / 0.1875rem base spacing unit. */ +igc-badge.badge-padded { + --ig-spacing-inline: 2.6667; +} + +igc-badge.badge-padded::part(base) { + padding-block: 0.125rem; + color: var(--ig-gray-900) !important; +} + +/* Use lighter variant shades across both department (filled) and employment (outlined) badges. */ +igc-badge.badge-padded[variant="success"] { + --ig-badge-border-color: var(--ig-success-300); +} + +igc-badge.badge-padded[variant="warning"] { + --ig-badge-border-color: var(--ig-warn-300); +} + +igc-badge.badge-padded[variant="primary"] { + --ig-badge-border-color: var(--ig-primary-300); +} + +igc-badge.badge-padded[variant="danger"] { + --ig-badge-border-color: var(--ig-error-300); +} + +/* Force lighter fills for department (filled) badges. */ +igc-badge.badge-padded.badge-department[variant="success"]::part(base) { + background: var(--ig-success-300) !important; +} + +igc-badge.badge-padded.badge-department[variant="warning"]::part(base) { + background: var(--ig-warn-300) !important; +} + +igc-badge.badge-padded.badge-department[variant="primary"]::part(base) { + background: var(--ig-primary-300) !important; +} + +igc-badge.badge-padded.badge-department[variant="danger"]::part(base) { + background: var(--ig-error-300) !important; +} + +/* Employment badges are outline-only. */ +igc-badge.badge-employment::part(base) { + background: transparent !important; + box-shadow: inset 0 0 0 0.125rem var(--ig-badge-border-color) !important; +} diff --git a/samples/grids/grid-lite/overview/src/index.tsx b/samples/grids/grid-lite/overview/src/index.tsx index 70aae07469..20d5d13ae4 100644 --- a/samples/grids/grid-lite/overview/src/index.tsx +++ b/samples/grids/grid-lite/overview/src/index.tsx @@ -1,77 +1,156 @@ -import React, { useEffect } from 'react'; -import ReactDOM from 'react-dom/client'; -import { GridLiteDataService, User } from './GridLiteDataService'; - -// Import the web component -import { IgcGridLite } from 'igniteui-grid-lite'; -import { - defineComponents, - IgcRatingComponent, - IgcCheckboxComponent, - IgcSelectComponent, - IgcAvatarComponent -} from 'igniteui-webcomponents'; +import React, { useEffect } from "react"; +import ReactDOM from "react-dom/client"; +import { GridLiteDataService, User } from "./GridLiteDataService"; +import "./index.css"; +import { + IgrAvatar, + IgrBadge, + IgrRating, + type StyleVariant, +} from "igniteui-react"; +import { + IgrGridLite, + IgrGridLiteColumn, + type IgrCellContext, +} from "igniteui-react/grid-lite"; import "igniteui-webcomponents/themes/light/bootstrap.css"; import "./index.css"; -// Register components -IgcGridLite.register(); -defineComponents( - IgcAvatarComponent, - IgcRatingComponent, - IgcCheckboxComponent, - IgcSelectComponent +const avatarCellTemplate = (ctx: IgrCellContext) => ( + ); -// Define cellTemplate functions outside component -const avatarCellTemplate = (params: any) => { - const cell = document.createElement('igc-avatar'); - cell.setAttribute('shape', 'circle'); - cell.setAttribute('alt', 'User avatar'); - cell.setAttribute('src', params.value); - return cell; -}; +const satisfactionCellTemplate = (ctx: IgrCellContext) => ( + +); -const satisfactionCellTemplate = (params: any) => { - const rating = document.createElement('igc-rating'); - rating.setAttribute('readonly', ''); - rating.setAttribute('value', params.value.toString()); - return rating; +const getDepartmentBadgeVariant = (value: string): StyleVariant => { + switch (value) { + case "Engineering": + return "primary"; + case "Marketing": + return "warning"; + case "Sales": + return "danger"; + case "Finance": + return "success"; + default: + return "primary"; + } }; -const registeredAtCellTemplate = (params: any) => { - const span = document.createElement('span'); - span.textContent = params.value.toLocaleString(); - return span; +const getEmploymentTypeOutline = (value: string): StyleVariant => { + switch (value) { + case "Full-Time": + return "success"; + case "Part-Time": + return "warning"; + case "Contract": + return "primary"; + default: + return "primary"; + } }; +const employmentTypeCellTemplate = (ctx: IgrCellContext) => ( + + {ctx.value} + +); + +const departmentCellTemplate = (ctx: IgrCellContext) => ( + + {ctx.value} + +); + +const registeredAtCellTemplate = (ctx: IgrCellContext) => ( + {ctx.value.toLocaleString()} +); export default function Sample() { - const [data, setData] = React.useState([]); + const [data, setData] = React.useState([]); useEffect(() => { - const dataService = new GridLiteDataService(); - const data: User[] = dataService.generateUsers(1000); - setData(data); + const dataService = new GridLiteDataService(); + const data: User[] = dataService.generateUsers(1000); + setData(data); }, []); return ( -
+
- - - - - - - - + + + + + + + + + +
); } // rendering above component in the React DOM -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render(); +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render(); diff --git a/samples/grids/grid-lite/sort-config-grid/src/index.tsx b/samples/grids/grid-lite/sort-config-grid/src/index.tsx index 6dcaff9b7c..4cf9af5c69 100644 --- a/samples/grids/grid-lite/sort-config-grid/src/index.tsx +++ b/samples/grids/grid-lite/sort-config-grid/src/index.tsx @@ -1,78 +1,94 @@ -import React, { useRef, useState } from 'react'; -import ReactDOM from 'react-dom/client'; -import { IgrSwitch } from 'igniteui-react'; -import { GridLiteDataService, ProductInfo } from './GridLiteDataService'; +import React, { useRef, useState } from "react"; +import ReactDOM from "react-dom/client"; +import { IgrRating, IgrSwitch } from "igniteui-react"; +import { GridLiteDataService, ProductInfo } from "./GridLiteDataService"; -// Import the web component -import { IgcGridLite } from 'igniteui-grid-lite'; -import { - defineComponents, - IgcRatingComponent -} from 'igniteui-webcomponents'; +import { + IgrGridLite, + IgrGridLiteColumn, + type IgrCellContext, +} from "igniteui-react/grid-lite"; import "igniteui-webcomponents/themes/light/bootstrap.css"; import "./index.css"; -// Register components -IgcGridLite.register(); -defineComponents(IgcRatingComponent); - // Define cellTemplate function outside component -const ratingCellTemplate = (params: any) => { - const rating = document.createElement('igc-rating'); - rating.setAttribute('readonly', ''); - rating.setAttribute('step', '0.01'); - rating.setAttribute('value', params.value.toString()); - return rating; -}; +const ratingCellTemplate = (ctx: IgrCellContext) => ( + +); export default function Sample() { const gridRef = useRef(null); - const [switchChecked, setSwitchChecked] = useState(true); + const [data, setData] = useState([]); const [sortingOptions, setSortingOptions] = useState({ - mode: 'multiple' + mode: "multiple", }); React.useEffect(() => { - if (gridRef.current) { - const dataService = new GridLiteDataService(); - const data: ProductInfo[] = dataService.generateProducts(100); - gridRef.current.data = data; - gridRef.current.sortingOptions = sortingOptions; - } - }, [sortingOptions]); + const dataService = new GridLiteDataService(); + const items: ProductInfo[] = dataService.generateProducts(100); + setData(items); + }, []); - const updateConfig = React.useCallback((prop: string, checked: boolean) => { - setSwitchChecked(checked); - - if (prop === 'multiple' && gridRef.current) { - const mode = checked ? 'multiple' : 'single'; - setSortingOptions({ mode }); - - gridRef.current.sortingConfiguration = { mode }; - gridRef.current.clearSort(); - } + const updateConfig = React.useCallback((checked: boolean) => { + const mode = checked ? "multiple" : "single"; + setSortingOptions((prev: any) => ({ ...prev, mode })); + gridRef.current?.clearSort(); }, []); - + return (
-
- updateConfig('multiple', e.target.checked)}> - Multiple Sort +
+ updateConfig(e.target.checked)} + > + Enable multi-sort -
+
- - - - - - - + + + + + + +
); } // rendering above component in the React DOM -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render(); +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render(); diff --git a/samples/grids/grid-lite/styling-custom-theme/src/index.scss b/samples/grids/grid-lite/styling-custom-theme/src/index.scss index 05f2e065e4..43ec409884 100644 --- a/samples/grids/grid-lite/styling-custom-theme/src/index.scss +++ b/samples/grids/grid-lite/styling-custom-theme/src/index.scss @@ -1,7 +1,14 @@ @use 'igniteui-theming' as *; @import 'igniteui-theming/sass/typography/presets'; -$custom-palette: palette( +$custom-light-palette: palette( + $primary: #ddd020, + $secondary: #d5896f, + $surface: #f8f7ff, + $gray: #04395e, +); + +$custom-dark-palette: palette( $primary: #ddd020, $secondary: #d5896f, $surface: #031d44, @@ -13,7 +20,16 @@ $custom-palette: palette( height: 100%; } -.custom-styled { - @include palette($custom-palette); +.theme-switcher { + margin-bottom: 1rem; +} + +.custom-light { + @include palette($custom-light-palette); + @include typography('"Merriweather Sans", sans-serif', $bootstrap-type-scale); +} + +.custom-dark { + @include palette($custom-dark-palette); @include typography('"Merriweather Sans", sans-serif', $bootstrap-type-scale); } diff --git a/samples/grids/grid-lite/styling-custom-theme/src/index.tsx b/samples/grids/grid-lite/styling-custom-theme/src/index.tsx index 8ce1fde75f..bee4c5dad9 100644 --- a/samples/grids/grid-lite/styling-custom-theme/src/index.tsx +++ b/samples/grids/grid-lite/styling-custom-theme/src/index.tsx @@ -2,49 +2,52 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import { GridLiteDataService, ProductInfo } from './GridLiteDataService'; -// Import the web component -import { IgcGridLite } from 'igniteui-grid-lite'; -import { - defineComponents, - IgcRatingComponent -} from 'igniteui-webcomponents'; +import { IgrSwitch } from 'igniteui-react'; +import { + IgrGridLite, + IgrGridLiteColumn, +} from 'igniteui-react/grid-lite'; import "igniteui-webcomponents/themes/light/bootstrap.css"; import "./index.scss"; -// Register components -IgcGridLite.register(); -defineComponents(IgcRatingComponent); - -// Define cellTemplate function outside component -const ratingCellTemplate = (params: any) => { - const rating = document.createElement('igc-rating'); - rating.setAttribute('readonly', ''); - rating.setAttribute('value', params.value.toString()); - return rating; -}; - export default function Sample() { - const gridRef = React.useRef(null); + const [data, setData] = React.useState([]); + const [theme, setTheme] = React.useState<'dark' | 'light'>('dark'); React.useEffect(() => { - if (gridRef.current) { - const dataService = new GridLiteDataService(); - const data: ProductInfo[] = dataService.generateProducts(50); - gridRef.current.data = data; - } + const dataService = new GridLiteDataService(); + const items: ProductInfo[] = dataService.generateProducts(50); + setData(items); + }, []); + + const switchTheme = React.useCallback(() => { + setTheme((prev) => (prev === 'dark' ? 'light' : 'dark')); }, []); return (
- - - - - - - +
+ + {`Switch to ${theme === 'dark' ? 'light' : 'dark'} theme`} + +
+ + + + + + +
);