@public-ui/mcp 4.1.1-rc.2 → 4.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@public-ui/mcp",
3
- "version": "4.1.1-rc.2",
3
+ "version": "4.1.1",
4
4
  "license": "EUPL-1.2",
5
5
  "homepage": "https://public-ui.github.io",
6
6
  "repository": {
@@ -46,16 +46,16 @@
46
46
  "express": "5.2.1",
47
47
  "fuse.js": "7.1.0",
48
48
  "zod": "4.3.6",
49
- "@public-ui/components": "4.1.1-rc.2"
49
+ "@public-ui/components": "4.1.1"
50
50
  },
51
51
  "devDependencies": {
52
- "@eslint/js": "9.39.3",
52
+ "@eslint/js": "9.39.4",
53
53
  "@modelcontextprotocol/inspector": "0.21.1",
54
54
  "@types/express": "5.0.6",
55
55
  "@types/node": "25.3.5",
56
56
  "@typescript-eslint/eslint-plugin": "8.56.1",
57
57
  "@typescript-eslint/parser": "8.56.1",
58
- "eslint": "9.39.3",
58
+ "eslint": "9.39.4",
59
59
  "eslint-plugin-json": "4.0.1",
60
60
  "globals": "17.4.0",
61
61
  "knip": "5.85.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "metadata": {
3
- "generatedAt": "2026-03-06T16:13:10.804Z",
3
+ "generatedAt": "2026-03-09T08:31:38.848Z",
4
4
  "buildMode": "ci",
5
5
  "counts": {
6
6
  "total": 276,
@@ -10,7 +10,7 @@
10
10
  "totalScenarios": 18
11
11
  },
12
12
  "repo": {
13
- "commit": "f1671112b494d8f31caf8f707ca14c02b9cdfa45",
13
+ "commit": "3d811ac1c92cc2dc322639b18bf240059d522cf3",
14
14
  "branch": "develop",
15
15
  "repoUrl": "https://github.com/public-ui/kolibri"
16
16
  }
@@ -293,7 +293,7 @@
293
293
  "group": "docs",
294
294
  "name": "CVE_OVERVIEW",
295
295
  "path": "docs/CVE_OVERVIEW.md",
296
- "code": "# CVE Overview\n\n> For more security information, see [SECURITY.md](./SECURITY.md)\n\n## 1. Production Dependencies\n\n### Summary\n\n| Severity | v4 | v3 | v2 | v1 |\n| -------- | --: | --: | --: | --: |\n| critical | 0 | 0 | 0 | 0 |\n| high | 0 | 0 | 0 | 5 |\n| moderate | 0 | 0 | 0 | 0 |\n| low | 0 | 0 | 0 | 0 |\n| info | 0 | 0 | 0 | 0 |\n| unknown | 0 | 0 | 0 | 0 |\n\n### Vulnerabilities\n\n| Package | Severity | CVE | Affected Versions | Description |\n| -------------------- | -------- | ------------------- | ----------------- | --------------------------------------------------------------------------------- |\n| immutable | high | CVE-2026-29063 | v1 | Immutable is vulnerable to Prototype Pollution |\n| lodash.pick | high | CVE-2020-8203 | v1 | Prototype Pollution in lodash |\n| minimatch | high | CVE-2026-27903 | v1 | minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja |\n| minimatch | high | CVE-2026-27904 | v1 | minimatch ReDoS: nested \\*() extglobs generate catastrophically backtracking regu |\n| serialize-javascript | high | GHSA-5c6j-r48x-rmvq | v1 | Serialize JavaScript is Vulnerable to RCE via RegExp.flags and Date.prototype.to |\n\n## 2. All Dependencies\n\n### Summary\n\n| Severity | v4 | v3 | v2 | v1 |\n| -------- | --: | --: | --: | --: |\n| critical | 3 | 3 | 3 | 1 |\n| high | 18 | 18 | 27 | 22 |\n| moderate | 2 | 2 | 13 | 1 |\n| low | 3 | 3 | 8 | 0 |\n| info | 0 | 0 | 0 | 0 |\n| unknown | 0 | 0 | 0 | 0 |\n\n### Vulnerabilities\n\n| Package | Severity | CVE | Affected Versions | Description |\n| -------------------- | -------- | ------------------- | ----------------- | --------------------------------------------------------------------------------- |\n| basic-ftp | critical | CVE-2026-27699 | v4, v3, v2 | Basic FTP has Path Traversal Vulnerability in its downloadToDir() method |\n| fast-xml-parser | critical | CVE-2026-25896 | v4, v3, v2 | fast-xml-parser has an entity encoding bypass via regex injection in DOCTYPE ent |\n| locutus | critical | CVE-2026-25521 | v4, v3, v2, v1 | locutus is vulnerable to Prototype Pollution |\n| @angular/common | high | CVE-2025-66035 | v1 | Angular is Vulnerable to XSRF Token Leakage via Protocol-Relative URLs in Angula |\n| @angular/compiler | high | CVE-2025-66412 | v1 | Angular Stored XSS Vulnerability via SVG Animation, SVG URL and MathML Attribute |\n| @angular/compiler | high | CVE-2026-22610 | v1 | Angular has XSS Vulnerability via Unsanitized SVG Script Attributes |\n| @angular/core | high | CVE-2026-22610 | v1 | Angular has XSS Vulnerability via Unsanitized SVG Script Attributes |\n| @angular/core | high | CVE-2026-27970 | v1 | Angular i18n vulnerable to Cross-Site Scripting |\n| @hono/node-server | high | CVE-2026-29087 | v2 | @hono/node-server has authorization bypass for protected static paths via encode |\n| axios | high | CVE-2026-25639 | v3, v2 | Axios is Vulnerable to Denial of Service via **proto** Key in mergeConfig |\n| braces | high | CVE-2024-4068 | v4, v3, v2, v1 | Uncontrolled resource consumption in braces |\n| fast-xml-parser | high | CVE-2026-25128 | v4, v3, v2 | fast-xml-parser has RangeError DoS Numeric Entities Bug |\n| fast-xml-parser | high | CVE-2026-26278 | v4, v3, v2 | fast-xml-parser affected by DoS through entity expansion in DOCTYPE (no expansio |\n| hono | high | CVE-2026-29045 | v2 | Hono vulnerable to arbitrary file access via serveStatic vulnerability |\n| immutable | high | CVE-2026-29063 | v2, v1 | Immutable is vulnerable to Prototype Pollution |\n| locutus | high | CVE-2026-29091 | v4, v3, v2, v1 | locutus call_user_func_array vulnerable to Remote Code Execution (RCE) due to Co |\n| lodash.pick | high | CVE-2020-8203 | v2, v1 | Prototype Pollution in lodash |\n| minimatch | high | CVE-2026-27903 | v4, v3, v2, v1 | minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja |\n| minimatch | high | CVE-2026-27904 | v4, v3, v2, v1 | minimatch ReDoS: nested \\*() extglobs generate catastrophically backtracking regu |\n| minimatch | high | CVE-2026-26996 | v4, v3, v2 | minimatch has a ReDoS via repeated wildcards with non-matching literal in patter |\n| rollup | high | CVE-2026-27606 | v1 | Rollup 4 has Arbitrary File Write via Path Traversal |\n| semver | high | CVE-2022-25883 | v2 | semver vulnerable to Regular Expression Denial of Service |\n| serialize-javascript | high | GHSA-5c6j-r48x-rmvq | v4, v3, v2, v1 | Serialize JavaScript is Vulnerable to RCE via RegExp.flags and Date.prototype.to |\n| svgo | high | CVE-2026-29074 | v4, v3, v2, v1 | SVGO DoS through entity expansion in DOCTYPE (Billion Laughs) |\n| tar | high | CVE-2026-23950 | v1 | Race Condition in node-tar Path Reservations via Unicode Ligature Collisions on |\n| tar | high | CVE-2026-24842 | v1 | node-tar Vulnerable to Arbitrary File Creation/Overwrite via Hardlink Path Trave |\n| tar | high | CVE-2026-23745 | v1 | node-tar is Vulnerable to Arbitrary File Overwrite and Symlink Poisoning via Ins |\n| tar | high | CVE-2026-26960 | v4, v3, v1 | Arbitrary File Read/Write via Hardlink Target Escape Through Symlink Chain in no |\n| tar | high | CVE-2026-29786 | v4, v3, v2, v1 | tar has Hardlink Path Traversal via Drive-Relative Linkpath |\n| ajv | moderate | CVE-2025-69873 | v4, v3, v2 | ajv has ReDoS when using `$data` option |\n| ejs | moderate | CVE-2024-33883 | v2 | ejs lacks certain pollution protection |\n| esbuild | moderate | GHSA-67mh-4wv8-2f99 | v2 | esbuild enables any website to send any requests to the development server and r |\n| hono | moderate | CVE-2026-29086 | v2 | Hono Vulnerable to Cookie Attribute Injection via Unsanitized domain and path in |\n| hono | moderate | CVE-2026-29085 | v2 | Hono Vulnerable to SSE Control Field Injection via CR/LF in writeSSE() |\n| js-yaml | moderate | CVE-2025-64718 | v2 | js-yaml has prototype pollution in merge (<<) |\n| micromatch | moderate | CVE-2024-4067 | v4, v3, v2, v1 | Regular Expression Denial of Service (ReDoS) in micromatch |\n| nanoid | moderate | CVE-2024-55565 | v2 | Predictable results in nanoid generation when given non-integer values |\n| qs | moderate | CVE-2025-15284 | v2 | qs's arrayLimit bypass in its bracket notation allows DoS via memory exhaustion |\n| serialize-javascript | moderate | CVE-2024-11831 | v2 | Cross-site Scripting (XSS) in serialize-javascript |\n| webpack | moderate | CVE-2024-43788 | v2 | Webpack's AutoPublicPathRuntimeModule has a DOM Clobbering Gadget that leads to |\n| webpack-dev-server | moderate | CVE-2025-30360 | v2 | webpack-dev-server users' source code may be stolen when they access a malicious |\n| webpack-dev-server | moderate | CVE-2025-30359 | v2 | webpack-dev-server users' source code may be stolen when they access a malicious |\n| @tootallnate/once | low | CVE-2026-3449 | v4, v3, v2 | @tootallnate/once vulnerable to Incorrect Control Flow Scoping |\n| diff | low | CVE-2026-24001 | v4, v3, v2 | jsdiff has a Denial of Service vulnerability in parsePatch and applyPatch |\n| fast-xml-parser | low | CVE-2026-27942 | v4, v3, v2 | fast-xml-parser has stack overflow in XMLBuilder with preserveOrder |\n| hono | low | GHSA-gq3j-xvxp-8hrf | v2 | Hono added timing comparison hardening in basicAuth and bearerAuth |\n| qs | low | CVE-2026-2391 | v2 | qs's arrayLimit bypass in comma parsing allows denial of service |\n| webpack | low | CVE-2025-68458 | v2 | webpack buildHttp: allowedUris allow-list bypass via URL userinfo (@) leading to |\n| webpack | low | CVE-2025-68157 | v2 | webpack buildHttp HttpUriPlugin allowedUris bypass via HTTP redirects → SSRF + c |\n",
296
+ "code": "# CVE Overview\n\n> For more security information, see [SECURITY.md](./SECURITY.md)\n\n## 1. Production Dependencies\n\n### Summary\n\n| Severity | v4 | v3 | v2 | v1 |\n| -------- | --: | --: | --: | --: |\n| critical | 0 | 0 | 0 | 0 |\n| high | 0 | 0 | 0 | 4 |\n| moderate | 0 | 0 | 0 | 0 |\n| low | 0 | 0 | 0 | 0 |\n| info | 0 | 0 | 0 | 0 |\n| unknown | 0 | 0 | 0 | 0 |\n\n### Vulnerabilities\n\n| Package | Severity | CVE | Affected Versions | Description |\n| -------------------- | -------- | ------------------- | ----------------- | --------------------------------------------------------------------------------- |\n| lodash.pick | high | CVE-2020-8203 | v1 | Prototype Pollution in lodash |\n| minimatch | high | CVE-2026-27903 | v1 | minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja |\n| minimatch | high | CVE-2026-27904 | v1 | minimatch ReDoS: nested \\*() extglobs generate catastrophically backtracking regu |\n| serialize-javascript | high | GHSA-5c6j-r48x-rmvq | v1 | Serialize JavaScript is Vulnerable to RCE via RegExp.flags and Date.prototype.to |\n\n## 2. All Dependencies\n\n### Summary\n\n| Severity | v4 | v3 | v2 | v1 |\n| -------- | --: | --: | --: | --: |\n| critical | 3 | 3 | 3 | 1 |\n| high | 17 | 17 | 27 | 20 |\n| moderate | 1 | 2 | 13 | 1 |\n| low | 3 | 3 | 8 | 0 |\n| info | 0 | 0 | 0 | 0 |\n| unknown | 0 | 0 | 0 | 0 |\n\n### Vulnerabilities\n\n| Package | Severity | CVE | Affected Versions | Description |\n| -------------------- | -------- | ------------------- | ----------------- | --------------------------------------------------------------------------------- |\n| basic-ftp | critical | CVE-2026-27699 | v4, v3, v2 | Basic FTP has Path Traversal Vulnerability in its downloadToDir() method |\n| fast-xml-parser | critical | CVE-2026-25896 | v4, v3, v2 | fast-xml-parser has an entity encoding bypass via regex injection in DOCTYPE ent |\n| locutus | critical | CVE-2026-25521 | v4, v3, v2, v1 | locutus is vulnerable to Prototype Pollution |\n| @angular/common | high | CVE-2025-66035 | v1 | Angular is Vulnerable to XSRF Token Leakage via Protocol-Relative URLs in Angula |\n| @angular/compiler | high | CVE-2025-66412 | v1 | Angular Stored XSS Vulnerability via SVG Animation, SVG URL and MathML Attribute |\n| @angular/compiler | high | CVE-2026-22610 | v1 | Angular has XSS Vulnerability via Unsanitized SVG Script Attributes |\n| @angular/core | high | CVE-2026-22610 | v1 | Angular has XSS Vulnerability via Unsanitized SVG Script Attributes |\n| @angular/core | high | CVE-2026-27970 | v1 | Angular i18n vulnerable to Cross-Site Scripting |\n| @hono/node-server | high | CVE-2026-29087 | v2 | @hono/node-server has authorization bypass for protected static paths via encode |\n| axios | high | CVE-2026-25639 | v3, v2 | Axios is Vulnerable to Denial of Service via **proto** Key in mergeConfig |\n| braces | high | CVE-2024-4068 | v4, v3, v2, v1 | Uncontrolled resource consumption in braces |\n| express-rate-limit | high | CVE-2026-30827 | v2 | express-rate-limit: IPv4-mapped IPv6 addresses bypass per-client rate limiting o |\n| fast-xml-parser | high | CVE-2026-25128 | v4, v3, v2 | fast-xml-parser has RangeError DoS Numeric Entities Bug |\n| fast-xml-parser | high | CVE-2026-26278 | v4, v3, v2 | fast-xml-parser affected by DoS through entity expansion in DOCTYPE (no expansio |\n| hono | high | CVE-2026-29045 | v2 | Hono vulnerable to arbitrary file access via serveStatic vulnerability |\n| immutable | high | CVE-2026-29063 | v2 | Immutable is vulnerable to Prototype Pollution |\n| locutus | high | CVE-2026-29091 | v4, v3, v2, v1 | locutus call_user_func_array vulnerable to Remote Code Execution (RCE) due to Co |\n| lodash.pick | high | CVE-2020-8203 | v2, v1 | Prototype Pollution in lodash |\n| minimatch | high | CVE-2026-27903 | v4, v3, v2, v1 | minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja |\n| minimatch | high | CVE-2026-27904 | v4, v3, v2, v1 | minimatch ReDoS: nested \\*() extglobs generate catastrophically backtracking regu |\n| minimatch | high | CVE-2026-26996 | v4, v3, v2 | minimatch has a ReDoS via repeated wildcards with non-matching literal in patter |\n| rollup | high | CVE-2026-27606 | v1 | Rollup 4 has Arbitrary File Write via Path Traversal |\n| semver | high | CVE-2022-25883 | v2 | semver vulnerable to Regular Expression Denial of Service |\n| serialize-javascript | high | GHSA-5c6j-r48x-rmvq | v4, v3, v2, v1 | Serialize JavaScript is Vulnerable to RCE via RegExp.flags and Date.prototype.to |\n| svgo | high | CVE-2026-29074 | v4, v3, v2, v1 | SVGO DoS through entity expansion in DOCTYPE (Billion Laughs) |\n| tar | high | CVE-2026-23950 | v1 | Race Condition in node-tar Path Reservations via Unicode Ligature Collisions on |\n| tar | high | CVE-2026-24842 | v1 | node-tar Vulnerable to Arbitrary File Creation/Overwrite via Hardlink Path Trave |\n| tar | high | CVE-2026-23745 | v1 | node-tar is Vulnerable to Arbitrary File Overwrite and Symlink Poisoning via Ins |\n| tar | high | CVE-2026-26960 | v4, v3, v1 | Arbitrary File Read/Write via Hardlink Target Escape Through Symlink Chain in no |\n| tar | high | CVE-2026-29786 | v4, v3, v2, v1 | tar has Hardlink Path Traversal via Drive-Relative Linkpath |\n| ajv | moderate | CVE-2025-69873 | v3, v2 | ajv has ReDoS when using `$data` option |\n| ejs | moderate | CVE-2024-33883 | v2 | ejs lacks certain pollution protection |\n| esbuild | moderate | GHSA-67mh-4wv8-2f99 | v2 | esbuild enables any website to send any requests to the development server and r |\n| hono | moderate | CVE-2026-29086 | v2 | Hono Vulnerable to Cookie Attribute Injection via Unsanitized domain and path in |\n| hono | moderate | CVE-2026-29085 | v2 | Hono Vulnerable to SSE Control Field Injection via CR/LF in writeSSE() |\n| js-yaml | moderate | CVE-2025-64718 | v2 | js-yaml has prototype pollution in merge (<<) |\n| micromatch | moderate | CVE-2024-4067 | v4, v3, v2, v1 | Regular Expression Denial of Service (ReDoS) in micromatch |\n| nanoid | moderate | CVE-2024-55565 | v2 | Predictable results in nanoid generation when given non-integer values |\n| qs | moderate | CVE-2025-15284 | v2 | qs's arrayLimit bypass in its bracket notation allows DoS via memory exhaustion |\n| serialize-javascript | moderate | CVE-2024-11831 | v2 | Cross-site Scripting (XSS) in serialize-javascript |\n| webpack | moderate | CVE-2024-43788 | v2 | Webpack's AutoPublicPathRuntimeModule has a DOM Clobbering Gadget that leads to |\n| webpack-dev-server | moderate | CVE-2025-30360 | v2 | webpack-dev-server users' source code may be stolen when they access a malicious |\n| webpack-dev-server | moderate | CVE-2025-30359 | v2 | webpack-dev-server users' source code may be stolen when they access a malicious |\n| @tootallnate/once | low | CVE-2026-3449 | v4, v3, v2 | @tootallnate/once vulnerable to Incorrect Control Flow Scoping |\n| diff | low | CVE-2026-24001 | v4, v3, v2 | jsdiff has a Denial of Service vulnerability in parsePatch and applyPatch |\n| fast-xml-parser | low | CVE-2026-27942 | v4, v3, v2 | fast-xml-parser has stack overflow in XMLBuilder with preserveOrder |\n| hono | low | GHSA-gq3j-xvxp-8hrf | v2 | Hono added timing comparison hardening in basicAuth and bearerAuth |\n| qs | low | CVE-2026-2391 | v2 | qs's arrayLimit bypass in comma parsing allows denial of service |\n| webpack | low | CVE-2025-68458 | v2 | webpack buildHttp: allowedUris allow-list bypass via URL userinfo (@) leading to |\n| webpack | low | CVE-2025-68157 | v2 | webpack buildHttp HttpUriPlugin allowedUris bypass via HTTP redirects → SSRF + c |\n",
297
297
  "kind": "doc"
298
298
  },
