@public-ui/mcp 3.0.7-rc.3 β†’ 4.0.0-alpha.2

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.
package/README.md CHANGED
@@ -30,10 +30,10 @@ The server will start on `http://localhost:3030` and provide the following endpo
30
30
  - `GET /mcp/health` - Server status and content counts
31
31
  - `GET /mcp/samples` - List all available component examples
32
32
  - `GET /mcp/sample?id=sample/button/basic` - Get specific sample source code
33
- - `GET /mcp/concepts` - List Markdown concept documentation
34
- - `GET /mcp/concept?id=concept/README` - Get a specific concept document
33
+ - `GET /mcp/docs` - List Markdown documentation
34
+ - `GET /mcp/doc?id=doc/README` - Get a specific documentation entry
35
35
 
36
- The sample and concept indexes are prebuilt for deployments, therefore no manual refresh endpoint is exposed in production.
36
+ The sample and doc indexes are prebuilt for deployments, therefore no manual refresh endpoint is exposed in production.
37
37
 
38
38
  ### Integration with AI Tools
39
39
 
@@ -68,7 +68,7 @@ const samples = await response.json();
68
68
 
69
69
  ## πŸ“š What's Included
70
70
 
71
- This MCP server provides access to **136+ KoliBri component examples** and the core **Markdown concept documentation** of the project, including:
71
+ This MCP server provides access to **136+ KoliBri component examples** and the core **Markdown documentation** of the project, including:
72
72
 
73
73
  - **Basic Components**: Button, Input, Link, Icon, Badge, etc.
74
74
  - **Form Components**: Form, Select, Textarea, Checkbox, Radio, etc.
@@ -76,7 +76,7 @@ This MCP server provides access to **136+ KoliBri component examples** and the c
76
76
  - **Navigation**: Breadcrumb, Pagination, Navigation, etc.
77
77
  - **Data Display**: Table, Alert, Toast, Progress, etc.
78
78
  - **Advanced Components**: Tree, Tooltip, Popover, etc.
79
- - **Concept Docs**: `README.md`, `docs/*.md`, migration guides, security guidelines, and more.
79
+ - **Docs**: `README.md`, `docs/*.md`, migration guides, security guidelines, and more.
80
80
 
81
81
  Each sample includes:
82
82
 
@@ -97,7 +97,6 @@ Returns server status and metadata:
97
97
  "healthy": true,
98
98
  "totalEntries": 154,
99
99
  "totalSamples": 136,
100
- "totalConcepts": 18,
101
100
  "totalDocs": 18,
102
101
  "message": "System healthy with 154 entries available",
103
102
  "generatedAt": "2024-05-28T08:15:30.000Z",
@@ -108,27 +107,27 @@ Returns server status and metadata:
108
107
  }
109
108
  ```
110
109
 
111
- ### GET /mcp/samples
110
+ ### GET /mcp/docs
112
111
 
113
- List all available samples with optional filtering:
112
+ List Markdown-based documentation entries:
114
113
 
115
114
  ```bash
116
- # Get all samples
117
- curl http://localhost:3030/mcp/samples
115
+ # Get all docs
116
+ curl http://localhost:3030/mcp/docs
118
117
 
119
- # Filter by component
120
- curl "http://localhost:3030/mcp/samples?q=button"
118
+ # Filter by term
119
+ curl "http://localhost:3030/mcp/docs?q=theme"
121
120
  ```
122
121
 
123
- ### GET /mcp/sample?id={sampleId}
122
+ ### GET /mcp/doc?id={docId}
124
123
 
125
- Get complete source code for a specific sample:
124
+ Fetch Markdown documentation by referencing its `docs/...` identifier:
126
125
 
127
126
  ```bash
128
- curl "http://localhost:3030/mcp/sample?id=sample/button/basic"
127
+ curl "http://localhost:3030/mcp/doc?id=doc/README"
129
128
  ```
130
129
 
131
- Returns:
130
+ Returns the Markdown content together with metadata. Every sample or doc response exposes a `kind` field so that clients can distinguish between component examples and documentation entries.
132
131
 
133
132
  ```json
134
133
  {
@@ -145,26 +144,26 @@ Returns:
145
144
  }
146
145
  ```
147
146
 
148
- ### GET /mcp/concepts
147
+ ### GET /mcp/docs
149
148
 
150
- List Markdown-based concept documentation entries:
149
+ List Markdown-based documentation entries:
151
150
 
152
151
  ```bash
153
- curl http://localhost:3030/mcp/concepts
152
+ curl http://localhost:3030/mcp/docs
154
153
 
155
154
  # Filter by term
156
- curl "http://localhost:3030/mcp/concepts?q=theme"
155
+ curl "http://localhost:3030/mcp/docs?q=theme"
157
156
  ```
158
157
 
159
- ### GET /mcp/concept?id={conceptId}
158
+ ### GET /mcp/doc?id={docId}
160
159
 
161
- Fetch Markdown documentation by referencing its `concepts/...` identifier:
160
+ Fetch Markdown documentation by referencing its `docs/...` identifier:
162
161
 
163
162
  ```bash
