@epam/ai-dial-ui-kit 0.11.0-dev.16 → 0.11.0-dev.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,60 @@ var import_types = require("@modelcontextprotocol/sdk/types.js");
10
10
  var manifest = JSON.parse(
11
11
  (0, import_node_fs.readFileSync)((0, import_node_path.join)(__dirname, "components-manifest.json"), "utf-8")
12
12
  );
13
+ var changelogPath = (0, import_node_path.join)(__dirname, "CHANGELOG.md");
14
+ var changelogRaw = (0, import_node_fs.existsSync)(changelogPath) ? (0, import_node_fs.readFileSync)(changelogPath, "utf-8") : "";
15
+ var migrationGuidesDir = (0, import_node_path.join)(__dirname, "migration-guides");
16
+ function parseChangelog(content) {
17
+ const map = /* @__PURE__ */ new Map();
18
+ const sectionRegex = /^## \[(\d+\.\d+\.\d+)\]/gm;
19
+ const sections = [];
20
+ let match;
21
+ while ((match = sectionRegex.exec(content)) !== null) {
22
+ sections.push({ version: match[1], start: match.index });
23
+ }
24
+ for (let i = 0; i < sections.length; i++) {
25
+ const { version, start } = sections[i];
26
+ const end = i + 1 < sections.length ? sections[i + 1].start : content.length;
27
+ map.set(version, content.slice(start, end).trim());
28
+ }
29
+ return map;
30
+ }
31
+ var changelogSections = parseChangelog(changelogRaw);
32
+ function parseSemver(v) {
33
+ const p = v.split(".").map(Number);
34
+ return [p[0] ?? 0, p[1] ?? 0, p[2] ?? 0];
35
+ }
36
+ function semverGt(a, b) {
37
+ const [a0, a1, a2] = parseSemver(a);
38
+ const [b0, b1, b2] = parseSemver(b);
39
+ if (a0 !== b0) return a0 > b0;
40
+ if (a1 !== b1) return a1 > b1;
41
+ return a2 > b2;
42
+ }
43
+ function versionsInRange(from, to) {
44
+ return [...changelogSections.keys()].filter(
45
+ (v) => semverGt(v, from) && !semverGt(v, to)
46
+ );
47
+ }
48
+ function readMigrationGuides(versions) {
49
+ const guides = [];
50
+ if (!(0, import_node_fs.existsSync)(migrationGuidesDir)) return guides;
51
+ for (const version of versions) {
52
+ const vDir = (0, import_node_path.join)(migrationGuidesDir, version);
53
+ if (!(0, import_node_fs.existsSync)(vDir)) continue;
54
+ const files = (0, import_node_fs.readdirSync)(vDir).filter(
55
+ (f) => f.endsWith(".md") && !f.startsWith("_")
56
+ );
57
+ for (const file of files.sort()) {
58
+ guides.push({
59
+ version,
60
+ filename: file,
61
+ content: (0, import_node_fs.readFileSync)((0, import_node_path.join)(vDir, file), "utf-8")
62
+ });
63
+ }
64
+ }
65
+ return guides;
66
+ }
13
67
  var ENTITY_KINDS = [
14
68
  "component",
15
69
  "hook",
@@ -206,6 +260,24 @@ server.setRequestHandler(import_types.ListToolsRequestSchema, async () => ({
206
260
  },
207
261
  required: ["entity"]
208
262
  }
263
+ },
264
+ {
265
+ name: "getMigrationGuides",
266
+ description: 'Returns the CHANGELOG entries and step-by-step migration guides for all breaking changes introduced between two versions of @epam/ai-dial-ui-kit.\n\nPass the version you are currently on as `fromVersion` and the version you are upgrading to as `toVersion`. The tool returns the changelog section for each intermediate release plus the full text of every migration guide that applies.\n\nExamples:\n getMigrationGuides("0.9.0", "0.10.0") \u2192 changelog + guides for 0.10.0\n getMigrationGuides("0.8.0", "0.10.0") \u2192 changelog + guides for 0.9.0 and 0.10.0',
267
+ inputSchema: {
268
+ type: "object",
269
+ properties: {
270
+ fromVersion: {
271
+ type: "string",
272
+ description: 'The version you are upgrading FROM (exclusive), e.g. "0.9.0".'
273
+ },
274
+ toVersion: {
275
+ type: "string",
276
+ description: 'The version you are upgrading TO (inclusive), e.g. "0.10.0".'
277
+ }
278
+ },
279
+ required: ["fromVersion", "toVersion"]
280
+ }
209
281
  }
210
282
  ]
211
283
  }));
@@ -358,6 +430,49 @@ server.setRequestHandler(import_types.CallToolRequestSchema, async (request) =>
358
430
  }
359
431
  return { content: [{ type: "text", text: formatExport(entry) }] };
360
432
  }