299
299
  {
@@ -1717,7 +1717,7 @@
1717
1717
  "group": "scenarios",
1718
1718
  "name": "performance-test",
1719
1719
  "path": "packages/samples/react/src/scenarios/performance-test.tsx",
1720
- "code": "import { KolButton, KolInputCheckbox, KolInputNumber, KolInputText, KolSkeleton } from '@public-ui/react-v19';\nimport type { FC } from 'react';\nimport React, { useState } from 'react';\nimport { SampleDescription } from '../components/SampleDescription';\n\ntype ComponentType = 'text' | 'number' | 'checkbox' | 'skeleton';\n\nexport const PerformanceTest: FC = () => {\n\tconst [count, setCount] = useState<number>(100);\n\tconst [activeComponent, setActiveComponent] = useState<ComponentType | null>(null);\n\tconst [renderTime, setRenderTime] = useState<number | null>(null);\n\tconst [isRendering, setIsRendering] = useState<boolean>(false);\n\n\tconst handleEvents = {\n\t\tonInput: (_event: Event, value: unknown) => {\n\t\t\tsetCount(value as number);\n\t\t},\n\t};\n\n\tconst renderComponent = (type: ComponentType, idx: number) => {\n\t\tswitch (type) {\n\t\t\tcase 'text':\n\t\t\t\treturn <KolInputText key={idx} _label={`TextInput #${idx}`} />;\n\t\t\tcase 'number':\n\t\t\t\treturn <KolInputNumber key={idx} _label={`NumberInput #${idx}`} />;\n\t\t\tcase 'checkbox':\n\t\t\t\treturn <KolInputCheckbox key={idx} _label={`Checkbox #${idx}`} />;\n\t\t\tcase 'skeleton':\n\t\t\t\treturn <KolSkeleton key={idx} _count={3} _name={`skeleton-${idx}`} />;\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t};\n\n\tconst renderComponents = () => {\n\t\tif (!activeComponent) return null;\n\n\t\tconst components = [];\n\t\tfor (let i = 1; i <= count; i++) {\n\t\t\tcomponents.push(renderComponent(activeComponent, i));\n\t\t}\n\t\treturn components;\n\t};\n\n\tconst handleComponentRender = (type: ComponentType) => {\n\t\tsetIsRendering(true);\n\t\tsetRenderTime(null);\n\t\tconst startTime = performance.now();\n\n\t\tsetActiveComponent(type);\n\n\t\t// Verwende setTimeout um die Renderzeit nach dem nächsten Render-Zyklus zu messen\n\t\tsetTimeout(() => {\n\t\t\tconst endTime = performance.now();\n\t\t\tsetRenderTime(endTime - startTime);\n\t\t\tsetIsRendering(false);\n\t\t}, 0);\n\t};\n\n\tconst handleClear = () => {\n\t\tsetActiveComponent(null);\n\t\tsetRenderTime(null);\n\t\tsetIsRendering(false);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This example renders many KoliBri components to show the performance. Choose a component type and set the number of instances to render.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<div className=\"w-full mb-6\">\n\t\t\t\t<div className=\"flex flex-wrap items-end gap-4 mb-4\">\n\t\t\t\t\t<KolInputNumber _label=\"Number of components\" _value={count} _min={1} _max={500} _on={handleEvents} />\n\t\t\t\t</div>\n\n\t\t\t\t<div className=\"flex flex-wrap gap-4 mb-6\">\n\t\t\t\t\t<KolButton _label=\"Render TextInputs\" _variant=\"primary\" onClick={() => handleComponentRender('text')} />\n\t\t\t\t\t<KolButton _label=\"Render NumberInputs\" _variant=\"primary\" onClick={() => handleComponentRender('number')} />\n\t\t\t\t\t<KolButton _label=\"Render Checkboxes\" _variant=\"primary\" onClick={() => handleComponentRender('checkbox')} />\n\t\t\t\t\t<KolButton _label=\"Render Skeletons\" _variant=\"primary\" onClick={() => handleComponentRender('skeleton')} />\n\t\t\t\t\t<KolButton _label=\"Clear\" _variant=\"secondary\" onClick={handleClear} />\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{activeComponent && (\n\t\t\t\t<div className=\"w-full mb-4\">\n\t\t\t\t\t<p className=\"text-sm text-gray-600 mb-2\">\n\t\t\t\t\t\tRendering {count} {activeComponent} component{count !== 1 ? 's' : ''}\n\t\t\t\t\t</p>\n\t\t\t\t\t{isRendering && <p className=\"text-sm text-blue-600\">⏱️ Measuring render time...</p>}\n\t\t\t\t\t{renderTime !== null && !isRendering && <p className=\"text-sm text-green-600\">✅ Render time: {renderTime.toFixed(2)}ms</p>}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<div className=\"w-full grid gap-4\">{renderComponents()}</div>\n\t\t</>\n\t);\n};\n",
1720
+ "code": "import { KolButton, KolInputCheckbox, KolInputNumber, KolInputText, KolSkeleton } from '@public-ui/react-v19';\nimport type { FC } from 'react';\nimport React, { useState } from 'react';\nimport { SampleDescription } from '../components/SampleDescription';\n\ntype ComponentType = 'text' | 'number' | 'checkbox' | 'skeleton';\n\nexport const PerformanceTest: FC = () => {\n\tconst [count, setCount] = useState<number>(100);\n\tconst [activeComponent, setActiveComponent] = useState<ComponentType | null>(null);\n\tconst [renderTime, setRenderTime] = useState<number | null>(null);\n\tconst [isRendering, setIsRendering] = useState<boolean>(false);\n\n\tconst handleEvents = {\n\t\tonInput: (_event: Event, value: unknown) => {\n\t\t\tsetCount(value as number);\n\t\t},\n\t};\n\n\tconst renderComponent = (type: ComponentType, idx: number) => {\n\t\tswitch (type) {\n\t\t\tcase 'text':\n\t\t\t\treturn <KolInputText key={idx} _label={`TextInput #${idx}`} />;\n\t\t\tcase 'number':\n\t\t\t\treturn <KolInputNumber key={idx} _label={`NumberInput #${idx}`} />;\n\t\t\tcase 'checkbox':\n\t\t\t\treturn <KolInputCheckbox key={idx} _label={`Checkbox #${idx}`} />;\n\t\t\tcase 'skeleton':\n\t\t\t\treturn <KolSkeleton key={idx} _name={`skeleton-${idx}`} />;\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t};\n\n\tconst renderComponents = () => {\n\t\tif (!activeComponent) return null;\n\n\t\tconst components = [];\n\t\tfor (let i = 1; i <= count; i++) {\n\t\t\tcomponents.push(renderComponent(activeComponent, i));\n\t\t}\n\t\treturn components;\n\t};\n\n\tconst handleComponentRender = (type: ComponentType) => {\n\t\tsetIsRendering(true);\n\t\tsetRenderTime(null);\n\t\tconst startTime = performance.now();\n\n\t\tsetActiveComponent(type);\n\n\t\t// Verwende setTimeout um die Renderzeit nach dem nächsten Render-Zyklus zu messen\n\t\tsetTimeout(() => {\n\t\t\tconst endTime = performance.now();\n\t\t\tsetRenderTime(endTime - startTime);\n\t\t\tsetIsRendering(false);\n\t\t}, 0);\n\t};\n\n\tconst handleClear = () => {\n\t\tsetActiveComponent(null);\n\t\tsetRenderTime(null);\n\t\tsetIsRendering(false);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>This example renders many KoliBri components to show the performance. Choose a component type and set the number of instances to render.</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<div className=\"w-full mb-6\">\n\t\t\t\t<div className=\"flex flex-wrap items-end gap-4 mb-4\">\n\t\t\t\t\t<KolInputNumber _label=\"Number of components\" _value={count} _min={1} _max={500} _on={handleEvents} />\n\t\t\t\t</div>\n\n\t\t\t\t<div className=\"flex flex-wrap gap-4 mb-6\">\n\t\t\t\t\t<KolButton _label=\"Render TextInputs\" _variant=\"primary\" onClick={() => handleComponentRender('text')} />\n\t\t\t\t\t<KolButton _label=\"Render NumberInputs\" _variant=\"primary\" onClick={() => handleComponentRender('number')} />\n\t\t\t\t\t<KolButton _label=\"Render Checkboxes\" _variant=\"primary\" onClick={() => handleComponentRender('checkbox')} />\n\t\t\t\t\t<KolButton _label=\"Render Skeletons\" _variant=\"primary\" onClick={() => handleComponentRender('skeleton')} />\n\t\t\t\t\t<KolButton _label=\"Clear\" _variant=\"secondary\" onClick={handleClear} />\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{activeComponent && (\n\t\t\t\t<div className=\"w-full mb-4\">\n\t\t\t\t\t<p className=\"text-sm text-gray-600 mb-2\">\n\t\t\t\t\t\tRendering {count} {activeComponent} component{count !== 1 ? 's' : ''}\n\t\t\t\t\t</p>\n\t\t\t\t\t{isRendering && <p className=\"text-sm text-blue-600\">⏱️ Measuring render time...</p>}\n\t\t\t\t\t{renderTime !== null && !isRendering && <p className=\"text-sm text-green-600\">✅ Render time: {renderTime.toFixed(2)}ms</p>}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<div className=\"w-full grid gap-4\">{renderComponents()}</div>\n\t\t</>\n\t);\n};\n",
1721
1721
  "kind": "scenario"
1722
1722
  },