164
- curl "http://localhost:3030/mcp/concept?id=concept/README"
163
+ curl "http://localhost:3030/mcp/doc?id=doc/README"
165
164
  ```
166
165
 
167
- Returns the Markdown content together with metadata. Every sample or concept response exposes a `kind` field so that clients can distinguish between component examples and documentation entries.
166
+ Returns the Markdown content together with metadata. Every sample or doc response exposes a `kind` field so that clients can distinguish between component examples and documentation entries.
168
167
 
169
168
  All JSON responses contain an `ai-hints` string array that reiterates in English that KoliBri Web Components must be registered in the browser and that integration steps vary with the chosen project setup.
170
169
 
@@ -79,8 +79,18 @@ class SampleIndex {
79
79
  }
80
80
  async function buildSampleIndex() {
81
81
  console.log("[buildSampleIndex] Starting sample index...");
82
+ const isProduction = process.env.NODE_ENV === "production" || process.env.BUILD_MODE === "prebuild";
83
+ let samplesJsonPath;
84
+ if (isProduction) {
85
+ if (__dirname$1.endsWith("/src")) {
86
+ samplesJsonPath = path__default.resolve(__dirname$1.replace(/\/src$/, "/dist"), "samples.json");
87
+ } else {
88
+ samplesJsonPath = path__default.resolve(__dirname$1, "samples.json");
89
+ }
90
+ } else {
91
+ samplesJsonPath = path__default.resolve(__dirname$1, "samples.json");
92
+ }
82
93
  try {
83
- const samplesJsonPath = path__default.resolve(__dirname$1, "samples.json");
84
94
  console.log("[buildSampleIndex] Trying to load prebuilt samples from:", samplesJsonPath);
85
95
  const jsonData = await promises.readFile(samplesJsonPath, "utf8");
86
96
  const data = JSON.parse(jsonData);
@@ -90,6 +100,9 @@ async function buildSampleIndex() {
90
100
  console.log("[buildSampleIndex] Generated at:", data.generatedAt);
91
101
  return new SampleIndex(data.entries, new Date(data.generatedAt), data.buildMode);
92
102
  } catch (error) {
103
+ if (isProduction) {
104
+ throw new Error("[buildSampleIndex] \u274C Prebuilt samples.json not found in production/built mode. Please run the build step before deploying.");
105
+ }
93
106
  console.log("[buildSampleIndex] \u26A0\uFE0F Could not load prebuilt samples:", error.message);
94
107
  console.log("[buildSampleIndex] Falling back to runtime discovery...");
95
108
  const { buildSampleIndex: originalBuildSampleIndex } = await import('./chunks/sample-index-runtime.cjs');
@@ -72,8 +72,18 @@ class SampleIndex {
72
72
  }
73
73
  async function buildSampleIndex() {
74
74
  console.log("[buildSampleIndex] Starting sample index...");
75
+ const isProduction = process.env.NODE_ENV === "production" || process.env.BUILD_MODE === "prebuild";
76
+ let samplesJsonPath;
77
+ if (isProduction) {
78
+ if (__dirname.endsWith("/src")) {
79
+ samplesJsonPath = path.resolve(__dirname.replace(/\/src$/, "/dist"), "samples.json");
80
+ } else {
81
+ samplesJsonPath = path.resolve(__dirname, "samples.json");
82
+ }
83
+ } else {
84
+ samplesJsonPath = path.resolve(__dirname, "samples.json");
85
+ }
75
86
  try {
76
- const samplesJsonPath = path.resolve(__dirname, "samples.json");
77
87
  console.log("[buildSampleIndex] Trying to load prebuilt samples from:", samplesJsonPath);
78
88
  const jsonData = await readFile(samplesJsonPath, "utf8");
79
89
  const data = JSON.parse(jsonData);
@@ -83,6 +93,9 @@ async function buildSampleIndex() {
83
93
  console.log("[buildSampleIndex] Generated at:", data.generatedAt);
84
94
  return new SampleIndex(data.entries, new Date(data.generatedAt), data.buildMode);
85
95
  } catch (error) {
96
+ if (isProduction) {
97
+ throw new Error("[buildSampleIndex] \u274C Prebuilt samples.json not found in production/built mode. Please run the build step before deploying.");
98
+ }
86
99
  console.log("[buildSampleIndex] \u26A0\uFE0F Could not load prebuilt samples:", error.message);
87
100
  console.log("[buildSampleIndex] Falling back to runtime discovery...");
88
101
  const { buildSampleIndex: originalBuildSampleIndex } = await import('./chunks/sample-index-runtime.mjs');
package/dist/samples.json CHANGED
@@ -90,6 +90,24 @@
90
90
  "code": "# Einsteiger-How-To: KoliBri und Web Components\n\nKoliBri ist eine Sammlung barrierefreier Web Components, die Design und FunktionalitΓ€t in wiederverwendbare Bausteine kapseln. Dieses How-To richtet sich an Einsteiger und erklΓ€rt die grundlegenden Konzepte rund um KoliBri und die Nutzung von Web Components.\n\n## Warum Web Components?\n\n- **Standardisiert**: Web Components sind Teil der Web-Plattform und funktionieren ohne zusΓ€tzliche Frameworks.\n- **Wiederverwendbar**: Einmal erstellt, kΓΆnnen Komponenten in verschiedenen Projekten eingesetzt werden.\n- **Framework-unabhΓ€ngig**: Sie lassen sich in jede moderne Frontend-Technologie integrieren.\n- **Langlebig**: Standards Γ€ndern sich selten, was langfristige Wartbarkeit erleichtert.\n\n## Warum Shadow Root?\n\nDer Shadow Root kapselt Markup und Styles einer Komponente und verhindert Konflikte mit globalen CSS-Regeln.\n\n- **Style-Isolation**: Styles wirken nur innerhalb der Komponente.\n- **StabilitΓ€t**: Externe Styles beeinflussen das Verhalten der Komponente nicht.\n- **Kapselung**: DOM-Struktur und Logik bleiben unabhΓ€ngig vom restlichen Dokument.\n\n## Starkes Theming\n\nKoliBri setzt auf ein mehrschichtiges Theming mit klaren Verantwortlichkeiten:\n\n1. A11y-Preset-Layer fΓΌr grundlegende Barrierefreiheit.\n2. Basis-Global-Layer fΓΌr gemeinsame Layout-Regeln.\n3. Basis-Komponenten-Layer fΓΌr spezifische Komponenten-Stile.\n4. Theme-Global-Layer fΓΌr globale Farbschemata.\n5. Theme-Komponenten-Layer fΓΌr individuelle Anpassungen.\n\nDieses System ermΓΆglicht es, ein Corporate Design konsistent umzusetzen und dennoch flexibel zu bleiben.\n\n> **Hinweis:** CSS-Custom-Properties sind global und durchdringen auch den Shadow DOM.\n> Verwende sie nur fΓΌr ΓΆffentliche Design-Tokens und statte sie mit einem eindeutigen Prefix aus.\n> FΓΌr interne Berechnungen und Zwischenergebnisse setze stattdessen auf SASS-Variablen,\n> um Kollisionen mit Variablen auf der Host-Seite zu vermeiden.\n\n## Mindset fΓΌr KoliBri-Nutzer:innen\n\n- **Accessibility first**: Barrierefreiheit ist kein Add-on, sondern Kernbestandteil jeder Komponente.\n- **Komponenten denken**: FunktionalitΓ€t und Darstellung werden in klar abgegrenzte Bausteine aufgeteilt.\n- **Theming bewusst nutzen**: Anpassungen erfolgen ΓΌber die vorgesehenen Layer statt durch Überschreiben globaler Styles.\n- **Standard-APIs verwenden**: KoliBri nutzt moderne Browser-Schnittstellen; zusΓ€tzliche AbhΓ€ngigkeiten bleiben gering.\n\n## NΓ€chste Schritte\n\n- Installiere die Bibliothek ΓΌber npm oder pnpm.\n- Schaue dir die Beispielanwendungen im `packages/samples` Verzeichnis an.\n- Experimentiere mit eigenen Themes, um KoliBri in dein Design-System zu integrieren.\n\nViel Erfolg beim Einstieg in die Welt von KoliBri!\n",
91
91
  "kind": "doc"
92
92
  },
93
+ {
94
+ "id": "doc/HOWTO_REGISTER_COMPONENTS_AND_THEMES",
95
+ "group": "docs",
96
+ "name": "HOWTO_REGISTER_COMPONENTS_AND_THEMES",
97
+ "path": "docs/HOWTO_REGISTER_COMPONENTS_AND_THEMES.md",
98
+ "absolutePath": "/home/runner/work/kolibri/kolibri/docs/HOWTO_REGISTER_COMPONENTS_AND_THEMES.md",
99
+ "code": "# Registering KoliBri Components and Themes\n\nKoliBri Web Components ship without side effects so that you can decide _when_ and _how_ to load them.\nEvery runtimeβ€”vanilla JavaScript, React, Angular, Vue, etc.β€”must explicitly register the component set **and** at least one theme before rendering any `<kol-*>` tag. The Model Context Protocol (MCP) server exposes this guide under the concept identifier `docs/HOWTO_REGISTER_COMPONENTS_AND_THEMES` so KI agents can retrieve the exact steps.\n\n## 1. Install the packages you need\n\nInstall the component bundle plus the theme (or themes) you want to offer to your users:\n\n```bash\npnpm add @public-ui/components @public-ui/theme-default\n```\n\n> ℹ️ Replace `@public-ui/theme-default` with another theme package (e.g. `@public-ui/theme-ecl`) if you prefer a different look.\n\n## 2. Call `register` during application bootstrap\n\n```ts\nimport { register } from '@public-ui/components';\nimport { defineCustomElements } from '@public-ui/components/dist/loader';\nimport { DEFAULT } from '@public-ui/theme-default';\n\nawait register(DEFAULT, defineCustomElements);\n```\n\n- `register` wires up the custom elements and installs the provided theme(s).\n- `defineCustomElements` is generated by Stencil and registers the underlying HTML custom elements. Pass an empty array (`[]`) if your framework adapter handles element definition for you.\n- Awaiting the promise ensures the registry is ready before you render components.\n\n## 3. Register multiple themes (optional)\n\nYou can pass an array when you want to ship several themes at once:\n\n```ts\nimport { register } from '@public-ui/components';\nimport { defineCustomElements } from '@public-ui/components/dist/loader';\nimport { DEFAULT } from '@public-ui/theme-default';\nimport { ECL } from '@public-ui/theme-ecl';\n\nawait register([DEFAULT, ECL], defineCustomElements);\n```\n\nSwitching themes at runtime works through the `kol-theme` attributeβ€”no additional registration call is required.\n\n## 4. Framework-specific notes\n\n- **React / Solid / Vue**: Use the official adapters (`@public-ui/react`, `@public-ui/solid`, `@public-ui/vue`). They wrap `register` for you, but you still need to call it once in your app entry point before rendering.\n- **Angular**: Install `@public-ui/angular` and follow the schematic. It invokes `register` during the Angular bootstrapping phase.\n- **Static HTML / plain JS**: Load the ESM bundles from a CDN and call `register` with `defineCustomElements` inside a `<script type=\"module\">` block.\n\n## 5. Troubleshooting\n\n- **`<kol-button>` renders as plain text** \\\n Components were not registered. Call `register(...)` before rendering or ensure the promise resolved.\n- **Components use fallback styling** \\\n No theme was registered. Pass a theme object (e.g. `DEFAULT`) to `register`.\n- **Duplicate custom element definition error** \\\n `defineCustomElements` executed twice. Call `register` only once per page load or pass `[]` when an adapter already defines the elements.\n\n## 6. Quick reference for KI agents\n\n1. Install `@public-ui/components` + at least one theme package.\n2. Import `register` from `@public-ui/components`.\n3. Import `defineCustomElements` unless your integration takes care of it.\n4. Pass a theme (or an array of themes) and the element loader to `register`.\n5. Await the promise before rendering `<kol-*>` components.\n\nKeep this checklist handy; the MCP endpoint will always return the latest version of this guide.\n",
100
+ "kind": "doc"
101
+ },
102
+ {
103
+ "id": "doc/KNOWN_ISSUES",
104
+ "group": "docs",
105
+ "name": "KNOWN_ISSUES",
106
+ "path": "KNOWN_ISSUES.md",
107
+ "absolutePath": "/home/runner/work/kolibri/kolibri/KNOWN_ISSUES.md",
108
+ "code": "# Known Issues\n\n## General\n\n### Limited support for `aria-description` (WAI-ARIA 1.2)\n\n- `aria-description` was introduced with [WAI-ARIA 1.2](https://www.w3.org/TR/wai-aria-1.2/#aria-description), but many assistive technologies have not yet adopted it and continue to rely solely on `aria-describedby` when presenting supplementary text. Components that accept `_ariaDescription` therefore keep rendering hidden fallback markup and set both attributes so older screen readers still expose the description.\n\n## select\n\n### All text inputs\n\nIn Chrome on Windows, clicking outside an HTML input but inside a Web Component does not give focus to the input when it is empty. This issue sometimes does not occur if the input already contains a value. We suspect a focus propagation problem related to Web Component behavior.\n\n[🐞 GitHub issue #7713](https://github.com/public-ui/kolibri/issues/7713)\n\n### NVDA spells out certain words instead of reading them\n\nIt has been observed that on a system with German locale, NVDA spells out certain English words such as \"selection\", instead of reading them properly.\n\n[🐞 GitHub issue #6898](https://github.com/public-ui/kolibri/issues/6898),\n[Stack Overflow](https://stackoverflow.com/questions/69091167/nvda-spells-words-where-it-shouldnt)\n\n### Text selection in Firefox\n\nIn Firefox, text selection when using Web Components does not work as expected. Highlighting and selecting text behaves inconsistently or fails.\n\n[🐞 GitHub issue #7761](https://github.com/public-ui/kolibri/issues/7761),\n[Mozilla Bug #1587724](https://bugzilla.mozilla.org/show_bug.cgi?id=1587724),\n[Mozilla Bug #1233594](https://bugzilla.mozilla.org/show_bug.cgi?id=1233594),\n[Mozilla Bug #1590379](https://bugzilla.mozilla.org/show_bug.cgi?id=1590379)\n\n## Components\n\n### kol-select\n\n- Disabled options in KolSelect affect the total count in some screen readers. When an option is set to `disabled: true`, it may still be included in the overall option count announced by assistive technology. Using `aria-hidden=\"true\"` on `<option>` is not conforming with WAI-ARIA and causes browser warnings, therefore it has been removed. As a result, screen readers might announce a higher number of available options than can actually be selected.\n\n[🐞 GitHub issue #7453](https://github.com/public-ui/kolibri/pull/7453)\n[🐞 GitHub issue #7920](https://github.com/public-ui/kolibri/pull/7920)\n\n### kol-input-color\n\nThe component InputColor is a wrapper for the native HTML element `<input type=\"color\">` which has accessibility problems:\n\n- With NVDA, the element is announced as \"clickable\" and not as an input element.\n- It's not possible to select a color using a screen reader.\n- **9.1.3.1h Labeling of form elements programmatically detectable:**\n The label is not announced by the screen reader. Since it reads linearly, no label is perceivable when `hideLabel` is used.\n- **9.1.3.2 Meaningful sequence:**\n When opening the color selection for \"Color with error,\" there is no output. It is not accessible via the Tab key, only with the arrow keys, making it very confusing for screen reader users.\n- **9.2.4.3 Logical keyboard navigation order:**\n The focus order for \"Color with error\" is very unusual. Users do not realize that they have to use arrow keys to enter. This is especially problematic since it is not visible on black.\n- **9.2.4.7 Clearly visible focus position:**\n The focus is not visible on the black color icon in \"Color with error.\"\n\nFor full accessibility, consider using predefined colors lists, e.g. using KolSelect or KolCheckbox.\n\n[🐞 GitHub issue #5549](https://github.com/public-ui/kolibri/issues/5549),\n[🐞 GitHub issue #7455](https://github.com/public-ui/kolibri/pull/7455)\n\n### kol-table-stateful and kol-table-stateless\n\n#### `aria-sort` changes sometimes not announced in NVDA\n\nWhen a table column changes its sort order (i.e. when its `aria-sort` attribute changes), screen readers announce this change automatically. For unknown reasons, this sometimes does not happen in NVDA.\n\n[🐞 GitHub issue (PR) #5780](https://github.com/public-ui/kolibri/pull/5780),\n[🐞 NVDA issue #10890](https://github.com/nvaccess/nvda/issues/10890),\n[🐞 NVDA issue #8132](https://github.com/nvaccess/nvda/issues/8132)\n\n#### Sticky headers\n\nSticky headers in tables are not supported at the moment, because `position: sticky` doesn't work together with `overflow: auto` on the table container, without introducing other drawbacks.\n\n[🐞 GitHub issue #7490](https://github.com/public-ui/kolibri/issues/7490),\n[CSSWG Drafts issue](https://github.com/w3c/csswg-drafts/issues/865),\n[Code sample (StackBlitz)](https://stackblitz.com/edit/stackblitz-starters-umfg2y7m)\n\n### kol-input-number and kol-input-date\n\n#### `readonly` not announced in NVDA\n\nThe components InputNumber and InputDate render their respective native HTML elements `<input type=\"number\">` and `<input type=\"date\">` which both support the attribute `readonly`. When focusing the element, it's expected that the `readonly` attribute is announced as part of the element description. This isn't the case for NVDA.\n\n[🐞 GitHub issue #5554](https://github.com/public-ui/kolibri/issues/5554) (For number),\n[🐞 GitHub issue #5749](https://github.com/public-ui/kolibri/issues/5749) (For date),\n[🐞 NVDA issue #13672](https://github.com/nvaccess/nvda/issues/13672)\n\n### kol-input-date\n\n#### VoiceOver reads date inputs with percentage in Google Chrome\n\nIn Google Chrome, when using VoiceOver with empty `date` input fields (no initial value), an unexpected percentage value is read aloud alongside the usual prompt.\n\nNotably, this issue does not occur with Windows Narrator, which handles empty date inputs correctly.\n\nThere is a bug report for this issue:\n\n[VoiceOver reads negative percent values for month, day, and year steppers in `<input type=\"date\">`](https://issuetracker.google.com/issues/361250561?pli=1)\n\n### kol-input-text\n\nThe `search` of this component is highly browser-dependent. For example, the close button is either shown or hidden depending on the browser. Accessibility is therefore not achieved.\n\n[🐞 GitHub issue #6307](https://github.com/public-ui/kolibri/issues/6307)\n\n### kol-select\n\n#### Screen reader only reads last selected option\n\nKolSelect is using native HTML `<select>`.\n\nWhen using KolSelect with the `multiple` property, the native HTML `<select>` may cause problems with screen readers. Often the entire selection is not read out, but only the last one. Therefore, the KolSelect has no full accessibility.\n\n#### Limited styling capabilities for `<select>` and `<option>` elements\n\n[Stackblitz example](https://stackblitz.com/edit/vitejs-vite-nthnce?file=src%2Fstyle.css)\n\nThe `<select>` element and its `<option>` tags offer limited styling options. Specifically, states such as \"selected\", \"focus\" or \"active\" cannot be reliably customized using CSS. This leads to challenges in meeting accessibility standards, especially in ensuring sufficient contrast ratios.\n\n**Impact**:\n\n- **Limited customization**: The visual state of dropdown options (e.g., on focus or selection) cannot be consistently customized across all browsers. This makes it difficult to create an accessible visual experience for all users.\n- **Browser-dependent rendering**: The appearance of the `<select>` element varies across browsers and operating systems, resulting in inconsistent user experiences.\n- **Contrast issues**: Since the contrast of the default dropdown rendering is controlled by the browser, it's not always possible to ensure WCAG-compliant contrast ratios, which may hinder readability for users with visual impairments.\n\n### kol-icon\n\n#### Firefox accessibility issue with `aria-label`\n\nThe use of `aria-label` or `aria-labelledby` on `<kol-icon>` or its nested elements does not work reliably in Firefox. Even applying these attributes directly to `<kol-icon>` has no effect, which points to a browser-specific issue with ARIA support in custom elements or shadow DOM contexts.\n\n##### Key points\n\n- The issue lies in Firefox's handling of ARIA attributes on custom web components or deeply nested elements.\n- This is not related to dynamic announcements (`aria-live`) but specifically to the inability of Firefox to process `aria-label` or `aria-labelledby` correctly in these cases.\n- The issue is browser-specific and does not consistently occur in Chrome, Edge, or Safari.\n\n##### Conclusion\n\nThis is a limitation in Firefox’s ARIA implementation. Until it is resolved, alternative strategies like visually hidden text near the element or redundant error messages should be used to ensure accessibility.\n\n[🐞 GitHub issue #7076](https://github.com/public-ui/kolibri/issues/7076),\n[🐞 GitHub issue #7119](https://github.com/public-ui/kolibri/issues/7119)\n\n### Toaster\n\nToasts are rendered in a container that's appended as first element of `<body>` and elevated using a high `z-index`.\n\nWhen using [modal dialogs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) these are rendered above toasts on the [top layer](https://developer.mozilla.org/en-US/docs/Glossary/Top_layer). Hence, toast messages are always blocked by modal dialogs. We recommend completely avoiding toasts in modals and giving feedback within the modal directly.\n",
109
+ "kind": "doc"
110
+ },
93
111
  {
94
112
  "id": "doc/MIGRATION",
95
113
  "group": "docs",
@@ -285,7 +303,7 @@
285
303
  "name": "icons",
286
304
  "path": "packages/samples/react/src/components/button-link/icons.tsx",
287
305
  "absolutePath": "/home/runner/work/kolibri/kolibri/packages/samples/react/src/components/button-link/icons.tsx",
288
- "code": "import React from 'react';\n\nimport { KolButtonLink } from '@public-ui/react-v19';\n\nimport type { FC } from 'react';\nimport { SampleDescription } from '../SampleDescription';\n\nexport const ButtonLinkIcons: FC = () => (\n\t<>\n\t\t<SampleDescription>\n\t\t\t<p>This sample shows KolButtonLink with icons in different locations.</p>\n\t\t</SampleDescription>\n\n\t\t<div className=\"grid gap-4\">\n\t\t\t<KolButtonLink _icons=\"codicon codicon-home\" _label=\"Ich bin ein Link mit Icon links\" />\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\tright: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with an icon on the right\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\ttop: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with an icon at the top\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\tbottom: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with icon below\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\ttop: 'codicon codicon-home',\n\t\t\t\t\tright: 'codicon codicon-home',\n\t\t\t\t\tbottom: 'codicon codicon-home',\n\t\t\t\t\tleft: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with all icons\"\n\t\t\t/>\n\t\t</div>\n\t</>\n);\n",
306
+ "code": "import React from 'react';\n\nimport { KolButtonLink } from '@public-ui/react-v19';\n\nimport type { FC } from 'react';\nimport { SampleDescription } from '../SampleDescription';\n\nexport const ButtonLinkIcons: FC = () => (\n\t<>\n\t\t<SampleDescription>\n\t\t\t<p>This sample shows KolButtonLink with icons in different locations.</p>\n\t\t</SampleDescription>\n\n\t\t<div className=\"grid gap-4\">\n\t\t\t<KolButtonLink _icons=\"codicon codicon-home\" _label=\"I am a link with an icon on the left\" />\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\tright: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with an icon on the right\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\ttop: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with an icon at the top\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\tbottom: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with icon below\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\ttop: 'codicon codicon-home',\n\t\t\t\t\tright: 'codicon codicon-home',\n\t\t\t\t\tbottom: 'codicon codicon-home',\n\t\t\t\t\tleft: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with all icons\"\n\t\t\t/>\n\t\t\t<KolButtonLink _icons=\"codicon codicon-home\" _hideLabel _label=\"I am a link with icon only\" />\n\t\t</div>\n\t</>\n);\n",
289
307
  "kind": "sample"
290
308
  },
