Skip to content

Commit dbd270d

Browse files
Merge pull request #1625 from IgniteUI/mstoyanova/update-skills-build
feat(build): add script to update skills for Angular, React, and WebC…
2 parents 285482a + afa25b5 commit dbd270d

4 files changed

Lines changed: 151 additions & 11 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"version": "node ./scripts/versionScript.js",
2424
"build": "node ./node_modules/typescript/lib/tsc.js && npm run config-schema && npm run build:mcp",
2525
"build:mcp": "cd packages/igniteui-mcp/igniteui-doc-mcp && npx tsc && npx tsx scripts/build.ts",
26-
"build-pack": "node ./node_modules/typescript/lib/tsc.js -p tsconfig-pack.json && npm run config-schema && npm run build:mcp",
26+
"build:update-skills": "npx tsx scripts/update-skills.ts",
27+
"build-pack": "node ./node_modules/typescript/lib/tsc.js -p tsconfig-pack.json && npm run config-schema && npm run build:mcp && npm run build:update-skills",
2728
"pretest": "npm run lint && npm run build",
2829
"test": "nyc npm run jasmine",
2930
"jasmine": "node spec/jasmine-runner.js",

packages/cli/templates/react/igr-ts/projects/_base/files/__dot__claude/skills/igniteui-react-components/reference/CHARTS-GRIDS.md

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export default function MasterView() {
110110

111111
return (
112112
<div className={styles['grid-lite']}>
113-
<IgrGridLite data={northwindCustomers} />
113+
<IgrGridLite data={northwindCustomers} autoGenerate={true} />
114114
</div>
115115
);
116116
}
@@ -120,8 +120,80 @@ export default function MasterView() {
120120
/* master-view.module.css */
121121
.grid-lite {
122122
min-width: 400px;
123-
min-height: 220px;
123+
height: 600px;
124124
flex-grow: 1;
125125
flex-basis: 0;
126126
}
127127
```
128+
129+
## Grid Lite Example with Column Configurations and Templates
130+
131+
Use `IgrGridLiteColumn` to define columns explicitly with typed `dataType` and optional `cellTemplate` for custom rendering. Set `autoGenerate={false}` (or omit it) when providing explicit columns.
132+
133+
```tsx
134+
import { IgrGridLite, IgrGridLiteColumn, type IgrCellContext } from 'igniteui-react/grid-lite';
135+
import styles from './order-list.module.css';
136+
137+
interface Order {
138+
id: number;
139+
customer: string;
140+
total: number;
141+
date: Date;
142+
status: 'pending' | 'shipped' | 'delivered';
143+
}
144+
145+
const orders: Order[] = [
146+
{ id: 1, customer: 'Alice', total: 149.99, date: new Date('2024-03-01'), status: 'delivered' },
147+
{ id: 2, customer: 'Bob', total: 89.50, date: new Date('2024-03-10'), status: 'shipped' },
148+
{ id: 3, customer: 'Carol', total: 220.00, date: new Date('2024-03-15'), status: 'pending' },
149+
];
150+
151+
// Simple cell templates — render JSX based on the cell value or row data
152+
const currencyTemplate = (ctx: IgrCellContext<Order>) => (
153+
<span>${(ctx.value as number).toFixed(2)}</span>
154+
);
155+
156+
const dateTemplate = (ctx: IgrCellContext<Order>) => (
157+
<span>${(ctx.value as Date).toLocaleDateString()}</span>
158+
);
159+
160+
const statusTemplate = (ctx: IgrCellContext<Order>) => {
161+
const colors: Record<Order['status'], string> = {
162+
pending: 'orange',
163+
shipped: 'blue',
164+
delivered: 'green',
165+
};
166+
return <span style={{ color: colors[ctx.value as Order['status']] }}>{ctx.value}</span>;
167+
};
168+
169+
export default function OrderList() {
170+
return (
171+
<div className={styles['grid-lite']}>
172+
<IgrGridLite data={orders}>
173+
{/* dataType ensures correct sorting and filtering behavior */}
174+
<IgrGridLiteColumn field="id" dataType="number" />
175+
<IgrGridLiteColumn field="customer" dataType="string" />
176+
{/* Columns with custom cell templates */}
177+
<IgrGridLiteColumn field="date" cellTemplate={dateTemplate} />
178+
<IgrGridLiteColumn field="total" dataType="number" cellTemplate={currencyTemplate} />
179+
<IgrGridLiteColumn field="status" dataType="string" cellTemplate={statusTemplate} />
180+
</IgrGridLite>
181+
</div>
182+
);
183+
}
184+
```
185+
186+
```css
187+
/* order-list.module.css */
188+
.grid-lite {
189+
min-width: 400px;
190+
height: 600px;
191+
flex-grow: 1;
192+
flex-basis: 0;
193+
}
194+
```
195+
196+
> **Column configuration notes:**
197+
> - `dataType` accepts `"string"` (default), `"number"`, `"boolean"` — set it explicitly so sorting and filtering work correctly for each column type.
198+
> - `cellTemplate` receives an `IgrCellContext<T>` where `ctx.value` is the cell value and `ctx.row.data` is the full row object.
199+
> - When using `cellTemplate`, define the function outside the component (or memoize it) to avoid unnecessary re-renders.

packages/cli/templates/react/igr-ts/projects/_base/files/__dot__claude/skills/igniteui-react-components/reference/REFS-FORMS.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,27 @@ function MyPage() {
4949

5050
## Uncontrolled Components
5151

52-
`igniteui-react` Inputs integrate with the native form handling through Element internals, allowing to take advantage of the native state management adn validation to create intuitive, straight-forward forms:
52+
`igniteui-react` Form elements like Inputs, Select, Checkbox, etc., integrate with the native form handling through Element internals, allowing to take advantage of the native state management and validation to create intuitive, straightforward forms. Use the `name` attribute to register the field value with `FormData`:
5353

5454
```tsx
55-
import { useRef } from 'react';
56-
import { IgrInput, IgrButton } from 'igniteui-react';
55+
import { IgrInput, IgrSelect, IgrSelectItem, IgrButton } from 'igniteui-react';
5756

5857
function SimpleForm() {
59-
const nameRef = useRef<IgrInput>(null);
60-
61-
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
62-
// e.preventDefault(); // optionally prevent default submit form custom handling
58+
const handleSubmit = (e: React.SubmitEvent<HTMLFormElement>) => {
59+
// e.preventDefault(); // optionally prevent default submit for custom handling
6360
const formData = new FormData(e.target);
61+
console.log(formData.get('name')); // input value
62+
console.log(formData.get('role')); // selected option value
6463
};
6564

6665
return (
6766
<form onSubmit={handleSubmit}>
6867
<IgrInput name="name" label="Name" required={true} />
69-
<IgrInput name="description" label="description" minLength={0}>
68+
<IgrSelect name="role" label="Role" required={true}>
69+
<IgrSelectItem value="user">User</IgrSelectItem>
70+
<IgrSelectItem value="admin">Admin</IgrSelectItem>
71+
<IgrSelectItem value="editor">Editor</IgrSelectItem>
72+
</IgrSelect>
7073
<IgrButton type="submit">
7174
<span>Submit</span>
7275
</IgrButton>

scripts/update-skills.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { execFileSync } from "child_process";
2+
import { cpSync, existsSync, rmSync } from "fs";
3+
import { join, relative, resolve } from "path";
4+
5+
const root = resolve(__dirname, "..");
6+
const branch = process.argv[2] || "master";
7+
8+
if (!/^[\w.\-/]+$/.test(branch) || branch.startsWith("-")) {
9+
// eslint-disable-next-line no-console
10+
console.error(`[update-skills] Invalid branch name: '${branch}'`);
11+
process.exit(1);
12+
}
13+
14+
const mappings = [
15+
{
16+
name: "angular",
17+
repo: join(root, "packages/igniteui-mcp/igniteui-doc-mcp/angular/igniteui-angular"),
18+
src: join(root, "packages/igniteui-mcp/igniteui-doc-mcp/angular/igniteui-angular/skills"),
19+
dest: join(root, "packages/igx-templates/igx-ts/projects/_base/files/__dot__claude/skills")
20+
},
21+
{
22+
name: "react",
23+
repo: join(root, "packages/igniteui-mcp/igniteui-doc-mcp/react/igniteui-react"),
24+
src: join(root, "packages/igniteui-mcp/igniteui-doc-mcp/react/igniteui-react/skills"),
25+
dest: join(root, "packages/cli/templates/react/igr-ts/projects/_base/files/__dot__claude/skills")
26+
},
27+
{
28+
name: "webcomponents",
29+
repo: join(root, "packages/igniteui-mcp/igniteui-doc-mcp/webcomponents/igniteui-webcomponents"),
30+
src: join(root, "packages/igniteui-mcp/igniteui-doc-mcp/webcomponents/igniteui-webcomponents/skills"),
31+
dest: join(root, "packages/cli/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills")
32+
}
33+
];
34+
35+
for (const { name, repo, src, dest } of mappings) {
36+
if (!existsSync(join(repo, ".git"))) {
37+
// Submodule directory exists but hasn't been initialized yet — initialize it now
38+
// eslint-disable-next-line no-console
39+
console.log(`[update-skills] Initializing submodule for ${name}...`);
40+
const submodulePath = relative(root, repo).replace(/\\/g, "/");
41+
execFileSync("git", ["submodule", "update", "--init", submodulePath], { cwd: root, stdio: "inherit" });
42+
}
43+
if (!existsSync(repo)) {
44+
// eslint-disable-next-line no-console
45+
console.warn(`[update-skills] Skipping ${name}: repo not found at ${repo}`);
46+
continue;
47+
}
48+
// eslint-disable-next-line no-console
49+
console.log(`[update-skills] Updating ${name} to branch '${branch}'...`);
50+
execFileSync("git", ["fetch", "origin", branch], { cwd: repo, stdio: "inherit" });
51+
execFileSync("git", ["checkout", "-B", branch, `origin/${branch}`], { cwd: repo, stdio: "inherit" });
52+
53+
if (!existsSync(src)) {
54+
// eslint-disable-next-line no-console
55+
console.warn(`[update-skills] Skipping ${name}: skills not found at ${src}`);
56+
continue;
57+
}
58+
if (existsSync(dest)) {
59+
rmSync(dest, { recursive: true, force: true });
60+
}
61+
cpSync(src, dest, { recursive: true });
62+
// eslint-disable-next-line no-console
63+
console.log(`[update-skills] Updated ${name} skills`);
64+
}

0 commit comments

Comments
 (0)