1723
1723
  {
@@ -1757,7 +1757,7 @@
1757
1757
  "group": "scenarios",
1758
1758
  "name": "skeleton",
1759
1759
  "path": "packages/samples/react/src/scenarios/skeleton.tsx",
1760
- "code": "import type { FC } from 'react';\nimport React, { useCallback, useRef, useState } from 'react';\n\nimport { KolButton, KolInputRange, KolSkeleton } from '@public-ui/react-v19';\nimport { SampleDescription } from '../components/SampleDescription';\n\ninterface EventLogEntry {\n\ttimestamp: string;\n\tcount: number;\n\tid: number;\n}\n\nexport const Skeleton: FC = () => {\n\tconst skeletonRef = useRef<HTMLKolSkeletonElement>(null);\n\tconst rangeRef = useRef<HTMLKolInputRangeElement>(null);\n\tconst initialCount = 3;\n\n\tconst durationFormatter = new Intl.NumberFormat('de-DE', { style: 'unit', unit: 'millisecond', maximumFractionDigits: 1 });\n\tconst timeFormatter = new Intl.DateTimeFormat('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n\n\tconst [count, setCount] = useState<number>(initialCount);\n\tconst [eventLog, setEventLog] = useState<EventLogEntry[]>([]);\n\tconst [lastEventTime, setLastEventTime] = useState<string>('');\n\tconst [eventCount, setEventCount] = useState<number>(0);\n\tconst [skeletonCount, setSkeletonCount] = useState<number>(20);\n\n\t// Render benchmark state\n\tconst [generation, setGeneration] = useState<number>(0);\n\tconst [renderDuration, setRenderDuration] = useState<number | null>(null);\n\tconst [isMeasuring, setIsMeasuring] = useState<boolean>(false);\n\n\t// Refs for stable values in closures (no stale closure issues)\n\tconst renderStartTimeRef = useRef<number>(0);\n\tconst expectedCountRef = useRef<number>(20);\n\tconst renderedCountRef = useRef<number>(0);\n\n\tconst handleLoaded = (event: CustomEvent<number>) => {\n\t\tconst now = new Date();\n\t\tconst timestamp = timeFormatter.format(now);\n\t\tconst newEventCount = eventCount + 1;\n\n\t\tsetCount(event.detail);\n\t\tsetLastEventTime(timestamp);\n\t\tsetEventCount(newEventCount);\n\n\t\t// Add to event log (keep only last 5 entries)\n\t\tsetEventLog((prev) => {\n\t\t\tconst newEntry: EventLogEntry = {\n\t\t\t\ttimestamp,\n\t\t\t\tcount: event.detail,\n\t\t\t\tid: newEventCount,\n\t\t\t};\n\t\t\treturn [newEntry, ...prev.slice(0, 4)];\n\t\t});\n\t};\n\n\tconst handleRendered = useCallback(() => {\n\t\trenderedCountRef.current += 1;\n\n\t\tif (renderedCountRef.current >= expectedCountRef.current) {\n\t\t\tconst duration = performance.now() - renderStartTimeRef.current;\n\t\t\tsetRenderDuration(duration);\n\t\t\tsetIsMeasuring(false);\n\t\t}\n\t}, []);\n\n\tconst handleRangeChange = (_event: Event, value: unknown) => {\n\t\tconst newValue = Number(value);\n\t\tsetSkeletonCount(newValue);\n\n\t\t// Start benchmark measurement\n\t\trenderedCountRef.current = 0;\n\t\texpectedCountRef.current = newValue;\n\t\trenderStartTimeRef.current = performance.now();\n\t\tsetRenderDuration(null);\n\t\tsetIsMeasuring(true);\n\t\tsetGeneration((prev) => prev + 1);\n\t};\n\n\tconst handleRangeBlur = () => {\n\t\t// Sicherstellen, dass der interne Wert mit dem State synchronisiert ist\n\t\tif (rangeRef.current) {\n\t\t\trangeRef.current._value = skeletonCount;\n\t\t}\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>\n\t\t\t\t\tKolSkeleton demonstriert Event-Emitter mit automatischem Intervall. Die Komponente emittiert alle 2 Sekunden ein &quot;loaded&quot; Event mit dem\n\t\t\t\t\taktuellen Count-Wert. Über die Buttons kann die Komponente getoggled und fokussiert werden. Der interne ClickButton erhöht bei Klick den Counter.\n\t\t\t\t</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<div className=\"grid md:grid-cols-2 gap-4 mb-4 items-center\">\n\t\t\t\t<div className=\"grid sm:grid-cols-2 gap-4\">\n\t\t\t\t\t<KolButton\n\t\t\t\t\t\t_label=\"Toggle Sichtbarkeit\"\n\t\t\t\t\t\t_on={{\n\t\t\t\t\t\t\tonClick: () => skeletonRef.current?.toggle(),\n\t\t\t\t\t\t}}\n\t\t\t\t\t\t_variant=\"primary\"\n\t\t\t\t\t/>\n\t\t\t\t\t<KolButton\n\t\t\t\t\t\t_label=\"Fokus auf Button\"\n\t\t\t\t\t\t_on={{\n\t\t\t\t\t\t\tonClick: () => skeletonRef.current?.focus(),\n\t\t\t\t\t\t}}\n\t\t\t\t\t\t_variant=\"secondary\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"grid sm:grid-cols-2 gap-4 items-center\">\n\t\t\t\t\t<KolInputRange\n\t\t\t\t\t\tref={rangeRef}\n\t\t\t\t\t\t_label=\"Anzahl der Skeletons\"\n\t\t\t\t\t\t_hideLabel\n\t\t\t\t\t\t_min={1}\n\t\t\t\t\t\t_max={10000}\n\t\t\t\t\t\t_step={25}\n\t\t\t\t\t\t_value={skeletonCount}\n\t\t\t\t\t\t_on={{\n\t\t\t\t\t\t\tonChange: handleRangeChange,\n\t\t\t\t\t\t\tonBlur: handleRangeBlur,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t<span className=\"text-sm text-gray-600 whitespace-nowrap\">{skeletonCount} Skeletons</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{/* Render Benchmark */}\n\t\t\t<div className=\"mb-4 px-3 py-2 border border-gray-300 rounded bg-gray-50 flex items-center gap-4 text-sm\">\n\t\t\t\t<span className=\"font-semibold\">Benchmark:</span>\n\t\t\t\t<span className={isMeasuring ? 'text-orange-600 font-bold' : renderDuration !== null ? 'text-green-600' : 'text-gray-400'}>\n\t\t\t\t\t{isMeasuring ? 'Rendering…' : renderDuration !== null ? 'Fertig' : 'Bereit'}\n\t\t\t\t</span>\n\t\t\t\t<span className=\"font-bold text-blue-600\" aria-live=\"polite\">\n\t\t\t\t\t{renderDuration !== null ? durationFormatter.format(renderDuration) : '—'}\n\t\t\t\t</span>\n\t\t\t</div>\n\n\t\t\t<div className=\"flex flex-wrap gap-4\">\n\t\t\t\t{Array.from({ length: skeletonCount }, (_, idx) => (\n\t\t\t\t\t<KolSkeleton\n\t\t\t\t\t\tkey={`skeleton-${generation}-${idx}`}\n\t\t\t\t\t\t_count={initialCount}\n\t\t\t\t\t\t_name={`Example ${idx}`}\n\t\t\t\t\t\tonLoaded={idx === 0 ? handleLoaded : undefined}\n\t\t\t\t\t\tonRendered={handleRendered}\n\t\t\t\t\t\tref={idx === 0 ? skeletonRef : undefined}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</div>\n\n\t\t\t<div className=\"mt-6 p-4 border border-gray-300 rounded-lg bg-gray-50\">\n\t\t\t\t<h3 className=\"text-lg font-semibold mb-3\">Event Monitor</h3>\n\t\t\t\t<div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p className=\"font-medium\">Aktueller Count-Wert:</p>\n\t\t\t\t\t\t<p className=\"text-2xl font-bold text-blue-600\" aria-live=\"polite\">\n\t\t\t\t\t\t\t{count}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p className=\"font-medium\">Letztes Event:</p>\n\t\t\t\t\t\t<p className=\"text-lg\" aria-live=\"polite\">\n\t\t\t\t\t\t\t{lastEventTime || 'Noch kein Event empfangen'}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"mt-4\">\n\t\t\t\t\t<p className=\"font-medium mb-2\">\n\t\t\t\t\t\tEvents empfangen: <span className=\"font-bold\">{eventCount}</span>\n\t\t\t\t\t</p>\n\t\t\t\t\t{eventLog.length > 0 && (\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<p className=\"font-medium mb-2\">Event-Historie (letzte 5):</p>\n\t\t\t\t\t\t\t<ul className=\"text-sm space-y-1 max-h-32 overflow-y-auto\">\n\t\t\t\t\t\t\t\t{eventLog.map((entry) => (\n\t\t\t\t\t\t\t\t\t<li key={entry.id} className=\"flex justify-between items-center p-2 bg-white rounded border\">\n\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t\t#{entry.id}: Count = {entry.count}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<span className=\"text-gray-500\">{entry.timestamp}</span>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"mt-4 p-3 bg-blue-50 rounded\">\n\t\t\t\t\t<p className=\"text-sm text-blue-800\">\n\t\t\t\t\t\t💡 <strong>Tipp:</strong> Die Komponente emittiert automatisch alle 2 Sekunden ein Event. Klicke auf den &quot;Click Button&quot; in der Komponente,\n\t\t\t\t\t\tum den Count-Wert zu erhöhen.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n};\n",
1760
+ "code": "import type { FC } from 'react';\nimport React, { useCallback, useRef, useState } from 'react';\n\nimport { KolButton, KolInputRange, KolSkeleton } from '@public-ui/react-v19';\nimport { SampleDescription } from '../components/SampleDescription';\n\ninterface EventLogEntry {\n\ttimestamp: string;\n\tcount: number;\n\tid: number;\n}\n\nexport const Skeleton: FC = () => {\n\tconst skeletonRef = useRef<HTMLKolSkeletonElement>(null);\n\tconst rangeRef = useRef<HTMLKolInputRangeElement>(null);\n\tconst initialCount = 3;\n\n\tconst durationFormatter = new Intl.NumberFormat('de-DE', { style: 'unit', unit: 'millisecond', maximumFractionDigits: 1 });\n\tconst timeFormatter = new Intl.DateTimeFormat('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n\n\tconst [count, setCount] = useState<number>(initialCount);\n\tconst [eventLog, setEventLog] = useState<EventLogEntry[]>([]);\n\tconst [lastEventTime, setLastEventTime] = useState<string>('');\n\tconst [eventCount, setEventCount] = useState<number>(0);\n\tconst [skeletonCount, setSkeletonCount] = useState<number>(20);\n\n\t// Render benchmark state\n\tconst [generation, setGeneration] = useState<number>(0);\n\tconst [renderDuration, setRenderDuration] = useState<number | null>(null);\n\tconst [isMeasuring, setIsMeasuring] = useState<boolean>(false);\n\n\t// Refs for stable values in closures (no stale closure issues)\n\tconst renderStartTimeRef = useRef<number>(0);\n\tconst expectedCountRef = useRef<number>(20);\n\tconst renderedCountRef = useRef<number>(0);\n\n\tconst handleLoaded = (event: CustomEvent<number>) => {\n\t\tconst now = new Date();\n\t\tconst timestamp = timeFormatter.format(now);\n\t\tconst newEventCount = eventCount + 1;\n\n\t\tsetCount(event.detail);\n\t\tsetLastEventTime(timestamp);\n\t\tsetEventCount(newEventCount);\n\n\t\t// Add to event log (keep only last 5 entries)\n\t\tsetEventLog((prev) => {\n\t\t\tconst newEntry: EventLogEntry = {\n\t\t\t\ttimestamp,\n\t\t\t\tcount: event.detail,\n\t\t\t\tid: newEventCount,\n\t\t\t};\n\t\t\treturn [newEntry, ...prev.slice(0, 4)];\n\t\t});\n\t};\n\n\tconst handleRendered = useCallback(() => {\n\t\trenderedCountRef.current += 1;\n\n\t\tif (renderedCountRef.current >= expectedCountRef.current) {\n\t\t\tconst duration = performance.now() - renderStartTimeRef.current;\n\t\t\tsetRenderDuration(duration);\n\t\t\tsetIsMeasuring(false);\n\t\t}\n\t}, []);\n\n\tconst handleRangeChange = (_event: Event, value: unknown) => {\n\t\tconst newValue = Number(value);\n\t\tsetSkeletonCount(newValue);\n\n\t\t// Start benchmark measurement\n\t\trenderedCountRef.current = 0;\n\t\texpectedCountRef.current = newValue;\n\t\trenderStartTimeRef.current = performance.now();\n\t\tsetRenderDuration(null);\n\t\tsetIsMeasuring(true);\n\t\tsetGeneration((prev) => prev + 1);\n\t};\n\n\tconst handleRangeBlur = () => {\n\t\t// Sicherstellen, dass der interne Wert mit dem State synchronisiert ist\n\t\tif (rangeRef.current) {\n\t\t\trangeRef.current._value = skeletonCount;\n\t\t}\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<SampleDescription>\n\t\t\t\t<p>\n\t\t\t\t\tKolSkeleton demonstriert Event-Emitter mit automatischem Intervall. Die Komponente emittiert alle 2 Sekunden ein &quot;loaded&quot; Event mit dem\n\t\t\t\t\taktuellen Count-Wert. Über die Buttons kann die Komponente getoggled und fokussiert werden. Der interne ClickButton erhöht bei Klick den Counter.\n\t\t\t\t</p>\n\t\t\t</SampleDescription>\n\n\t\t\t<div className=\"grid md:grid-cols-2 gap-4 mb-4 items-center\">\n\t\t\t\t<div className=\"grid sm:grid-cols-2 gap-4\">\n\t\t\t\t\t<KolButton\n\t\t\t\t\t\t_label=\"Toggle Sichtbarkeit\"\n\t\t\t\t\t\t_on={{\n\t\t\t\t\t\t\tonClick: () => skeletonRef.current?.toggle(),\n\t\t\t\t\t\t}}\n\t\t\t\t\t\t_variant=\"primary\"\n\t\t\t\t\t/>\n\t\t\t\t\t<KolButton\n\t\t\t\t\t\t_label=\"Fokus auf Button\"\n\t\t\t\t\t\t_on={{\n\t\t\t\t\t\t\tonClick: () => skeletonRef.current?.focus(),\n\t\t\t\t\t\t}}\n\t\t\t\t\t\t_variant=\"secondary\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"grid sm:grid-cols-2 gap-4 items-center\">\n\t\t\t\t\t<KolInputRange\n\t\t\t\t\t\tref={rangeRef}\n\t\t\t\t\t\t_label=\"Anzahl der Skeletons\"\n\t\t\t\t\t\t_hideLabel\n\t\t\t\t\t\t_min={1}\n\t\t\t\t\t\t_max={10000}\n\t\t\t\t\t\t_step={25}\n\t\t\t\t\t\t_value={skeletonCount}\n\t\t\t\t\t\t_on={{\n\t\t\t\t\t\t\tonChange: handleRangeChange,\n\t\t\t\t\t\t\tonBlur: handleRangeBlur,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t<span className=\"text-sm text-gray-600 whitespace-nowrap\">{skeletonCount} Skeletons</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{/* Render Benchmark */}\n\t\t\t<div className=\"mb-4 px-3 py-2 border border-gray-300 rounded bg-gray-50 flex items-center gap-4 text-sm\">\n\t\t\t\t<span className=\"font-semibold\">Benchmark:</span>\n\t\t\t\t<span className={isMeasuring ? 'text-orange-600 font-bold' : renderDuration !== null ? 'text-green-600' : 'text-gray-400'}>\n\t\t\t\t\t{isMeasuring ? 'Rendering…' : renderDuration !== null ? 'Fertig' : 'Bereit'}\n\t\t\t\t</span>\n\t\t\t\t<span className=\"font-bold text-blue-600\" aria-live=\"polite\">\n\t\t\t\t\t{renderDuration !== null ? durationFormatter.format(renderDuration) : '—'}\n\t\t\t\t</span>\n\t\t\t</div>\n\n\t\t\t<div className=\"flex flex-wrap gap-4\">\n\t\t\t\t{Array.from({ length: skeletonCount }, (_, idx) => (\n\t\t\t\t\t<KolSkeleton\n\t\t\t\t\t\tkey={`skeleton-${generation}-${idx}`}\n\t\t\t\t\t\t_name={`Example ${idx}`}\n\t\t\t\t\t\tonLoaded={idx === 0 ? handleLoaded : undefined}\n\t\t\t\t\t\tonRendered={handleRendered}\n\t\t\t\t\t\tref={idx === 0 ? skeletonRef : undefined}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</div>\n\n\t\t\t<div className=\"mt-6 p-4 border border-gray-300 rounded-lg bg-gray-50\">\n\t\t\t\t<h3 className=\"text-lg font-semibold mb-3\">Event Monitor</h3>\n\t\t\t\t<div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p className=\"font-medium\">Aktueller Count-Wert:</p>\n\t\t\t\t\t\t<p className=\"text-2xl font-bold text-blue-600\" aria-live=\"polite\">\n\t\t\t\t\t\t\t{count}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p className=\"font-medium\">Letztes Event:</p>\n\t\t\t\t\t\t<p className=\"text-lg\" aria-live=\"polite\">\n\t\t\t\t\t\t\t{lastEventTime || 'Noch kein Event empfangen'}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"mt-4\">\n\t\t\t\t\t<p className=\"font-medium mb-2\">\n\t\t\t\t\t\tEvents empfangen: <span className=\"font-bold\">{eventCount}</span>\n\t\t\t\t\t</p>\n\t\t\t\t\t{eventLog.length > 0 && (\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<p className=\"font-medium mb-2\">Event-Historie (letzte 5):</p>\n\t\t\t\t\t\t\t<ul className=\"text-sm space-y-1 max-h-32 overflow-y-auto\">\n\t\t\t\t\t\t\t\t{eventLog.map((entry) => (\n\t\t\t\t\t\t\t\t\t<li key={entry.id} className=\"flex justify-between items-center p-2 bg-white rounded border\">\n\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t\t#{entry.id}: Count = {entry.count}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<span className=\"text-gray-500\">{entry.timestamp}</span>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"mt-4 p-3 bg-blue-50 rounded\">\n\t\t\t\t\t<p className=\"text-sm text-blue-800\">\n\t\t\t\t\t\t💡 <strong>Tipp:</strong> Die Komponente emittiert automatisch alle 2 Sekunden ein Event. Klicke auf den &quot;Click Button&quot; in der Komponente,\n\t\t\t\t\t\tum den Count-Wert zu erhöhen.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n};\n",
1761
1761
  "kind": "scenario"
1762
1762
  },