291
309
  {
@@ -762,7 +780,7 @@
762
780
  "name": "basic",
763
781
  "path": "packages/samples/react/src/components/link/basic.tsx",
764
782
  "absolutePath": "/home/runner/work/kolibri/kolibri/packages/samples/react/src/components/link/basic.tsx",
765
- "code": "import type { FC } from 'react';\nimport React from 'react';\n\nimport { KolLink, KolHeading } from '@public-ui/react-v19';\nimport { SampleDescription } from '../SampleDescription';\n\nexport const LinkBasic: FC = () => (\n\t<>\n\t\t<SampleDescription>\n\t\t\t<p>\n\t\t\t\tKolLink renders a link. This sample shows disabled links, links with hidden label and links with different CSS <code>display</code>-properties.\n\t\t\t</p>\n\t\t</SampleDescription>\n\n\t\t<div className=\"grid gap-4\">\n\t\t\t<KolHeading _level={2} _label=\"Links with variant 'standalone'\" />\n\t\t\t<KolLink _href=\"#/back-page\" _label=\"Simple Link\" _variant=\"standalone\" />\n\t\t\t<KolLink _disabled _href=\"#/back-page\" _label=\"Simple Link (deaktiviert)\" _variant=\"standalone\" />\n\t\t\t<KolLink _hideLabel _icons=\"codicon codicon-home\" _href=\"#/back-page\" _label=\"Icon Link\" _variant=\"standalone\" />\n\t\t\t<KolLink _disabled _hideLabel _icons=\"codicon codicon-home\" _href=\"#/back-page\" _label=\"Icon Link (deaktiviert)\" _variant=\"standalone\" />\n\n\t\t\t<KolHeading _level={2} _label=\"Links with variant 'inline'\" />\n\t\t\t<p>\n\t\t\t\tIn this paragraph, a link is inserted that contains no additional attributes. <KolLink _href=\"#/back-page\" _label=\"Simple Link\" /> It is rendered by\n\t\t\t\tdefault as a <strong>inline element</strong>.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tIn this paragraph, a link is inserted that is rendered as an inline-block element.{' '}\n\t\t\t\t<KolLink class=\"d-inline-block\" _accessKey=\"S\" _href=\"#/back-page\" _label=\"Simple Link\" />. This allows you to assign width, height, and other\n\t\t\t\tproperties to it using CSS styles.\n\t\t\t\t<br />\n\t\t\t\t<br />\n\t\t\t\tAfter that, there is a link that is rendered as a block element. <KolLink class=\"d-block\" _href=\"#/back-page\" _label=\"Simple Link\" />, therefore, I span\n\t\t\t\tthe entire width of the parent element, causing a line break.\n\t\t\t</p>\n\t\t</div>\n\t</>\n);\n",
783
+ "code": "import type { FC } from 'react';\nimport React from 'react';\n\nimport { KolLink } from '@public-ui/react-v19';\nimport { SampleDescription } from '../SampleDescription';\n\nexport const LinkBasic: FC = () => (\n\t<>\n\t\t<SampleDescription>\n\t\t\t<p>\n\t\t\t\tKolLink renders a link. This sample shows disabled links, links with hidden label and links with different CSS <code>display</code>-properties.\n\t\t\t</p>\n\t\t</SampleDescription>\n\n\t\t<div className=\"grid gap-4\">\n\t\t\t<KolLink _href=\"#/back-page\" _label=\"Simple Link\" _variant=\"standalone\" />\n\t\t\t<KolLink _disabled _href=\"#/back-page\" _label=\"Simple Link (disabled)\" _variant=\"standalone\" />\n\t\t\t<KolLink _hideLabel _icons=\"codicon codicon-home\" _href=\"#/back-page\" _label=\"Icon Link\" _variant=\"standalone\" />\n\t\t\t<KolLink _disabled _hideLabel _icons=\"codicon codicon-home\" _href=\"#/back-page\" _label=\"Icon Link (disabled)\" _variant=\"standalone\" />\n\t\t\t<p>\n\t\t\t\tIn this paragraph, a link is inserted that contains no additional attributes. <KolLink _href=\"#/back-page\" _label=\"Simple Link\" /> It is rendered by\n\t\t\t\tdefault as a <strong>inline element</strong>.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tIn this paragraph, a link is inserted that is rendered as an inline-block element.{' '}\n\t\t\t\t<KolLink class=\"d-inline-block\" _accessKey=\"S\" _href=\"#/back-page\" _label=\"Simple Link\" />. This allows you to assign width, height, and other\n\t\t\t\tproperties to it using CSS styles.\n\t\t\t\t<br />\n\t\t\t\t<br />\n\t\t\t\tAfter that, there is a link that is rendered as a block element. <KolLink class=\"d-block\" _href=\"#/back-page\" _label=\"Simple Link\" />, therefore, I span\n\t\t\t\tthe entire width of the parent element, causing a line break.\n\t\t\t</p>\n\t\t</div>\n\t</>\n);\n",
766
784
  "kind": "sample"
767
785
  },
