@api-client/ui 0.5.33 → 0.5.34

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ApplicationRoute.d.ts","sourceRoot":"","sources":["../../../src/core/ApplicationRoute.ts"],"names":[],"mappings":"AAkDA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,SAAS,CAWhH;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,YAAY,SAAK,GAAG,MAAM,CAUlD;AAkBD,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAItE;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAIlE"}
1
+ {"version":3,"file":"ApplicationRoute.d.ts","sourceRoot":"","sources":["../../../src/core/ApplicationRoute.ts"],"names":[],"mappings":"AAqDA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,SAAS,CAWhH;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,YAAY,SAAK,GAAG,MAAM,CAUlD;AAkBD,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAItE;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAIlE"}
@@ -32,6 +32,9 @@ function parseParams(pattern, uri) {
32
32
  if (groups) {
33
33
  Object.keys(groups).forEach((key) => {
34
34
  let value = groups[key];
35
+ if (value === undefined) {
36
+ return;
37
+ }
35
38
  if (value[0] === '/') {
36
39
  value = value.substring(1);
37
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ApplicationRoute.js","sourceRoot":"","sources":["../../../src/core/ApplicationRoute.ts"],"names":[],"mappings":"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","sourcesContent":["const compiled = new Map<string, RegExp>()\n\n/**\n * @param value The pattern to evaluate\n */\nfunction getPattern(value: string): RegExp {\n if (compiled.has(value)) {\n return compiled.get(value) as RegExp\n }\n const result = new RegExp(`^${value}$`)\n compiled.set(value, result)\n return result\n}\n\n/**\n * @param uri The path value of the current URL.\n * @param pattern The pattern to evaluate\n */\nfunction testRoute(uri: string, pattern: string): boolean {\n return getPattern(pattern).test(uri)\n}\n\n/**\n * @param pattern The pattern to evaluate\n * @param uri The path value of the current URL.\n */\nfunction parseParams(pattern: string, uri: string): Record<string, string | string[]> | undefined {\n const r = getPattern(pattern)\n const match = r.exec(uri)\n if (!match) {\n return undefined\n }\n const { groups } = match\n const result: Record<string, string | string[]> = {}\n if (groups) {\n Object.keys(groups).forEach((key) => {\n let value = groups[key] as string\n if (value[0] === '/') {\n value = value.substring(1)\n }\n if (value.includes('/')) {\n result[key] = value.split('/').map((i) => decodeURIComponent(i))\n } else {\n result[key] = decodeURIComponent(value)\n }\n })\n }\n return result\n}\n\n/**\n * Reads params from the route for given patterns.\n * @param patterns The list of patterns to consider\n * @param route The current route\n * @returns A list of read parameters or undefined when there's no matching route or params.\n *\n * @example\n *\n * ```typescript\n * const patterns = ['/my/path/:id']\n * const route = '/my/path/1234'\n * const params = readRouteParams(patterns, route)\n * // -> { id: '1234' }\n * ```\n */\nexport function readRouteParams(patterns: string[], route: string): Record<string, string | string[]> | undefined {\n for (const pattern of patterns) {\n if (!testRoute(route, pattern)) {\n continue\n }\n const params = parseParams(pattern, route)\n if (params) {\n return params\n }\n }\n return undefined\n}\n\n/**\n * Reads the current route as everything that is past the `#`\n * @param defaultRoute The route that would be considered a default route for the activity.\n * @returns The current route.\n */\nexport function getRoute(defaultRoute = ''): string {\n const url = new URL(window.location.href)\n let path = url.hash.replace('#', '')\n if (!path) {\n path = defaultRoute\n }\n if (!path.startsWith('/')) {\n path = `/${path}`\n }\n return path\n}\n\nfunction createHash(...route: string[]): string {\n const atoms: string[] = []\n for (const atom of route) {\n if (atom.includes('/')) {\n atoms.push(...atom.split('/').filter((i) => !!i))\n } else {\n atoms.push(atom)\n }\n }\n let hash = atoms.map(encodeURIComponent).join('/')\n if (!hash.startsWith('/')) {\n hash = `/${hash}`\n }\n return hash\n}\n\nexport function buildRoute(...route: string[]): string {\n const url = new URL(window.location.href)\n url.hash = createHash(...route)\n return url.toString()\n}\n\n/**\n * Navigates to an internal route.\n *\n * @param route Optional route params to add to the hash part of the url.\n */\nexport function navigateScreen(...route: string[]): void {\n window.location.href = buildRoute(...route)\n}\n\n/**\n * Navigates to another application.\n *\n * @param htmlFile The relative location of the target HTML file.\n * @param route Optional route params to add to the has part of the url.\n */\nexport function navigateApp(htmlFile: string, ...route: string[]): void {\n const url = new URL(htmlFile, window.location.href)\n url.hash = createHash(...route)\n window.location.href = url.toString()\n}\n\n/**\n * Navigates to another application.\n *\n * @param htmlFile The relative location of the target HTML file.\n * @param route Optional route params to add to the has part of the url.\n */\nexport function openApp(htmlFile: string, ...route: string[]): void {\n const url = new URL(htmlFile, window.location.href)\n url.hash = createHash(...route)\n window.open(url.toString(), '_blank')\n}\n"]}
1
+ {"version":3,"file":"ApplicationRoute.js","sourceRoot":"","sources":["../../../src/core/ApplicationRoute.ts"],"names":[],"mappings":"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","sourcesContent":["const compiled = new Map<string, RegExp>()\n\n/**\n * @param value The pattern to evaluate\n */\nfunction getPattern(value: string): RegExp {\n if (compiled.has(value)) {\n return compiled.get(value) as RegExp\n }\n const result = new RegExp(`^${value}$`)\n compiled.set(value, result)\n return result\n}\n\n/**\n * @param uri The path value of the current URL.\n * @param pattern The pattern to evaluate\n */\nfunction testRoute(uri: string, pattern: string): boolean {\n return getPattern(pattern).test(uri)\n}\n\n/**\n * @param pattern The pattern to evaluate\n * @param uri The path value of the current URL.\n */\nfunction parseParams(pattern: string, uri: string): Record<string, string | string[]> | undefined {\n const r = getPattern(pattern)\n const match = r.exec(uri)\n if (!match) {\n return undefined\n }\n const { groups } = match\n const result: Record<string, string | string[]> = {}\n if (groups) {\n Object.keys(groups).forEach((key) => {\n let value = groups[key] as string | undefined\n if (value === undefined) {\n return\n }\n if (value[0] === '/') {\n value = value.substring(1)\n }\n if (value.includes('/')) {\n result[key] = value.split('/').map((i) => decodeURIComponent(i))\n } else {\n result[key] = decodeURIComponent(value)\n }\n })\n }\n return result\n}\n\n/**\n * Reads params from the route for given patterns.\n * @param patterns The list of patterns to consider\n * @param route The current route\n * @returns A list of read parameters or undefined when there's no matching route or params.\n *\n * @example\n *\n * ```typescript\n * const patterns = ['/my/path/:id']\n * const route = '/my/path/1234'\n * const params = readRouteParams(patterns, route)\n * // -> { id: '1234' }\n * ```\n */\nexport function readRouteParams(patterns: string[], route: string): Record<string, string | string[]> | undefined {\n for (const pattern of patterns) {\n if (!testRoute(route, pattern)) {\n continue\n }\n const params = parseParams(pattern, route)\n if (params) {\n return params\n }\n }\n return undefined\n}\n\n/**\n * Reads the current route as everything that is past the `#`\n * @param defaultRoute The route that would be considered a default route for the activity.\n * @returns The current route.\n */\nexport function getRoute(defaultRoute = ''): string {\n const url = new URL(window.location.href)\n let path = url.hash.replace('#', '')\n if (!path) {\n path = defaultRoute\n }\n if (!path.startsWith('/')) {\n path = `/${path}`\n }\n return path\n}\n\nfunction createHash(...route: string[]): string {\n const atoms: string[] = []\n for (const atom of route) {\n if (atom.includes('/')) {\n atoms.push(...atom.split('/').filter((i) => !!i))\n } else {\n atoms.push(atom)\n }\n }\n let hash = atoms.map(encodeURIComponent).join('/')\n if (!hash.startsWith('/')) {\n hash = `/${hash}`\n }\n return hash\n}\n\nexport function buildRoute(...route: string[]): string {\n const url = new URL(window.location.href)\n url.hash = createHash(...route)\n return url.toString()\n}\n\n/**\n * Navigates to an internal route.\n *\n * @param route Optional route params to add to the hash part of the url.\n */\nexport function navigateScreen(...route: string[]): void {\n window.location.href = buildRoute(...route)\n}\n\n/**\n * Navigates to another application.\n *\n * @param htmlFile The relative location of the target HTML file.\n * @param route Optional route params to add to the has part of the url.\n */\nexport function navigateApp(htmlFile: string, ...route: string[]): void {\n const url = new URL(htmlFile, window.location.href)\n url.hash = createHash(...route)\n window.location.href = url.toString()\n}\n\n/**\n * Navigates to another application.\n *\n * @param htmlFile The relative location of the target HTML file.\n * @param route Optional route params to add to the has part of the url.\n */\nexport function openApp(htmlFile: string, ...route: string[]): void {\n const url = new URL(htmlFile, window.location.href)\n url.hash = createHash(...route)\n window.open(url.toString(), '_blank')\n}\n"]}
@@ -73,6 +73,11 @@ export default class NavigationItem extends UiElement {
73
73
  * @attribute
74
74
  */
75
75
  accessor iconOnly: boolean;
76
+ /**
77
+ * The reference of the navigation item to the target.
78
+ * @attribute
79
+ */
80
+ accessor href: string | undefined;
76
81
  /**
77
82
  * Determines when the element has an icon in the "icon" slot.
78
83
  */
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationItem.d.ts","sourceRoot":"","sources":["../../../../../src/elements/navigation/internals/NavigationItem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAW,MAAM,KAAK,CAAA;AAInD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,SAAS;IACnD,OAAgB,iBAAiB,EAAE,cAAc,CAGhD;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;OAGG;IACH,IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAI1B;IAED;;;OAGG;IACyC,QAAQ,CAAC,QAAQ,UAAQ;IACrE;;;;OAIG;IACyC,QAAQ,CAAC,QAAQ,UAAQ;IAErE;;OAEG;IACM,SAAS,CAAC,QAAQ,CAAC,OAAO,UAAQ;IAE3C;;OAEG;IACH,SAAS,CAAC,oBAAoB,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;cAK3B,MAAM,IAAI,cAAc;IAqB3C,SAAS,CAAC,UAAU,IAAI,cAAc;CAKvC"}
1
+ {"version":3,"file":"NavigationItem.d.ts","sourceRoot":"","sources":["../../../../../src/elements/navigation/internals/NavigationItem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAW,MAAM,KAAK,CAAA;AAInD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,SAAS;IACnD,OAAgB,iBAAiB,EAAE,cAAc,CAGhD;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;OAGG;IACH,IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAI1B;IAED;;;OAGG;IACyC,QAAQ,CAAC,QAAQ,UAAQ;IACrE;;;;OAIG;IACyC,QAAQ,CAAC,QAAQ,UAAQ;IACrE;;;OAGG;IACwC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IAE5E;;OAEG;IACM,SAAS,CAAC,QAAQ,CAAC,OAAO,UAAQ;IAE3C;;OAEG;IACH,SAAS,CAAC,oBAAoB,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;cAK3B,MAAM,IAAI,cAAc;IAqB3C,SAAS,CAAC,UAAU,IAAI,cAAc;CAKvC"}
@@ -15,6 +15,9 @@ let NavigationItem = (() => {
15
15
  let _iconOnly_decorators;
16
16
  let _iconOnly_initializers = [];
17
17
  let _iconOnly_extraInitializers = [];
18
+ let _href_decorators;
19
+ let _href_initializers = [];
20
+ let _href_extraInitializers = [];
18
21
  let _hasIcon_decorators;
19
22
  let _hasIcon_initializers = [];
20
23
  let _hasIcon_extraInitializers = [];
@@ -24,10 +27,12 @@ let NavigationItem = (() => {
24
27
  _set_disabled_decorators = [property({ reflect: true, type: Boolean })];
25
28
  _selected_decorators = [property({ reflect: true, type: Boolean })];
26
29
  _iconOnly_decorators = [property({ reflect: true, type: Boolean })];
30
+ _href_decorators = [property({ reflect: true, type: String })];
27
31
  _hasIcon_decorators = [state()];
28
32
  __esDecorate(this, null, _set_disabled_decorators, { kind: "setter", name: "disabled", static: false, private: false, access: { has: obj => "disabled" in obj, set: (obj, value) => { obj.disabled = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
29
33
  __esDecorate(this, null, _selected_decorators, { kind: "accessor", name: "selected", static: false, private: false, access: { has: obj => "selected" in obj, get: obj => obj.selected, set: (obj, value) => { obj.selected = value; } }, metadata: _metadata }, _selected_initializers, _selected_extraInitializers);
30
34
  __esDecorate(this, null, _iconOnly_decorators, { kind: "accessor", name: "iconOnly", static: false, private: false, access: { has: obj => "iconOnly" in obj, get: obj => obj.iconOnly, set: (obj, value) => { obj.iconOnly = value; } }, metadata: _metadata }, _iconOnly_initializers, _iconOnly_extraInitializers);
35
+ __esDecorate(this, null, _href_decorators, { kind: "accessor", name: "href", static: false, private: false, access: { has: obj => "href" in obj, get: obj => obj.href, set: (obj, value) => { obj.href = value; } }, metadata: _metadata }, _href_initializers, _href_extraInitializers);
31
36
  __esDecorate(this, null, _hasIcon_decorators, { kind: "accessor", name: "hasIcon", static: false, private: false, access: { has: obj => "hasIcon" in obj, get: obj => obj.hasIcon, set: (obj, value) => { obj.hasIcon = value; } }, metadata: _metadata }, _hasIcon_initializers, _hasIcon_extraInitializers);
32
37
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
33
38
  }
@@ -62,7 +67,8 @@ let NavigationItem = (() => {
62
67
  set selected(value) { this.#selected_accessor_storage = value; }
63
68
  #iconOnly_accessor_storage = (__runInitializers(this, _selected_extraInitializers), __runInitializers(this, _iconOnly_initializers, false
64
69
  /**
65
- * Determines when the element has an icon in the "icon" slot.
70
+ * The reference of the navigation item to the target.
71
+ * @attribute
66
72
  */
67
73
  ));
68
74
  /**
@@ -72,7 +78,14 @@ let NavigationItem = (() => {
72
78
  */
73
79
  get iconOnly() { return this.#iconOnly_accessor_storage; }
74
80
  set iconOnly(value) { this.#iconOnly_accessor_storage = value; }
75
- #hasIcon_accessor_storage = (__runInitializers(this, _iconOnly_extraInitializers), __runInitializers(this, _hasIcon_initializers, false
81
+ #href_accessor_storage = (__runInitializers(this, _iconOnly_extraInitializers), __runInitializers(this, _href_initializers, void 0));
82
+ /**
83
+ * The reference of the navigation item to the target.
84
+ * @attribute
85
+ */
86
+ get href() { return this.#href_accessor_storage; }
87
+ set href(value) { this.#href_accessor_storage = value; }
88
+ #hasIcon_accessor_storage = (__runInitializers(this, _href_extraInitializers), __runInitializers(this, _hasIcon_initializers, false
76
89
  /**
77
90
  * Sets the `_hasIcon` state property when the "icon" slot change event is dispatched.
78
91
  */
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationItem.js","sourceRoot":"","sources":["../../../../../src/elements/navigation/internals/NavigationItem.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult, nothing } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { when } from 'lit/directives/when.js'\nimport { UiElement } from '../../../md/UiElement.js'\nimport { isDisabled, setDisabled } from '../../../lib/disabled.js'\n\n/**\n * NavigationItem\n *\n * An element to be placed inside a navigation bar. This component is designed for use with navigation bars and supports\n * icon-only, selected, and disabled states. It is built with accessibility and composability in mind.\n *\n * ## Accessibility\n *\n * - Uses a native `<button>` element for proper semantics and keyboard accessibility.\n * - The icon is marked with `role=\"presentation\"` to indicate it is decorative.\n * - Focus ring and ripple effects are included for visual feedback.\n *\n * ## Usage Example\n *\n * ### Accessible Navigation Example\n *\n * ```html\n * <nav aria-label=\"Main navigation\">\n * <ul style=\"display: flex; gap: 8px; list-style: none; padding: 0; margin: 0;\">\n * <li>\n * <navigation-item selected aria-current=\"page\">\n * <span slot=\"icon\" aria-hidden=\"true\">🏠</span>\n * Home\n * </navigation-item>\n * </li>\n * <li>\n * <navigation-item>\n * <span slot=\"icon\" aria-hidden=\"true\">🔍</span>\n * Search\n * </navigation-item>\n * </li>\n * <li>\n * <navigation-item>\n * <span slot=\"icon\" aria-hidden=\"true\">📁</span>\n * Files\n * </navigation-item>\n * </li>\n * <li>\n * <navigation-item iconOnly disabled aria-disabled=\"true\" tabindex=\"-1\">\n * <span slot=\"icon\" aria-hidden=\"true\">⚙️</span>\n * </navigation-item>\n * </li>\n * </ul>\n * </nav>\n * ```\n *\n * This example demonstrates a horizontal navigation bar using semantic HTML. Each `navigation-item`\n * is placed inside a list item for proper structure. The `aria-current=\"page\"` attribute marks the current\n * page, and `aria-disabled=\"true\"` with `tabindex=\"-1\"` ensures the disabled item is not focusable.\n * Icons use `aria-hidden=\"true\"` for accessibility.\n *\n * @slot icon - A slot for the icon element\n * @slot - The default slot for the label\n */\nexport default class NavigationItem extends UiElement {\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n }\n\n get disabled(): boolean {\n return isDisabled(this)\n }\n\n /**\n * When set, the navigation item is in a disabled state.\n * @attribute\n */\n @property({ reflect: true, type: Boolean })\n set disabled(value: boolean) {\n const old = isDisabled(this)\n setDisabled(this, value)\n this.requestUpdate('disabled', old)\n }\n\n /**\n * Whether the navigation item is selected.\n * @attribute\n */\n @property({ reflect: true, type: Boolean }) accessor selected = false\n /**\n * When set, the navigation item is rendered as an icon-only button.\n * The width of the button is set to 40px.\n * @attribute\n */\n @property({ reflect: true, type: Boolean }) accessor iconOnly = false\n\n /**\n * Determines when the element has an icon in the \"icon\" slot.\n */\n @state() protected accessor hasIcon = false\n\n /**\n * Sets the `_hasIcon` state property when the \"icon\" slot change event is dispatched.\n */\n protected handleIconSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement\n this.hasIcon = !!slot.assignedNodes().length\n }\n\n protected override render(): TemplateResult {\n const { pressed = false } = this\n const containerClasses = classMap({\n 'button': true,\n 'with-icon': this.hasIcon,\n 'pressed': pressed,\n 'icon-only': this.iconOnly,\n })\n return html`\n <button class=\"${containerClasses}\" id=\"button\" ?disabled=\"${this.disabled}\" aria-disabled=\"${this.disabled}\">\n <md-focus-ring part=\"focus-ring\" for=\"button\"></md-focus-ring>\n <md-ripple></md-ripple>\n ${this.renderIcon()}${when(\n this.iconOnly,\n () => nothing,\n () => html`<slot></slot>`\n )}\n </button>\n `\n }\n\n protected renderIcon(): TemplateResult {\n return html`<span role=\"presentation\" class=\"icon\"\n ><slot name=\"icon\" @slotchange=\"${this.handleIconSlotChange}\"></slot\n ></span>`\n }\n}\n"]}
1
+ {"version":3,"file":"NavigationItem.js","sourceRoot":"","sources":["../../../../../src/elements/navigation/internals/NavigationItem.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult, nothing } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { when } from 'lit/directives/when.js'\nimport { UiElement } from '../../../md/UiElement.js'\nimport { isDisabled, setDisabled } from '../../../lib/disabled.js'\n\n/**\n * NavigationItem\n *\n * An element to be placed inside a navigation bar. This component is designed for use with navigation bars and supports\n * icon-only, selected, and disabled states. It is built with accessibility and composability in mind.\n *\n * ## Accessibility\n *\n * - Uses a native `<button>` element for proper semantics and keyboard accessibility.\n * - The icon is marked with `role=\"presentation\"` to indicate it is decorative.\n * - Focus ring and ripple effects are included for visual feedback.\n *\n * ## Usage Example\n *\n * ### Accessible Navigation Example\n *\n * ```html\n * <nav aria-label=\"Main navigation\">\n * <ul style=\"display: flex; gap: 8px; list-style: none; padding: 0; margin: 0;\">\n * <li>\n * <navigation-item selected aria-current=\"page\">\n * <span slot=\"icon\" aria-hidden=\"true\">🏠</span>\n * Home\n * </navigation-item>\n * </li>\n * <li>\n * <navigation-item>\n * <span slot=\"icon\" aria-hidden=\"true\">🔍</span>\n * Search\n * </navigation-item>\n * </li>\n * <li>\n * <navigation-item>\n * <span slot=\"icon\" aria-hidden=\"true\">📁</span>\n * Files\n * </navigation-item>\n * </li>\n * <li>\n * <navigation-item iconOnly disabled aria-disabled=\"true\" tabindex=\"-1\">\n * <span slot=\"icon\" aria-hidden=\"true\">⚙️</span>\n * </navigation-item>\n * </li>\n * </ul>\n * </nav>\n * ```\n *\n * This example demonstrates a horizontal navigation bar using semantic HTML. Each `navigation-item`\n * is placed inside a list item for proper structure. The `aria-current=\"page\"` attribute marks the current\n * page, and `aria-disabled=\"true\"` with `tabindex=\"-1\"` ensures the disabled item is not focusable.\n * Icons use `aria-hidden=\"true\"` for accessibility.\n *\n * @slot icon - A slot for the icon element\n * @slot - The default slot for the label\n */\nexport default class NavigationItem extends UiElement {\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n }\n\n get disabled(): boolean {\n return isDisabled(this)\n }\n\n /**\n * When set, the navigation item is in a disabled state.\n * @attribute\n */\n @property({ reflect: true, type: Boolean })\n set disabled(value: boolean) {\n const old = isDisabled(this)\n setDisabled(this, value)\n this.requestUpdate('disabled', old)\n }\n\n /**\n * Whether the navigation item is selected.\n * @attribute\n */\n @property({ reflect: true, type: Boolean }) accessor selected = false\n /**\n * When set, the navigation item is rendered as an icon-only button.\n * The width of the button is set to 40px.\n * @attribute\n */\n @property({ reflect: true, type: Boolean }) accessor iconOnly = false\n /**\n * The reference of the navigation item to the target.\n * @attribute\n */\n @property({ reflect: true, type: String }) accessor href: string | undefined\n\n /**\n * Determines when the element has an icon in the \"icon\" slot.\n */\n @state() protected accessor hasIcon = false\n\n /**\n * Sets the `_hasIcon` state property when the \"icon\" slot change event is dispatched.\n */\n protected handleIconSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement\n this.hasIcon = !!slot.assignedNodes().length\n }\n\n protected override render(): TemplateResult {\n const { pressed = false } = this\n const containerClasses = classMap({\n 'button': true,\n 'with-icon': this.hasIcon,\n 'pressed': pressed,\n 'icon-only': this.iconOnly,\n })\n return html`\n <button class=\"${containerClasses}\" id=\"button\" ?disabled=\"${this.disabled}\" aria-disabled=\"${this.disabled}\">\n <md-focus-ring part=\"focus-ring\" for=\"button\"></md-focus-ring>\n <md-ripple></md-ripple>\n ${this.renderIcon()}${when(\n this.iconOnly,\n () => nothing,\n () => html`<slot></slot>`\n )}\n </button>\n `\n }\n\n protected renderIcon(): TemplateResult {\n return html`<span role=\"presentation\" class=\"icon\"\n ><slot name=\"icon\" @slotchange=\"${this.handleIconSlotChange}\"></slot\n ></span>`\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api-client/ui",
3
- "version": "0.5.33",
3
+ "version": "0.5.34",
4
4
  "description": "Internal UI component library for the API Client ecosystem.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "build/src/index.js",
@@ -34,7 +34,10 @@ function parseParams(pattern: string, uri: string): Record<string, string | stri
34
34
  const result: Record<string, string | string[]> = {}
35
35
  if (groups) {
36
36
  Object.keys(groups).forEach((key) => {
37
- let value = groups[key] as string
37
+ let value = groups[key] as string | undefined
38
+ if (value === undefined) {
39
+ return
40
+ }
38
41
  if (value[0] === '/') {
39
42
  value = value.substring(1)
40
43
  }
@@ -91,6 +91,11 @@ export default class NavigationItem extends UiElement {
91
91
  * @attribute
92
92
  */
93
93
  @property({ reflect: true, type: Boolean }) accessor iconOnly = false
94
+ /**
95
+ * The reference of the navigation item to the target.
96
+ * @attribute
97
+ */
98
+ @property({ reflect: true, type: String }) accessor href: string | undefined
94
99
 
95
100
  /**
96
101
  * Determines when the element has an icon in the "icon" slot.