433
+ if (name === "getMigrationGuides") {
434
+ const fromVersion = typeof a.fromVersion === "string" ? a.fromVersion.trim() : "";
435
+ const toVersion = typeof a.toVersion === "string" ? a.toVersion.trim() : "";
436
+ if (!fromVersion || !toVersion) {
437
+ throw new Error('"fromVersion" and "toVersion" are required.');
438
+ }
439
+ const versions = versionsInRange(fromVersion, toVersion).sort(
440
+ (a2, b) => semverGt(a2, b) ? 1 : -1
441
+ );
442
+ if (versions.length === 0) {
443
+ return {
444
+ content: [
445
+ {
446
+ type: "text",
447
+ text: `No changelog entries found for versions between ${fromVersion} (exclusive) and ${toVersion} (inclusive). Either this range is already up to date or the versions are unknown.`
448
+ }
449
+ ]
450
+ };
451
+ }
452
+ const sections = [];
453
+ for (const version of versions) {
454
+ const changelogSection = changelogSections.get(version);
455
+ if (changelogSection) sections.push(changelogSection);
456
+ const guides = readMigrationGuides([version]);
457
+ for (const guide of guides) {
458
+ sections.push(
459
+ `---
460
+
461
+ <!-- Migration guide: ${guide.version}/${guide.filename} -->
462
+
463
+ ${guide.content}`
464
+ );
465
+ }
466
+ }
467
+ return {
468
+ content: [
469
+ {
470
+ type: "text",
471
+ text: sections.join("\n\n")
472
+ }
473
+ ]
474
+ };
475
+ }
361
476
  throw new Error(`Unknown tool: ${name}`);
362
477
  });