768
786
  {
@@ -1203,7 +1221,7 @@
1203
1221
  "name": "stateless-with-selection",
1204
1222
  "path": "packages/samples/react/src/components/table/stateless-with-selection.tsx",
1205
1223
  "absolutePath": "/home/runner/work/kolibri/kolibri/packages/samples/react/src/components/table/stateless-with-selection.tsx",
1206
- "code": "import type { FC } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { createReactRenderElement, KolButton, KolTableStateless } from '@public-ui/react-v19';\nimport { SampleDescription } from '../SampleDescription';\nimport type { KoliBriTableCell, KoliBriTableSelection } from '@public-ui/components';\nimport { KolEvent } from '@public-ui/components';\nimport { getRoot } from '../../shares/react-roots';\nimport { useToasterService } from '../../hooks/useToasterService';\n\nconst DATA = [\n\t{ id: '1001', name: 'Foo Bar', internalIdentifier: `AAA1001` },\n\t{ id: '1002', name: 'Foo Baz', internalIdentifier: `AAA1002` },\n\t{ id: '1003', name: 'This row is always unchecked', internalIdentifier: `AAA1003` },\n\t{ id: '1004', name: 'This row is always checked', internalIdentifier: `AAA1004` },\n];\ntype Data = (typeof DATA)[0];\n\nfunction KolButtonWrapper({ label }: { label: string }) {\n\tconst { dummyClickEventHandler } = useToasterService();\n\n\tconst dummyEventHandler = {\n\t\tonClick: dummyClickEventHandler,\n\t};\n\n\treturn <KolButton _label={label} _on={dummyEventHandler} />;\n}\n\nexport const TableStatelessWithSelection: FC = () => {\n\tconst [selectedKeys, setSelectedKeys] = useState(['AAA1002', 'AAA1004']);\n\n\tconst selection: KoliBriTableSelection = {\n\t\tlabel: (row) => `Selection for ${(row as Data).name}`,\n\t\tselectedKeys,\n\t\tkeyPropertyName: 'internalIdentifier',\n\t\tdisabledKeys: ['AAA1003', 'AAA1004'],\n\t};\n\n\tconst kolTableStatelessRef = useRef<HTMLKolTableStatelessElement>(null);\n\n\tconst handleSelectionChangeEvent = ({ detail: selection }: { detail: string[] }) => {\n\t\tconsole.log('Selection change via event', selection);\n\t};\n\tconst handleSelectionChangeCallback = (_event: Event, selection: string[] | string) => {\n\t\tconsole.log('Selection change via callback', selection);\n\t\tsetSelectedKeys(typeof selection === 'string' ? [selection] : selection);\n\t};\n\n\tuseEffect(() => {\n\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\tkolTableStatelessRef.current?.addEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\n\t\treturn () => {\n\t\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\t\tkolTableStatelessRef.current?.removeEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\t\t};\n\t}, [kolTableStatelessRef]);\n\n\tconst renderButton = (element: HTMLElement, cell: KoliBriTableCell) => {\n\t\tgetRoot(createReactRenderElement(element)).render(<KolButtonWrapper label={`Click ${cell.data?.id}`} />);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This sample shows KolTableStateless with checkboxes for selection enabled.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<section className=\"w-full\">\n\t\t\t\t<KolTableStateless\n\t\t\t\t\t_label=\"Table with selection checkboxes\"\n\t\t\t\t\t_minWidth=\"auto\"\n\t\t\t\t\t_headerCells={{\n\t\t\t\t\t\thorizontal: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t{ key: 'id', label: '#ID', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'name', label: 'Name', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'action', label: 'Action', textAlign: 'left', render: renderButton },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t\t_data={DATA}\n\t\t\t\t\t_selection={selection}\n\t\t\t\t\t_on={{ onSelectionChange: handleSelectionChangeCallback }}\n\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\tstyle={{ maxWidth: '600px' }}\n\t\t\t\t\tref={kolTableStatelessRef}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</>\n\t);\n};\n",
1224
+ "code": "import type { KoliBriTableCell, KoliBriTableSelection, KoliBriTableSelectionKeys } from '@public-ui/components';\nimport { KolEvent } from '@public-ui/components';\nimport { createReactRenderElement, KolButton, KolTableStateless } from '@public-ui/react-v19';\nimport type { FC } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useToasterService } from '../../hooks/useToasterService';\nimport { getRoot } from '../../shares/react-roots';\nimport { SampleDescription } from '../SampleDescription';\n\ntype SelectionValue = string | number;\n\nconst DATA = [\n\t{ id: '1001', name: 'Foo Bar', internalIdentifier: `AAA1001` },\n\t{ id: '1002', name: 'Foo Baz', internalIdentifier: `AAA1002` },\n\t{ id: '1003', name: 'This row is always unchecked', internalIdentifier: `AAA1003` },\n\t{ id: '1004', name: 'This row is always checked', internalIdentifier: `AAA1004` },\n];\ntype Data = (typeof DATA)[0];\n\nfunction KolButtonWrapper({ label }: { label: string }) {\n\tconst { dummyClickEventHandler } = useToasterService();\n\n\tconst dummyEventHandler = {\n\t\tonClick: dummyClickEventHandler,\n\t};\n\n\treturn <KolButton _label={label} _on={dummyEventHandler} />;\n}\n\nexport const TableStatelessWithSelection: FC = () => {\n\tconst [selectedKeys, setSelectedKeys] = useState<KoliBriTableSelectionKeys>(['AAA1002', 'AAA1004']);\n\n\tconst selection: KoliBriTableSelection = {\n\t\tlabel: (row) => `Selection for ${(row as Data).name}`,\n\t\tselectedKeys,\n\t\tkeyPropertyName: 'internalIdentifier',\n\t\tdisabledKeys: ['AAA1003', 'AAA1004'],\n\t};\n\n\tconst kolTableStatelessRef = useRef<HTMLKolTableStatelessElement>(null);\n\n\tconst handleSelectionChangeEvent = ({ detail: selection }: { detail: string[] }) => {\n\t\tconsole.log('Selection change via event', selection);\n\t};\n\tconst handleSelectionChangeCallback = (_event: Event, selection: SelectionValue[] | SelectionValue) => {\n\t\tconsole.log('Selection change via callback', selection);\n\t\tsetSelectedKeys(Array.isArray(selection) ? selection : [selection]);\n\t};\n\n\tuseEffect(() => {\n\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\tkolTableStatelessRef.current?.addEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\n\t\treturn () => {\n\t\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\t\tkolTableStatelessRef.current?.removeEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\t\t};\n\t}, [kolTableStatelessRef]);\n\n\tconst renderButton = (element: HTMLElement, cell: KoliBriTableCell) => {\n\t\tgetRoot(createReactRenderElement(element)).render(<KolButtonWrapper label={`Click ${cell.data?.id}`} />);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This sample shows KolTableStateless with checkboxes for selection enabled.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<section className=\"w-full\">\n\t\t\t\t<KolTableStateless\n\t\t\t\t\t_label=\"Table with selection checkboxes\"\n\t\t\t\t\t_minWidth=\"auto\"\n\t\t\t\t\t_headerCells={{\n\t\t\t\t\t\thorizontal: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t{ key: 'id', label: '#ID', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'name', label: 'Name', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'action', label: 'Action', textAlign: 'left', render: renderButton },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t\t_data={DATA}\n\t\t\t\t\t_selection={selection}\n\t\t\t\t\t_on={{ onSelectionChange: handleSelectionChangeCallback }}\n\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\tstyle={{ maxWidth: '600px' }}\n\t\t\t\t\tref={kolTableStatelessRef}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</>\n\t);\n};\n",
1207
1225
  "kind": "sample"
1208
1226
  },