1763
1763
  {
@@ -2125,7 +2125,7 @@
2125
2125
  "group": "spec",
2126
2126
  "name": "skeleton",
2127
2127
  "path": "packages/tools/mcp/node_modules/@public-ui/components/doc/skeleton.md",
2128
- "code": "# kol-skeleton\n\n\n\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property | Attribute | Description | Type | Default |\n| -------------------- | --------- | ----------------------------------------- | ------------------------------- | ----------- |\n| `_count` | `_count` | Sets the count of the skeleton component. | `number \\| string \\| undefined` | `undefined` |\n| `_name` _(required)_ | `_name` | Sets the name of the skeleton component. | `string` | `undefined` |\n\n\n## Events\n\n| Event | Description | Type |\n| ---------- | --------------------------------------------------------------- | --------------------- |\n| `loaded` | Emitted when the skeleton has finished loading. | `CustomEvent<number>` |\n| `rendered` | Emitted when the skeleton has been rendered for the first time. | `CustomEvent<void>` |\n\n\n## Methods\n\n### `focus() => Promise<void>`\n\nFocuses the interactive element of the component.\n\n#### Returns\n\nType: `Promise<void>`\n\n\n\n### `toggle() => Promise<void>`\n\nToggles the visibility of the skeleton component.\n\n#### Returns\n\nType: `Promise<void>`\n\n\n\n\n----------------------------------------------\n\n\n",
2128
+ "code": "# kol-skeleton\n\n\n\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property | Attribute | Description | Type | Default |\n| -------------------- | --------- | ---------------------------------------- | -------- | ----------- |\n| `_name` _(required)_ | `_name` | Sets the name of the skeleton component. | `string` | `undefined` |\n\n\n## Events\n\n| Event | Description | Type |\n| ---------- | --------------------------------------------------------------- | --------------------- |\n| `loaded` | Emitted when the skeleton has finished loading. | `CustomEvent<number>` |\n| `rendered` | Emitted when the skeleton has been rendered for the first time. | `CustomEvent<void>` |\n\n\n## Methods\n\n### `focus() => Promise<void>`\n\nFocuses the interactive element of the component.\n\n#### Returns\n\nType: `Promise<void>`\n\n\n\n### `toggle() => Promise<void>`\n\nToggles the visibility of the skeleton component.\n\n#### Returns\n\nType: `Promise<void>`\n\n\n\n\n----------------------------------------------\n\n\n",
2129
2129
  "kind": "spec"
2130
2130
  },
2131
2131
  {