363
478
  void (async () => {
@@ -0,0 +1,78 @@
1
+ # Migrating `DialDropdown` and `DialDropdownIcon` `menu` prop — v0.11.0
2
+
3
+ ## Why this changed
4
+
5
+ The nested `menu` object was an unnecessary indirection. Passing `items` directly as a top-level prop is simpler, more consistent with other components in the library, and friendlier to TypeScript autocomplete.
6
+
7
+ ## What changed
8
+
9
+ | Before | After |
10
+ | ----------------------------------- | --------------------------------- |
11
+ | `menu={{ items }}` | `items={items}` |
12
+ | `menu={{ items, onClick: fn }}` | `items={items} onItemClick={fn}` |
13
+ | `menu={{ items, header: node }}` | `items={items} menuHeader={node}` |
14
+ | `menu={{ items, footer: node }}` | `items={items} menuFooter={node}` |
15
+ | `DropdownMenuProps` (exported type) | Removed — no replacement needed |
16
+
17
+ Both `DialDropdown` and `DialDropdownIcon` are affected.
18
+
19
+ ## Step-by-step migration
20
+
21
+ ### 1. Find all usages
22
+
23
+ ```bash
24
+ grep -r "menu={{" src/
25
+ grep -r "DropdownMenuProps" src/
26
+ ```
27
+
28
+ ### 2. Replace with the new API
29
+
30
+ **Before:**
31
+
32
+ ```tsx
33
+ <DialDropdown menu={{ items, onClick: handleClick, header: <h4>Title</h4>, footer: <Footer /> }}>
34
+ <button type="button">Open</button>
35
+ </DialDropdown>
36
+
37
+ <DialDropdownIcon
38
+ ariaLabel="Select model"
39
+ icon={<IconBrandOpenai />}
40
+ menu={{ items, onClick: handleClick }}
41
+ />
42
+ ```
43
+
44
+ **After:**
45
+
46
+ ```tsx
47
+ <DialDropdown
48
+ items={items}
49
+ onItemClick={handleClick}
50
+ menuHeader={<h4>Title</h4>}
51
+ menuFooter={<Footer />}
52
+ >
53
+ <button type="button">Open</button>
54
+ </DialDropdown>
55
+
56
+ <DialDropdownIcon
57
+ ariaLabel="Select model"
58
+ icon={<IconBrandOpenai />}
59
+ items={items}
60
+ onItemClick={handleClick}
61
+ />
62
+ ```
63
+
64
+ ### 3. Remove `DropdownMenuProps` imports
65
+
66
+ ```tsx
67
+ // Remove this line
68
+ import type { DropdownMenuProps } from '@epam/ai-dial-ui-kit';
69
+ ```
70
+
71
+ ### 4. Verify
72
+
73
+ Run the commands specific to your project, e.g.
74
+
75
+ ```bash
76
+ npm run typecheck
77
+ npm run test
78
+ ```
@@ -0,0 +1,21 @@
1
+ # Migration Guides
2
+
3
+ This folder contains step-by-step migration guides for breaking changes introduced in each release of `@epam/ai-dial-ui-kit`.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ migration-guides/
9
+ <version>/
10
+ <migration-name>.md ← one file per breaking change
11
+ ```
12
+
13
+ ## Index
14
+
15
+ | Version | Guide | Summary |
16
+ | ------- | ----- | ------- |
17
+ | 0.11.0 | [dropdown-menu-prop-flatten](0.11.0/dropdown-menu-prop-flatten.md) | `DialDropdown`/`DialDropdownIcon` `menu` prop replaced with flat `items`, `onItemClick`, `menuHeader`, `menuFooter` props |
18
+
19
+ ---
20
+
21
+ New guides are added here whenever a breaking change is introduced. See [CHANGELOG.md](../CHANGELOG.md) for the full list of changes per release.
@@ -0,0 +1,54 @@
1
+ # Migration guide template
2
+
3
+ Use this file as a template when adding a new migration guide.
4
+ Copy it to `migration-guides/<version>/<migration-name>.md` and fill in the sections.
5
+
6
+ ---
7
+
8
+ # Migrating `<what changed>` — v`<from>` → v`<to>`
9
+
10
+ ## Why this changed
11
+
12
+ _Explain the motivation: API consistency, accessibility improvement, removed ambiguity, etc._
13
+
14
+ ## What changed
15
+
16
+ | Before | After |
17
+ | ---------- | ---------- |
18
+ | `oldThing` | `newThing` |
19
+
20
+ ## Step-by-step migration
21
+
22
+ ### 1. Find all usages
23
+
24
+ ```bash
25
+ # Example: search for the old prop name across your project
26
+ grep -r "oldPropName" src/
27
+ ```
28
+
29
+ ### 2. Replace with the new API
30
+
31
+ **Before:**
32
+
33
+ ```tsx
34
+ <DialComponent oldPropName="value" />
35
+ ```
36
+
37
+ **After:**
38
+
39
+ ```tsx
40
+ <DialComponent newPropName="value" />
41
+ ```
42
+
43
+ ### 3. Verify
44
+
45
+ Run the commands specific to your project, e.g.
46
+
47
+ ```bash
48
+ npm run typecheck
49
+ npm run test
50
+ ```
51
+
52
+ ## Notes
53
+
54
+ _Any edge cases, optional codemods, or further reading._
@@ -2,18 +2,15 @@ import { Placement } from '@floating-ui/react';
2
2
  import { FC, MouseEvent, ReactNode, RefObject } from 'react';
3
3
  import { DropdownTrigger } from '../../types/dropdown';
4
4
  import { DropdownItem } from '../../models/dropdown';
5
- export interface DropdownMenuProps {
6
- items: DropdownItem[];
7
- onClick?: (info: {
5
+ export interface DialDropdownProps {
6
+ children: ReactNode;
7
+ items?: DropdownItem[];
8
+ onItemClick?: (info: {
8
9
  key: string;
9
10
  domEvent: MouseEvent;
10
11
  }) => void;
11
- header?: ReactNode | (() => ReactNode);
12
- footer?: ReactNode | (() => ReactNode);
13
- }
14
- export interface DialDropdownProps {
15
- children: ReactNode;
16
- menu?: DropdownMenuProps;
12
+ menuHeader?: ReactNode | (() => ReactNode);
13
+ menuFooter?: ReactNode | (() => ReactNode);
17
14
  renderOverlay?: () => ReactNode;
18
15
  trigger?: DropdownTrigger[];
19
16
  placement?: Placement;
@@ -1,8 +1,7 @@
1
1
  import { FC, ReactNode } from 'react';
2
- import { DialDropdownProps, DropdownMenuProps } from '../Dropdown/Dropdown';
2
+ import { DialDropdownProps } from '../Dropdown/Dropdown';
3
3
  import { ElementSize } from '../../types/size';
4
- export interface DialDropdownIconProps extends Omit<DialDropdownProps, 'children' | 'menu' | 'className'> {
5
- menu: DropdownMenuProps;
4
+ export interface DialDropdownIconProps extends Omit<DialDropdownProps, 'children' | 'className'> {
6
5
  icon: ReactNode;
7
6
  ariaLabel: string;
8
7
  size?: ElementSize;
@@ -21,11 +20,11 @@ export interface DialDropdownIconProps extends Omit<DialDropdownProps, 'children
21
20
  * <DialDropdownIcon
22
21
  * ariaLabel="Select model"
23
22
  * icon={<IconBrandOpenai size={18} />}
24
- * menu={{ items }}
23
+ * items={items}
25
24
  * />
26
25
  * ```
27
26
  *
28
- * @param menu - Dropdown menu definition.
27
+ * @param items - Menu items to display.
29
28
  * @param icon - Primary trigger icon.
30
29
  * @param ariaLabel - Accessible name for the trigger button.
31
30
  * @param [size=ElementSize.Standard] - Trigger size.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epam/ai-dial-ui-kit",
3
- "version": "0.11.0-dev.16",
3
+ "version": "0.11.0-dev.17",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "description": "A modern UI kit for building AI DIAL interfaces with React",