1209
1227
  {
@@ -1221,7 +1239,7 @@
1221
1239
  "name": "stateless-with-single-selection",
1222
1240
  "path": "packages/samples/react/src/components/table/stateless-with-single-selection.tsx",
1223
1241
  "absolutePath": "/home/runner/work/kolibri/kolibri/packages/samples/react/src/components/table/stateless-with-single-selection.tsx",
1224
- "code": "import type { FC } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { createReactRenderElement, KolButton, KolTableStateless } from '@public-ui/react-v19';\nimport { SampleDescription } from '../SampleDescription';\nimport type { KoliBriTableCell, KoliBriTableSelection } from '@public-ui/components';\nimport { KolEvent } from '@public-ui/components';\nimport { getRoot } from '../../shares/react-roots';\nimport { useToasterService } from '../../hooks/useToasterService';\n\nconst DATA = [\n\t{ id: '1001', name: 'Foo Bar', internalIdentifier: `AAA1001` },\n\t{ id: '1002', name: 'Foo Baz', internalIdentifier: `AAA1002` },\n\t{ id: '1003', name: 'Foo Disabled', internalIdentifier: `AAA1003` },\n];\ntype Data = (typeof DATA)[0];\n\nfunction KolButtonWrapper({ label }: { label: string }) {\n\tconst { dummyClickEventHandler } = useToasterService();\n\n\tconst dummyEventHandler = {\n\t\tonClick: dummyClickEventHandler,\n\t};\n\n\treturn <KolButton _label={label} _on={dummyEventHandler} />;\n}\n\nexport const TableStatelessWithSingleSelection: FC = () => {\n\tconst [selectedKeys, setSelectedKeys] = useState(['1002']);\n\n\tconst selection: KoliBriTableSelection = {\n\t\tlabel: (row) => `Selection for ${(row as Data).name}`,\n\t\tmultiple: false,\n\t\tselectedKeys,\n\t\tdisabledKeys: ['AAA1003'],\n\t\tkeyPropertyName: 'internalIdentifier',\n\t};\n\n\tconst kolTableStatelessRef = useRef<HTMLKolTableStatelessElement>(null);\n\n\tconst handleSelectionChangeEvent = ({ detail: selection }: { detail: string[] }) => {\n\t\tconsole.log('Selection change via event', selection);\n\t};\n\tconst handleSelectionChangeCallback = (_event: Event, selection: string[] | string) => {\n\t\tconsole.log('Selection change via callback', selection);\n\t\tsetSelectedKeys(typeof selection === 'string' ? [selection] : selection);\n\t};\n\n\tuseEffect(() => {\n\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\tkolTableStatelessRef.current?.addEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\n\t\treturn () => {\n\t\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\t\tkolTableStatelessRef.current?.removeEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\t\t};\n\t}, [kolTableStatelessRef]);\n\n\tconst renderButton = (element: HTMLElement, cell: KoliBriTableCell) => {\n\t\tgetRoot(createReactRenderElement(element)).render(<KolButtonWrapper label={`Click ${cell.data?.id}`} />);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This sample shows KolTableStateless with checkboxes for selection enabled.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<section className=\"w-full\">\n\t\t\t\t<KolTableStateless\n\t\t\t\t\t_label=\"Table with selection checkboxes\"\n\t\t\t\t\t_minWidth=\"auto\"\n\t\t\t\t\t_headerCells={{\n\t\t\t\t\t\thorizontal: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t{ key: 'id', label: '#ID', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'name', label: 'Name', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'action', label: 'Action', textAlign: 'left', render: renderButton },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t\t_data={DATA}\n\t\t\t\t\t_selection={selection}\n\t\t\t\t\t_on={{ onSelectionChange: handleSelectionChangeCallback }}\n\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\tstyle={{ maxWidth: '600px' }}\n\t\t\t\t\tref={kolTableStatelessRef}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</>\n\t);\n};\n",
1242
+ "code": "import type { KoliBriTableCell, KoliBriTableSelection, KoliBriTableSelectionKeys } from '@public-ui/components';\nimport { KolEvent } from '@public-ui/components';\nimport { createReactRenderElement, KolButton, KolTableStateless } from '@public-ui/react-v19';\nimport type { FC } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useToasterService } from '../../hooks/useToasterService';\nimport { getRoot } from '../../shares/react-roots';\nimport { SampleDescription } from '../SampleDescription';\n\ntype SelectionValue = string | number;\n\nconst DATA = [\n\t{ id: '1001', name: 'Foo Bar', internalIdentifier: `AAA1001` },\n\t{ id: '1002', name: 'Foo Baz', internalIdentifier: `AAA1002` },\n\t{ id: '1003', name: 'Foo Disabled', internalIdentifier: `AAA1003` },\n];\ntype Data = (typeof DATA)[0];\n\nfunction KolButtonWrapper({ label }: { label: string }) {\n\tconst { dummyClickEventHandler } = useToasterService();\n\n\tconst dummyEventHandler = {\n\t\tonClick: dummyClickEventHandler,\n\t};\n\n\treturn <KolButton _label={label} _on={dummyEventHandler} />;\n}\n\nexport const TableStatelessWithSingleSelection: FC = () => {\n\tconst [selectedKeys, setSelectedKeys] = useState<KoliBriTableSelectionKeys>(['1002']);\n\n\tconst selection: KoliBriTableSelection = {\n\t\tlabel: (row) => `Selection for ${(row as Data).name}`,\n\t\tmultiple: false,\n\t\tselectedKeys,\n\t\tdisabledKeys: ['AAA1003'],\n\t\tkeyPropertyName: 'internalIdentifier',\n\t};\n\n\tconst kolTableStatelessRef = useRef<HTMLKolTableStatelessElement>(null);\n\n\tconst handleSelectionChangeEvent = ({ detail: selection }: { detail: string[] }) => {\n\t\tconsole.log('Selection change via event', selection);\n\t};\n\tconst handleSelectionChangeCallback = (_event: Event, selection: SelectionValue[] | SelectionValue) => {\n\t\tconsole.log('Selection change via callback', selection);\n\t\tsetSelectedKeys(Array.isArray(selection) ? selection : [selection]);\n\t};\n\n\tuseEffect(() => {\n\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\tkolTableStatelessRef.current?.addEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\n\t\treturn () => {\n\t\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\t\tkolTableStatelessRef.current?.removeEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\t\t};\n\t}, [kolTableStatelessRef]);\n\n\tconst renderButton = (element: HTMLElement, cell: KoliBriTableCell) => {\n\t\tgetRoot(createReactRenderElement(element)).render(<KolButtonWrapper label={`Click ${cell.data?.id}`} />);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This sample shows KolTableStateless with checkboxes for selection enabled.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<section className=\"w-full\">\n\t\t\t\t<KolTableStateless\n\t\t\t\t\t_label=\"Table with selection checkboxes\"\n\t\t\t\t\t_minWidth=\"auto\"\n\t\t\t\t\t_headerCells={{\n\t\t\t\t\t\thorizontal: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t{ key: 'id', label: '#ID', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'name', label: 'Name', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'action', label: 'Action', textAlign: 'left', render: renderButton },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t\t_data={DATA}\n\t\t\t\t\t_selection={selection}\n\t\t\t\t\t_on={{ onSelectionChange: handleSelectionChangeCallback }}\n\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\tstyle={{ maxWidth: '600px' }}\n\t\t\t\t\tref={kolTableStatelessRef}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</>\n\t);\n};\n",
1225
1243
  "kind": "sample"
1226
1244
  },
1227
1245
  {
@@ -1405,6 +1423,6 @@
1405
1423
  "kind": "sample"
1406
1424
  }
1407
1425
  ],
1408
- "generatedAt": "2025-10-11T04:24:23.973Z",
1426
+ "generatedAt": "2025-10-12T03:00:19.944Z",
1409
1427
  "buildMode": "prebuild"
1410
1428
  }
package/dist/samples.mjs CHANGED
@@ -91,6 +91,24 @@ export const samplesData = {
91
91
  "code": "# Einsteiger-How-To: KoliBri und Web Components\n\nKoliBri ist eine Sammlung barrierefreier Web Components, die Design und FunktionalitΓ€t in wiederverwendbare Bausteine kapseln. Dieses How-To richtet sich an Einsteiger und erklΓ€rt die grundlegenden Konzepte rund um KoliBri und die Nutzung von Web Components.\n\n## Warum Web Components?\n\n- **Standardisiert**: Web Components sind Teil der Web-Plattform und funktionieren ohne zusΓ€tzliche Frameworks.\n- **Wiederverwendbar**: Einmal erstellt, kΓΆnnen Komponenten in verschiedenen Projekten eingesetzt werden.\n- **Framework-unabhΓ€ngig**: Sie lassen sich in jede moderne Frontend-Technologie integrieren.\n- **Langlebig**: Standards Γ€ndern sich selten, was langfristige Wartbarkeit erleichtert.\n\n## Warum Shadow Root?\n\nDer Shadow Root kapselt Markup und Styles einer Komponente und verhindert Konflikte mit globalen CSS-Regeln.\n\n- **Style-Isolation**: Styles wirken nur innerhalb der Komponente.\n- **StabilitΓ€t**: Externe Styles beeinflussen das Verhalten der Komponente nicht.\n- **Kapselung**: DOM-Struktur und Logik bleiben unabhΓ€ngig vom restlichen Dokument.\n\n## Starkes Theming\n\nKoliBri setzt auf ein mehrschichtiges Theming mit klaren Verantwortlichkeiten:\n\n1. A11y-Preset-Layer fΓΌr grundlegende Barrierefreiheit.\n2. Basis-Global-Layer fΓΌr gemeinsame Layout-Regeln.\n3. Basis-Komponenten-Layer fΓΌr spezifische Komponenten-Stile.\n4. Theme-Global-Layer fΓΌr globale Farbschemata.\n5. Theme-Komponenten-Layer fΓΌr individuelle Anpassungen.\n\nDieses System ermΓΆglicht es, ein Corporate Design konsistent umzusetzen und dennoch flexibel zu bleiben.\n\n> **Hinweis:** CSS-Custom-Properties sind global und durchdringen auch den Shadow DOM.\n> Verwende sie nur fΓΌr ΓΆffentliche Design-Tokens und statte sie mit einem eindeutigen Prefix aus.\n> FΓΌr interne Berechnungen und Zwischenergebnisse setze stattdessen auf SASS-Variablen,\n> um Kollisionen mit Variablen auf der Host-Seite zu vermeiden.\n\n## Mindset fΓΌr KoliBri-Nutzer:innen\n\n- **Accessibility first**: Barrierefreiheit ist kein Add-on, sondern Kernbestandteil jeder Komponente.\n- **Komponenten denken**: FunktionalitΓ€t und Darstellung werden in klar abgegrenzte Bausteine aufgeteilt.\n- **Theming bewusst nutzen**: Anpassungen erfolgen ΓΌber die vorgesehenen Layer statt durch Überschreiben globaler Styles.\n- **Standard-APIs verwenden**: KoliBri nutzt moderne Browser-Schnittstellen; zusΓ€tzliche AbhΓ€ngigkeiten bleiben gering.\n\n## NΓ€chste Schritte\n\n- Installiere die Bibliothek ΓΌber npm oder pnpm.\n- Schaue dir die Beispielanwendungen im `packages/samples` Verzeichnis an.\n- Experimentiere mit eigenen Themes, um KoliBri in dein Design-System zu integrieren.\n\nViel Erfolg beim Einstieg in die Welt von KoliBri!\n",
92
92
  "kind": "doc"
93
93
  },
94
+ {
95
+ "id": "doc/HOWTO_REGISTER_COMPONENTS_AND_THEMES",
96
+ "group": "docs",
97
+ "name": "HOWTO_REGISTER_COMPONENTS_AND_THEMES",
98
+ "path": "docs/HOWTO_REGISTER_COMPONENTS_AND_THEMES.md",
99
+ "absolutePath": "/home/runner/work/kolibri/kolibri/docs/HOWTO_REGISTER_COMPONENTS_AND_THEMES.md",
100
+ "code": "# Registering KoliBri Components and Themes\n\nKoliBri Web Components ship without side effects so that you can decide _when_ and _how_ to load them.\nEvery runtimeβ€”vanilla JavaScript, React, Angular, Vue, etc.β€”must explicitly register the component set **and** at least one theme before rendering any `<kol-*>` tag. The Model Context Protocol (MCP) server exposes this guide under the concept identifier `docs/HOWTO_REGISTER_COMPONENTS_AND_THEMES` so KI agents can retrieve the exact steps.\n\n## 1. Install the packages you need\n\nInstall the component bundle plus the theme (or themes) you want to offer to your users:\n\n```bash\npnpm add @public-ui/components @public-ui/theme-default\n```\n\n> ℹ️ Replace `@public-ui/theme-default` with another theme package (e.g. `@public-ui/theme-ecl`) if you prefer a different look.\n\n## 2. Call `register` during application bootstrap\n\n```ts\nimport { register } from '@public-ui/components';\nimport { defineCustomElements } from '@public-ui/components/dist/loader';\nimport { DEFAULT } from '@public-ui/theme-default';\n\nawait register(DEFAULT, defineCustomElements);\n```\n\n- `register` wires up the custom elements and installs the provided theme(s).\n- `defineCustomElements` is generated by Stencil and registers the underlying HTML custom elements. Pass an empty array (`[]`) if your framework adapter handles element definition for you.\n- Awaiting the promise ensures the registry is ready before you render components.\n\n## 3. Register multiple themes (optional)\n\nYou can pass an array when you want to ship several themes at once:\n\n```ts\nimport { register } from '@public-ui/components';\nimport { defineCustomElements } from '@public-ui/components/dist/loader';\nimport { DEFAULT } from '@public-ui/theme-default';\nimport { ECL } from '@public-ui/theme-ecl';\n\nawait register([DEFAULT, ECL], defineCustomElements);\n```\n\nSwitching themes at runtime works through the `kol-theme` attributeβ€”no additional registration call is required.\n\n## 4. Framework-specific notes\n\n- **React / Solid / Vue**: Use the official adapters (`@public-ui/react`, `@public-ui/solid`, `@public-ui/vue`). They wrap `register` for you, but you still need to call it once in your app entry point before rendering.\n- **Angular**: Install `@public-ui/angular` and follow the schematic. It invokes `register` during the Angular bootstrapping phase.\n- **Static HTML / plain JS**: Load the ESM bundles from a CDN and call `register` with `defineCustomElements` inside a `<script type=\"module\">` block.\n\n## 5. Troubleshooting\n\n- **`<kol-button>` renders as plain text** \\\n Components were not registered. Call `register(...)` before rendering or ensure the promise resolved.\n- **Components use fallback styling** \\\n No theme was registered. Pass a theme object (e.g. `DEFAULT`) to `register`.\n- **Duplicate custom element definition error** \\\n `defineCustomElements` executed twice. Call `register` only once per page load or pass `[]` when an adapter already defines the elements.\n\n## 6. Quick reference for KI agents\n\n1. Install `@public-ui/components` + at least one theme package.\n2. Import `register` from `@public-ui/components`.\n3. Import `defineCustomElements` unless your integration takes care of it.\n4. Pass a theme (or an array of themes) and the element loader to `register`.\n5. Await the promise before rendering `<kol-*>` components.\n\nKeep this checklist handy; the MCP endpoint will always return the latest version of this guide.\n",
101
+ "kind": "doc"
102
+ },
103
+ {
104
+ "id": "doc/KNOWN_ISSUES",
105
+ "group": "docs",
106
+ "name": "KNOWN_ISSUES",
107
+ "path": "KNOWN_ISSUES.md",
108
+ "absolutePath": "/home/runner/work/kolibri/kolibri/KNOWN_ISSUES.md",
109
+ "code": "# Known Issues\n\n## General\n\n### Limited support for `aria-description` (WAI-ARIA 1.2)\n\n- `aria-description` was introduced with [WAI-ARIA 1.2](https://www.w3.org/TR/wai-aria-1.2/#aria-description), but many assistive technologies have not yet adopted it and continue to rely solely on `aria-describedby` when presenting supplementary text. Components that accept `_ariaDescription` therefore keep rendering hidden fallback markup and set both attributes so older screen readers still expose the description.\n\n## select\n\n### All text inputs\n\nIn Chrome on Windows, clicking outside an HTML input but inside a Web Component does not give focus to the input when it is empty. This issue sometimes does not occur if the input already contains a value. We suspect a focus propagation problem related to Web Component behavior.\n\n[🐞 GitHub issue #7713](https://github.com/public-ui/kolibri/issues/7713)\n\n### NVDA spells out certain words instead of reading them\n\nIt has been observed that on a system with German locale, NVDA spells out certain English words such as \"selection\", instead of reading them properly.\n\n[🐞 GitHub issue #6898](https://github.com/public-ui/kolibri/issues/6898),\n[Stack Overflow](https://stackoverflow.com/questions/69091167/nvda-spells-words-where-it-shouldnt)\n\n### Text selection in Firefox\n\nIn Firefox, text selection when using Web Components does not work as expected. Highlighting and selecting text behaves inconsistently or fails.\n\n[🐞 GitHub issue #7761](https://github.com/public-ui/kolibri/issues/7761),\n[Mozilla Bug #1587724](https://bugzilla.mozilla.org/show_bug.cgi?id=1587724),\n[Mozilla Bug #1233594](https://bugzilla.mozilla.org/show_bug.cgi?id=1233594),\n[Mozilla Bug #1590379](https://bugzilla.mozilla.org/show_bug.cgi?id=1590379)\n\n## Components\n\n### kol-select\n\n- Disabled options in KolSelect affect the total count in some screen readers. When an option is set to `disabled: true`, it may still be included in the overall option count announced by assistive technology. Using `aria-hidden=\"true\"` on `<option>` is not conforming with WAI-ARIA and causes browser warnings, therefore it has been removed. As a result, screen readers might announce a higher number of available options than can actually be selected.\n\n[🐞 GitHub issue #7453](https://github.com/public-ui/kolibri/pull/7453)\n[🐞 GitHub issue #7920](https://github.com/public-ui/kolibri/pull/7920)\n\n### kol-input-color\n\nThe component InputColor is a wrapper for the native HTML element `<input type=\"color\">` which has accessibility problems:\n\n- With NVDA, the element is announced as \"clickable\" and not as an input element.\n- It's not possible to select a color using a screen reader.\n- **9.1.3.1h Labeling of form elements programmatically detectable:**\n The label is not announced by the screen reader. Since it reads linearly, no label is perceivable when `hideLabel` is used.\n- **9.1.3.2 Meaningful sequence:**\n When opening the color selection for \"Color with error,\" there is no output. It is not accessible via the Tab key, only with the arrow keys, making it very confusing for screen reader users.\n- **9.2.4.3 Logical keyboard navigation order:**\n The focus order for \"Color with error\" is very unusual. Users do not realize that they have to use arrow keys to enter. This is especially problematic since it is not visible on black.\n- **9.2.4.7 Clearly visible focus position:**\n The focus is not visible on the black color icon in \"Color with error.\"\n\nFor full accessibility, consider using predefined colors lists, e.g. using KolSelect or KolCheckbox.\n\n[🐞 GitHub issue #5549](https://github.com/public-ui/kolibri/issues/5549),\n[🐞 GitHub issue #7455](https://github.com/public-ui/kolibri/pull/7455)\n\n### kol-table-stateful and kol-table-stateless\n\n#### `aria-sort` changes sometimes not announced in NVDA\n\nWhen a table column changes its sort order (i.e. when its `aria-sort` attribute changes), screen readers announce this change automatically. For unknown reasons, this sometimes does not happen in NVDA.\n\n[🐞 GitHub issue (PR) #5780](https://github.com/public-ui/kolibri/pull/5780),\n[🐞 NVDA issue #10890](https://github.com/nvaccess/nvda/issues/10890),\n[🐞 NVDA issue #8132](https://github.com/nvaccess/nvda/issues/8132)\n\n#### Sticky headers\n\nSticky headers in tables are not supported at the moment, because `position: sticky` doesn't work together with `overflow: auto` on the table container, without introducing other drawbacks.\n\n[🐞 GitHub issue #7490](https://github.com/public-ui/kolibri/issues/7490),\n[CSSWG Drafts issue](https://github.com/w3c/csswg-drafts/issues/865),\n[Code sample (StackBlitz)](https://stackblitz.com/edit/stackblitz-starters-umfg2y7m)\n\n### kol-input-number and kol-input-date\n\n#### `readonly` not announced in NVDA\n\nThe components InputNumber and InputDate render their respective native HTML elements `<input type=\"number\">` and `<input type=\"date\">` which both support the attribute `readonly`. When focusing the element, it's expected that the `readonly` attribute is announced as part of the element description. This isn't the case for NVDA.\n\n[🐞 GitHub issue #5554](https://github.com/public-ui/kolibri/issues/5554) (For number),\n[🐞 GitHub issue #5749](https://github.com/public-ui/kolibri/issues/5749) (For date),\n[🐞 NVDA issue #13672](https://github.com/nvaccess/nvda/issues/13672)\n\n### kol-input-date\n\n#### VoiceOver reads date inputs with percentage in Google Chrome\n\nIn Google Chrome, when using VoiceOver with empty `date` input fields (no initial value), an unexpected percentage value is read aloud alongside the usual prompt.\n\nNotably, this issue does not occur with Windows Narrator, which handles empty date inputs correctly.\n\nThere is a bug report for this issue:\n\n[VoiceOver reads negative percent values for month, day, and year steppers in `<input type=\"date\">`](https://issuetracker.google.com/issues/361250561?pli=1)\n\n### kol-input-text\n\nThe `search` of this component is highly browser-dependent. For example, the close button is either shown or hidden depending on the browser. Accessibility is therefore not achieved.\n\n[🐞 GitHub issue #6307](https://github.com/public-ui/kolibri/issues/6307)\n\n### kol-select\n\n#### Screen reader only reads last selected option\n\nKolSelect is using native HTML `<select>`.\n\nWhen using KolSelect with the `multiple` property, the native HTML `<select>` may cause problems with screen readers. Often the entire selection is not read out, but only the last one. Therefore, the KolSelect has no full accessibility.\n\n#### Limited styling capabilities for `<select>` and `<option>` elements\n\n[Stackblitz example](https://stackblitz.com/edit/vitejs-vite-nthnce?file=src%2Fstyle.css)\n\nThe `<select>` element and its `<option>` tags offer limited styling options. Specifically, states such as \"selected\", \"focus\" or \"active\" cannot be reliably customized using CSS. This leads to challenges in meeting accessibility standards, especially in ensuring sufficient contrast ratios.\n\n**Impact**:\n\n- **Limited customization**: The visual state of dropdown options (e.g., on focus or selection) cannot be consistently customized across all browsers. This makes it difficult to create an accessible visual experience for all users.\n- **Browser-dependent rendering**: The appearance of the `<select>` element varies across browsers and operating systems, resulting in inconsistent user experiences.\n- **Contrast issues**: Since the contrast of the default dropdown rendering is controlled by the browser, it's not always possible to ensure WCAG-compliant contrast ratios, which may hinder readability for users with visual impairments.\n\n### kol-icon\n\n#### Firefox accessibility issue with `aria-label`\n\nThe use of `aria-label` or `aria-labelledby` on `<kol-icon>` or its nested elements does not work reliably in Firefox. Even applying these attributes directly to `<kol-icon>` has no effect, which points to a browser-specific issue with ARIA support in custom elements or shadow DOM contexts.\n\n##### Key points\n\n- The issue lies in Firefox's handling of ARIA attributes on custom web components or deeply nested elements.\n- This is not related to dynamic announcements (`aria-live`) but specifically to the inability of Firefox to process `aria-label` or `aria-labelledby` correctly in these cases.\n- The issue is browser-specific and does not consistently occur in Chrome, Edge, or Safari.\n\n##### Conclusion\n\nThis is a limitation in Firefox’s ARIA implementation. Until it is resolved, alternative strategies like visually hidden text near the element or redundant error messages should be used to ensure accessibility.\n\n[🐞 GitHub issue #7076](https://github.com/public-ui/kolibri/issues/7076),\n[🐞 GitHub issue #7119](https://github.com/public-ui/kolibri/issues/7119)\n\n### Toaster\n\nToasts are rendered in a container that's appended as first element of `<body>` and elevated using a high `z-index`.\n\nWhen using [modal dialogs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) these are rendered above toasts on the [top layer](https://developer.mozilla.org/en-US/docs/Glossary/Top_layer). Hence, toast messages are always blocked by modal dialogs. We recommend completely avoiding toasts in modals and giving feedback within the modal directly.\n",
110
+ "kind": "doc"
111
+ },
94
112
  {
95
113
  "id": "doc/MIGRATION",
96
114
  "group": "docs",
@@ -286,7 +304,7 @@ export const samplesData = {
286
304
  "name": "icons",
287
305
  "path": "packages/samples/react/src/components/button-link/icons.tsx",
288
306
  "absolutePath": "/home/runner/work/kolibri/kolibri/packages/samples/react/src/components/button-link/icons.tsx",
289
- "code": "import React from 'react';\n\nimport { KolButtonLink } from '@public-ui/react-v19';\n\nimport type { FC } from 'react';\nimport { SampleDescription } from '../SampleDescription';\n\nexport const ButtonLinkIcons: FC = () => (\n\t<>\n\t\t<SampleDescription>\n\t\t\t<p>This sample shows KolButtonLink with icons in different locations.</p>\n\t\t</SampleDescription>\n\n\t\t<div className=\"grid gap-4\">\n\t\t\t<KolButtonLink _icons=\"codicon codicon-home\" _label=\"Ich bin ein Link mit Icon links\" />\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\tright: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with an icon on the right\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\ttop: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with an icon at the top\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\tbottom: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with icon below\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\ttop: 'codicon codicon-home',\n\t\t\t\t\tright: 'codicon codicon-home',\n\t\t\t\t\tbottom: 'codicon codicon-home',\n\t\t\t\t\tleft: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with all icons\"\n\t\t\t/>\n\t\t</div>\n\t</>\n);\n",
307
+ "code": "import React from 'react';\n\nimport { KolButtonLink } from '@public-ui/react-v19';\n\nimport type { FC } from 'react';\nimport { SampleDescription } from '../SampleDescription';\n\nexport const ButtonLinkIcons: FC = () => (\n\t<>\n\t\t<SampleDescription>\n\t\t\t<p>This sample shows KolButtonLink with icons in different locations.</p>\n\t\t</SampleDescription>\n\n\t\t<div className=\"grid gap-4\">\n\t\t\t<KolButtonLink _icons=\"codicon codicon-home\" _label=\"I am a link with an icon on the left\" />\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\tright: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with an icon on the right\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\ttop: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with an icon at the top\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\tbottom: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with icon below\"\n\t\t\t/>\n\t\t\t<KolButtonLink\n\t\t\t\t_icons={{\n\t\t\t\t\ttop: 'codicon codicon-home',\n\t\t\t\t\tright: 'codicon codicon-home',\n\t\t\t\t\tbottom: 'codicon codicon-home',\n\t\t\t\t\tleft: 'codicon codicon-home',\n\t\t\t\t}}\n\t\t\t\t_label=\"I am a link with all icons\"\n\t\t\t/>\n\t\t\t<KolButtonLink _icons=\"codicon codicon-home\" _hideLabel _label=\"I am a link with icon only\" />\n\t\t</div>\n\t</>\n);\n",
290
308
  "kind": "sample"
291
309
  },
292
310
  {
@@ -763,7 +781,7 @@ export const samplesData = {
763
781
  "name": "basic",
764
782
  "path": "packages/samples/react/src/components/link/basic.tsx",
765
783
  "absolutePath": "/home/runner/work/kolibri/kolibri/packages/samples/react/src/components/link/basic.tsx",
766
- "code": "import type { FC } from 'react';\nimport React from 'react';\n\nimport { KolLink, KolHeading } from '@public-ui/react-v19';\nimport { SampleDescription } from '../SampleDescription';\n\nexport const LinkBasic: FC = () => (\n\t<>\n\t\t<SampleDescription>\n\t\t\t<p>\n\t\t\t\tKolLink renders a link. This sample shows disabled links, links with hidden label and links with different CSS <code>display</code>-properties.\n\t\t\t</p>\n\t\t</SampleDescription>\n\n\t\t<div className=\"grid gap-4\">\n\t\t\t<KolHeading _level={2} _label=\"Links with variant 'standalone'\" />\n\t\t\t<KolLink _href=\"#/back-page\" _label=\"Simple Link\" _variant=\"standalone\" />\n\t\t\t<KolLink _disabled _href=\"#/back-page\" _label=\"Simple Link (deaktiviert)\" _variant=\"standalone\" />\n\t\t\t<KolLink _hideLabel _icons=\"codicon codicon-home\" _href=\"#/back-page\" _label=\"Icon Link\" _variant=\"standalone\" />\n\t\t\t<KolLink _disabled _hideLabel _icons=\"codicon codicon-home\" _href=\"#/back-page\" _label=\"Icon Link (deaktiviert)\" _variant=\"standalone\" />\n\n\t\t\t<KolHeading _level={2} _label=\"Links with variant 'inline'\" />\n\t\t\t<p>\n\t\t\t\tIn this paragraph, a link is inserted that contains no additional attributes. <KolLink _href=\"#/back-page\" _label=\"Simple Link\" /> It is rendered by\n\t\t\t\tdefault as a <strong>inline element</strong>.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tIn this paragraph, a link is inserted that is rendered as an inline-block element.{' '}\n\t\t\t\t<KolLink class=\"d-inline-block\" _accessKey=\"S\" _href=\"#/back-page\" _label=\"Simple Link\" />. This allows you to assign width, height, and other\n\t\t\t\tproperties to it using CSS styles.\n\t\t\t\t<br />\n\t\t\t\t<br />\n\t\t\t\tAfter that, there is a link that is rendered as a block element. <KolLink class=\"d-block\" _href=\"#/back-page\" _label=\"Simple Link\" />, therefore, I span\n\t\t\t\tthe entire width of the parent element, causing a line break.\n\t\t\t</p>\n\t\t</div>\n\t</>\n);\n",
784
+ "code": "import type { FC } from 'react';\nimport React from 'react';\n\nimport { KolLink } from '@public-ui/react-v19';\nimport { SampleDescription } from '../SampleDescription';\n\nexport const LinkBasic: FC = () => (\n\t<>\n\t\t<SampleDescription>\n\t\t\t<p>\n\t\t\t\tKolLink renders a link. This sample shows disabled links, links with hidden label and links with different CSS <code>display</code>-properties.\n\t\t\t</p>\n\t\t</SampleDescription>\n\n\t\t<div className=\"grid gap-4\">\n\t\t\t<KolLink _href=\"#/back-page\" _label=\"Simple Link\" _variant=\"standalone\" />\n\t\t\t<KolLink _disabled _href=\"#/back-page\" _label=\"Simple Link (disabled)\" _variant=\"standalone\" />\n\t\t\t<KolLink _hideLabel _icons=\"codicon codicon-home\" _href=\"#/back-page\" _label=\"Icon Link\" _variant=\"standalone\" />\n\t\t\t<KolLink _disabled _hideLabel _icons=\"codicon codicon-home\" _href=\"#/back-page\" _label=\"Icon Link (disabled)\" _variant=\"standalone\" />\n\t\t\t<p>\n\t\t\t\tIn this paragraph, a link is inserted that contains no additional attributes. <KolLink _href=\"#/back-page\" _label=\"Simple Link\" /> It is rendered by\n\t\t\t\tdefault as a <strong>inline element</strong>.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tIn this paragraph, a link is inserted that is rendered as an inline-block element.{' '}\n\t\t\t\t<KolLink class=\"d-inline-block\" _accessKey=\"S\" _href=\"#/back-page\" _label=\"Simple Link\" />. This allows you to assign width, height, and other\n\t\t\t\tproperties to it using CSS styles.\n\t\t\t\t<br />\n\t\t\t\t<br />\n\t\t\t\tAfter that, there is a link that is rendered as a block element. <KolLink class=\"d-block\" _href=\"#/back-page\" _label=\"Simple Link\" />, therefore, I span\n\t\t\t\tthe entire width of the parent element, causing a line break.\n\t\t\t</p>\n\t\t</div>\n\t</>\n);\n",
767
785
  "kind": "sample"
768
786
  },
769
787
  {
@@ -1204,7 +1222,7 @@ export const samplesData = {
1204
1222
  "name": "stateless-with-selection",
1205
1223
  "path": "packages/samples/react/src/components/table/stateless-with-selection.tsx",
1206
1224
  "absolutePath": "/home/runner/work/kolibri/kolibri/packages/samples/react/src/components/table/stateless-with-selection.tsx",
1207
- "code": "import type { FC } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { createReactRenderElement, KolButton, KolTableStateless } from '@public-ui/react-v19';\nimport { SampleDescription } from '../SampleDescription';\nimport type { KoliBriTableCell, KoliBriTableSelection } from '@public-ui/components';\nimport { KolEvent } from '@public-ui/components';\nimport { getRoot } from '../../shares/react-roots';\nimport { useToasterService } from '../../hooks/useToasterService';\n\nconst DATA = [\n\t{ id: '1001', name: 'Foo Bar', internalIdentifier: `AAA1001` },\n\t{ id: '1002', name: 'Foo Baz', internalIdentifier: `AAA1002` },\n\t{ id: '1003', name: 'This row is always unchecked', internalIdentifier: `AAA1003` },\n\t{ id: '1004', name: 'This row is always checked', internalIdentifier: `AAA1004` },\n];\ntype Data = (typeof DATA)[0];\n\nfunction KolButtonWrapper({ label }: { label: string }) {\n\tconst { dummyClickEventHandler } = useToasterService();\n\n\tconst dummyEventHandler = {\n\t\tonClick: dummyClickEventHandler,\n\t};\n\n\treturn <KolButton _label={label} _on={dummyEventHandler} />;\n}\n\nexport const TableStatelessWithSelection: FC = () => {\n\tconst [selectedKeys, setSelectedKeys] = useState(['AAA1002', 'AAA1004']);\n\n\tconst selection: KoliBriTableSelection = {\n\t\tlabel: (row) => `Selection for ${(row as Data).name}`,\n\t\tselectedKeys,\n\t\tkeyPropertyName: 'internalIdentifier',\n\t\tdisabledKeys: ['AAA1003', 'AAA1004'],\n\t};\n\n\tconst kolTableStatelessRef = useRef<HTMLKolTableStatelessElement>(null);\n\n\tconst handleSelectionChangeEvent = ({ detail: selection }: { detail: string[] }) => {\n\t\tconsole.log('Selection change via event', selection);\n\t};\n\tconst handleSelectionChangeCallback = (_event: Event, selection: string[] | string) => {\n\t\tconsole.log('Selection change via callback', selection);\n\t\tsetSelectedKeys(typeof selection === 'string' ? [selection] : selection);\n\t};\n\n\tuseEffect(() => {\n\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\tkolTableStatelessRef.current?.addEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\n\t\treturn () => {\n\t\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\t\tkolTableStatelessRef.current?.removeEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\t\t};\n\t}, [kolTableStatelessRef]);\n\n\tconst renderButton = (element: HTMLElement, cell: KoliBriTableCell) => {\n\t\tgetRoot(createReactRenderElement(element)).render(<KolButtonWrapper label={`Click ${cell.data?.id}`} />);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This sample shows KolTableStateless with checkboxes for selection enabled.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<section className=\"w-full\">\n\t\t\t\t<KolTableStateless\n\t\t\t\t\t_label=\"Table with selection checkboxes\"\n\t\t\t\t\t_minWidth=\"auto\"\n\t\t\t\t\t_headerCells={{\n\t\t\t\t\t\thorizontal: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t{ key: 'id', label: '#ID', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'name', label: 'Name', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'action', label: 'Action', textAlign: 'left', render: renderButton },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t\t_data={DATA}\n\t\t\t\t\t_selection={selection}\n\t\t\t\t\t_on={{ onSelectionChange: handleSelectionChangeCallback }}\n\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\tstyle={{ maxWidth: '600px' }}\n\t\t\t\t\tref={kolTableStatelessRef}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</>\n\t);\n};\n",
1225
+ "code": "import type { KoliBriTableCell, KoliBriTableSelection, KoliBriTableSelectionKeys } from '@public-ui/components';\nimport { KolEvent } from '@public-ui/components';\nimport { createReactRenderElement, KolButton, KolTableStateless } from '@public-ui/react-v19';\nimport type { FC } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useToasterService } from '../../hooks/useToasterService';\nimport { getRoot } from '../../shares/react-roots';\nimport { SampleDescription } from '../SampleDescription';\n\ntype SelectionValue = string | number;\n\nconst DATA = [\n\t{ id: '1001', name: 'Foo Bar', internalIdentifier: `AAA1001` },\n\t{ id: '1002', name: 'Foo Baz', internalIdentifier: `AAA1002` },\n\t{ id: '1003', name: 'This row is always unchecked', internalIdentifier: `AAA1003` },\n\t{ id: '1004', name: 'This row is always checked', internalIdentifier: `AAA1004` },\n];\ntype Data = (typeof DATA)[0];\n\nfunction KolButtonWrapper({ label }: { label: string }) {\n\tconst { dummyClickEventHandler } = useToasterService();\n\n\tconst dummyEventHandler = {\n\t\tonClick: dummyClickEventHandler,\n\t};\n\n\treturn <KolButton _label={label} _on={dummyEventHandler} />;\n}\n\nexport const TableStatelessWithSelection: FC = () => {\n\tconst [selectedKeys, setSelectedKeys] = useState<KoliBriTableSelectionKeys>(['AAA1002', 'AAA1004']);\n\n\tconst selection: KoliBriTableSelection = {\n\t\tlabel: (row) => `Selection for ${(row as Data).name}`,\n\t\tselectedKeys,\n\t\tkeyPropertyName: 'internalIdentifier',\n\t\tdisabledKeys: ['AAA1003', 'AAA1004'],\n\t};\n\n\tconst kolTableStatelessRef = useRef<HTMLKolTableStatelessElement>(null);\n\n\tconst handleSelectionChangeEvent = ({ detail: selection }: { detail: string[] }) => {\n\t\tconsole.log('Selection change via event', selection);\n\t};\n\tconst handleSelectionChangeCallback = (_event: Event, selection: SelectionValue[] | SelectionValue) => {\n\t\tconsole.log('Selection change via callback', selection);\n\t\tsetSelectedKeys(Array.isArray(selection) ? selection : [selection]);\n\t};\n\n\tuseEffect(() => {\n\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\tkolTableStatelessRef.current?.addEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\n\t\treturn () => {\n\t\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\t\tkolTableStatelessRef.current?.removeEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\t\t};\n\t}, [kolTableStatelessRef]);\n\n\tconst renderButton = (element: HTMLElement, cell: KoliBriTableCell) => {\n\t\tgetRoot(createReactRenderElement(element)).render(<KolButtonWrapper label={`Click ${cell.data?.id}`} />);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This sample shows KolTableStateless with checkboxes for selection enabled.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<section className=\"w-full\">\n\t\t\t\t<KolTableStateless\n\t\t\t\t\t_label=\"Table with selection checkboxes\"\n\t\t\t\t\t_minWidth=\"auto\"\n\t\t\t\t\t_headerCells={{\n\t\t\t\t\t\thorizontal: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t{ key: 'id', label: '#ID', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'name', label: 'Name', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'action', label: 'Action', textAlign: 'left', render: renderButton },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t\t_data={DATA}\n\t\t\t\t\t_selection={selection}\n\t\t\t\t\t_on={{ onSelectionChange: handleSelectionChangeCallback }}\n\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\tstyle={{ maxWidth: '600px' }}\n\t\t\t\t\tref={kolTableStatelessRef}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</>\n\t);\n};\n",
1208
1226
  "kind": "sample"
1209
1227
  },
1210
1228
  {
@@ -1222,7 +1240,7 @@ export const samplesData = {
1222
1240
  "name": "stateless-with-single-selection",
1223
1241
  "path": "packages/samples/react/src/components/table/stateless-with-single-selection.tsx",
1224
1242
  "absolutePath": "/home/runner/work/kolibri/kolibri/packages/samples/react/src/components/table/stateless-with-single-selection.tsx",
1225
- "code": "import type { FC } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { createReactRenderElement, KolButton, KolTableStateless } from '@public-ui/react-v19';\nimport { SampleDescription } from '../SampleDescription';\nimport type { KoliBriTableCell, KoliBriTableSelection } from '@public-ui/components';\nimport { KolEvent } from '@public-ui/components';\nimport { getRoot } from '../../shares/react-roots';\nimport { useToasterService } from '../../hooks/useToasterService';\n\nconst DATA = [\n\t{ id: '1001', name: 'Foo Bar', internalIdentifier: `AAA1001` },\n\t{ id: '1002', name: 'Foo Baz', internalIdentifier: `AAA1002` },\n\t{ id: '1003', name: 'Foo Disabled', internalIdentifier: `AAA1003` },\n];\ntype Data = (typeof DATA)[0];\n\nfunction KolButtonWrapper({ label }: { label: string }) {\n\tconst { dummyClickEventHandler } = useToasterService();\n\n\tconst dummyEventHandler = {\n\t\tonClick: dummyClickEventHandler,\n\t};\n\n\treturn <KolButton _label={label} _on={dummyEventHandler} />;\n}\n\nexport const TableStatelessWithSingleSelection: FC = () => {\n\tconst [selectedKeys, setSelectedKeys] = useState(['1002']);\n\n\tconst selection: KoliBriTableSelection = {\n\t\tlabel: (row) => `Selection for ${(row as Data).name}`,\n\t\tmultiple: false,\n\t\tselectedKeys,\n\t\tdisabledKeys: ['AAA1003'],\n\t\tkeyPropertyName: 'internalIdentifier',\n\t};\n\n\tconst kolTableStatelessRef = useRef<HTMLKolTableStatelessElement>(null);\n\n\tconst handleSelectionChangeEvent = ({ detail: selection }: { detail: string[] }) => {\n\t\tconsole.log('Selection change via event', selection);\n\t};\n\tconst handleSelectionChangeCallback = (_event: Event, selection: string[] | string) => {\n\t\tconsole.log('Selection change via callback', selection);\n\t\tsetSelectedKeys(typeof selection === 'string' ? [selection] : selection);\n\t};\n\n\tuseEffect(() => {\n\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\tkolTableStatelessRef.current?.addEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\n\t\treturn () => {\n\t\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\t\tkolTableStatelessRef.current?.removeEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\t\t};\n\t}, [kolTableStatelessRef]);\n\n\tconst renderButton = (element: HTMLElement, cell: KoliBriTableCell) => {\n\t\tgetRoot(createReactRenderElement(element)).render(<KolButtonWrapper label={`Click ${cell.data?.id}`} />);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This sample shows KolTableStateless with checkboxes for selection enabled.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<section className=\"w-full\">\n\t\t\t\t<KolTableStateless\n\t\t\t\t\t_label=\"Table with selection checkboxes\"\n\t\t\t\t\t_minWidth=\"auto\"\n\t\t\t\t\t_headerCells={{\n\t\t\t\t\t\thorizontal: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t{ key: 'id', label: '#ID', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'name', label: 'Name', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'action', label: 'Action', textAlign: 'left', render: renderButton },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t\t_data={DATA}\n\t\t\t\t\t_selection={selection}\n\t\t\t\t\t_on={{ onSelectionChange: handleSelectionChangeCallback }}\n\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\tstyle={{ maxWidth: '600px' }}\n\t\t\t\t\tref={kolTableStatelessRef}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</>\n\t);\n};\n",
1243
+ "code": "import type { KoliBriTableCell, KoliBriTableSelection, KoliBriTableSelectionKeys } from '@public-ui/components';\nimport { KolEvent } from '@public-ui/components';\nimport { createReactRenderElement, KolButton, KolTableStateless } from '@public-ui/react-v19';\nimport type { FC } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { useToasterService } from '../../hooks/useToasterService';\nimport { getRoot } from '../../shares/react-roots';\nimport { SampleDescription } from '../SampleDescription';\n\ntype SelectionValue = string | number;\n\nconst DATA = [\n\t{ id: '1001', name: 'Foo Bar', internalIdentifier: `AAA1001` },\n\t{ id: '1002', name: 'Foo Baz', internalIdentifier: `AAA1002` },\n\t{ id: '1003', name: 'Foo Disabled', internalIdentifier: `AAA1003` },\n];\ntype Data = (typeof DATA)[0];\n\nfunction KolButtonWrapper({ label }: { label: string }) {\n\tconst { dummyClickEventHandler } = useToasterService();\n\n\tconst dummyEventHandler = {\n\t\tonClick: dummyClickEventHandler,\n\t};\n\n\treturn <KolButton _label={label} _on={dummyEventHandler} />;\n}\n\nexport const TableStatelessWithSingleSelection: FC = () => {\n\tconst [selectedKeys, setSelectedKeys] = useState<KoliBriTableSelectionKeys>(['1002']);\n\n\tconst selection: KoliBriTableSelection = {\n\t\tlabel: (row) => `Selection for ${(row as Data).name}`,\n\t\tmultiple: false,\n\t\tselectedKeys,\n\t\tdisabledKeys: ['AAA1003'],\n\t\tkeyPropertyName: 'internalIdentifier',\n\t};\n\n\tconst kolTableStatelessRef = useRef<HTMLKolTableStatelessElement>(null);\n\n\tconst handleSelectionChangeEvent = ({ detail: selection }: { detail: string[] }) => {\n\t\tconsole.log('Selection change via event', selection);\n\t};\n\tconst handleSelectionChangeCallback = (_event: Event, selection: SelectionValue[] | SelectionValue) => {\n\t\tconsole.log('Selection change via callback', selection);\n\t\tsetSelectedKeys(Array.isArray(selection) ? selection : [selection]);\n\t};\n\n\tuseEffect(() => {\n\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\tkolTableStatelessRef.current?.addEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\n\t\treturn () => {\n\t\t\t// @ts-expect-error https://github.com/Microsoft/TypeScript/issues/28357\n\t\t\tkolTableStatelessRef.current?.removeEventListener(KolEvent.selectionChange, handleSelectionChangeEvent);\n\t\t};\n\t}, [kolTableStatelessRef]);\n\n\tconst renderButton = (element: HTMLElement, cell: KoliBriTableCell) => {\n\t\tgetRoot(createReactRenderElement(element)).render(<KolButtonWrapper label={`Click ${cell.data?.id}`} />);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This sample shows KolTableStateless with checkboxes for selection enabled.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<section className=\"w-full\">\n\t\t\t\t<KolTableStateless\n\t\t\t\t\t_label=\"Table with selection checkboxes\"\n\t\t\t\t\t_minWidth=\"auto\"\n\t\t\t\t\t_headerCells={{\n\t\t\t\t\t\thorizontal: [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t{ key: 'id', label: '#ID', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'name', label: 'Name', textAlign: 'left' },\n\t\t\t\t\t\t\t\t{ key: 'action', label: 'Action', textAlign: 'left', render: renderButton },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t\t_data={DATA}\n\t\t\t\t\t_selection={selection}\n\t\t\t\t\t_on={{ onSelectionChange: handleSelectionChangeCallback }}\n\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\tstyle={{ maxWidth: '600px' }}\n\t\t\t\t\tref={kolTableStatelessRef}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</>\n\t);\n};\n",
1226
1244
  "kind": "sample"
1227
1245
  },
1228
1246
  {
@@ -1406,7 +1424,7 @@ export const samplesData = {
1406
1424
  "kind": "sample"
1407
1425
  }
1408
1426
  ],
1409
- "generatedAt": "2025-10-11T04:24:23.973Z",
1427
+ "generatedAt": "2025-10-12T03:00:19.944Z",
1410
1428
  "buildMode": "prebuild"
1411
1429
  };
1412
1430
  export default samplesData;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@public-ui/mcp",
3
- "version": "3.0.7-rc.3",
3
+ "version": "4.0.0-alpha.2",
4
4
  "license": "EUPL-1.2",
5
5
  "homepage": "https://public-ui.github.io",
6
6
  "repository": {
@@ -50,7 +50,7 @@
50
50
  ],
51
51
  "scripts": {
52
52
  "build": "node prebuild.js && unbuild",
53
- "format": "prettier --check src",
53
+ "format": "prettier --check public src",
54
54
  "prestart": "pnpm build",
55
55
  "start": "node dist/index.mjs"
56
56
  }