@duskmoon-dev/el-bottom-navigation 0.5.0 → 0.6.0

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.
@@ -2,11 +2,11 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/el-dm-bottom-navigation.ts", "../../src/index.ts", "../../src/register.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * DuskMoon Bottom Navigation Element\n *\n * A mobile-first bottom navigation bar component with nav items and icons.\n * Fixed position at the bottom of the viewport for easy thumb access.\n *\n * @element el-dm-bottom-navigation\n *\n * @attr {Array} items - Array of navigation items with { value, label, icon? } structure\n * @attr {string} value - Currently selected item value\n * @attr {string} color - Color theme: primary, secondary, or custom color\n *\n * @slot - Default slot for custom nav items (el-dm-bottom-navigation-item)\n *\n * @csspart container - The navigation container\n * @csspart item - Individual navigation item\n * @csspart icon - Item icon container\n * @csspart label - Item label\n *\n * @fires change - Fired when selection changes, detail: { value, item }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\n/**\n * Navigation item structure\n */\nexport interface BottomNavigationItem {\n /** Unique identifier for the item */\n value: string;\n /** Display label */\n label: string;\n /** Icon HTML or SVG string */\n icon?: string;\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Optional href for link behavior */\n href?: string;\n}\n\nconst styles = css`\n :host {\n --bottom-nav-height: 56px;\n --bottom-nav-bg: var(--color-surface, #ffffff);\n --bottom-nav-border: var(--color-border, #e5e7eb);\n --bottom-nav-text: var(--color-text-secondary, #6b7280);\n --bottom-nav-text-active: var(--color-primary, #3b82f6);\n --bottom-nav-icon-size: 24px;\n --bottom-nav-label-size: 0.75rem;\n --bottom-nav-shadow: 0 -1px 3px rgba(0, 0, 0, 0.1);\n\n display: block;\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n :host([position='static']) {\n position: static;\n }\n\n :host([position='sticky']) {\n position: sticky;\n }\n\n .bottom-nav {\n display: flex;\n align-items: center;\n justify-content: space-around;\n height: var(--bottom-nav-height);\n background: var(--bottom-nav-bg);\n border-top: 1px solid var(--bottom-nav-border);\n box-shadow: var(--bottom-nav-shadow);\n padding: 0;\n margin: 0;\n /* Safe area for iOS devices */\n padding-bottom: env(safe-area-inset-bottom, 0);\n }\n\n .nav-item {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n padding: 6px 12px;\n min-width: 0;\n max-width: 168px;\n height: 100%;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--bottom-nav-text);\n text-decoration: none;\n transition:\n color 0.2s ease,\n transform 0.1s ease;\n -webkit-tap-highlight-color: transparent;\n user-select: none;\n }\n\n .nav-item:focus {\n outline: none;\n }\n\n .nav-item:focus-visible {\n outline: 2px solid var(--bottom-nav-text-active);\n outline-offset: -2px;\n border-radius: 4px;\n }\n\n .nav-item:active:not([disabled]) {\n transform: scale(0.95);\n }\n\n .nav-item[aria-selected='true'],\n .nav-item.active {\n color: var(--bottom-nav-text-active);\n }\n\n .nav-item[disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .nav-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--bottom-nav-icon-size);\n height: var(--bottom-nav-icon-size);\n flex-shrink: 0;\n }\n\n .nav-icon ::slotted(*),\n .nav-icon svg,\n .nav-icon img {\n width: 100%;\n height: 100%;\n }\n\n .nav-label {\n font-size: var(--bottom-nav-label-size);\n font-weight: 500;\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n\n /* Hide labels on very small screens */\n @media (max-width: 320px) {\n .nav-label {\n display: none;\n }\n\n .nav-icon {\n width: 28px;\n height: 28px;\n }\n }\n\n /* Color variants */\n :host([color='secondary']) {\n --bottom-nav-text-active: var(--color-secondary, #8b5cf6);\n }\n\n :host([color='success']) {\n --bottom-nav-text-active: var(--color-success, #22c55e);\n }\n\n :host([color='warning']) {\n --bottom-nav-text-active: var(--color-warning, #f59e0b);\n }\n\n :host([color='error']) {\n --bottom-nav-text-active: var(--color-error, #ef4444);\n }\n\n /* Badge indicator for items */\n .nav-item-badge {\n position: absolute;\n top: 4px;\n right: calc(50% - 18px);\n min-width: 8px;\n height: 8px;\n background: var(--color-error, #ef4444);\n border-radius: 50%;\n }\n\n .nav-item-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n justify-content: center;\n max-width: 168px;\n }\n\n /* Slot for custom items */\n ::slotted(el-dm-bottom-navigation-item) {\n flex: 1;\n }\n`;\n\nexport class ElDmBottomNavigation extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false, default: [] },\n value: { type: String, reflect: true },\n color: { type: String, reflect: true, default: 'primary' },\n position: { type: String, reflect: true, default: 'fixed' },\n };\n\n /** Array of navigation items */\n declare items: BottomNavigationItem[];\n\n /** Currently selected item value */\n declare value: string;\n\n /** Color theme */\n declare color: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | string;\n\n /** Position of the navigation bar */\n declare position: 'fixed' | 'static' | 'sticky';\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n this.addEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('click', this._handleClick.bind(this));\n this.removeEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n /**\n * Handle click events on nav items\n */\n private _handleClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n const navItem = target.closest('[data-value]') as HTMLElement | null;\n\n if (!navItem || navItem.hasAttribute('disabled')) {\n return;\n }\n\n const value = navItem.dataset.value;\n if (value && value !== this.value) {\n const item = this.items.find((i) => i.value === value);\n this.value = value;\n this.emit('change', { value, item });\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n private _handleKeydown(event: KeyboardEvent): void {\n const target = event.target as HTMLElement;\n if (!target.classList.contains('nav-item')) return;\n\n const items = Array.from(this.shadowRoot.querySelectorAll('.nav-item:not([disabled])'));\n const currentIndex = items.indexOf(target);\n\n let nextIndex = -1;\n\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault();\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n break;\n case 'Home':\n event.preventDefault();\n nextIndex = 0;\n break;\n case 'End':\n event.preventDefault();\n nextIndex = items.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n target.click();\n return;\n }\n\n if (nextIndex >= 0 && items[nextIndex]) {\n (items[nextIndex] as HTMLElement).focus();\n }\n }\n\n /**\n * Render a single navigation item\n */\n private _renderItem(item: BottomNavigationItem, index: number): string {\n const isSelected = item.value === this.value;\n const Tag = item.href ? 'a' : 'button';\n const hrefAttr = item.href ? `href=\"${item.href}\"` : '';\n const disabledAttr = item.disabled ? 'disabled' : '';\n const typeAttr = Tag === 'button' ? 'type=\"button\"' : '';\n\n return `\n <div class=\"nav-item-wrapper\">\n <${Tag}\n class=\"nav-item\"\n part=\"item\"\n role=\"tab\"\n tabindex=\"${item.disabled ? '-1' : '0'}\"\n aria-selected=\"${isSelected}\"\n data-value=\"${item.value}\"\n ${hrefAttr}\n ${disabledAttr}\n ${typeAttr}\n >\n ${\n item.icon\n ? `\n <span class=\"nav-icon\" part=\"icon\">\n ${item.icon}\n </span>\n `\n : ''\n }\n <span class=\"nav-label\" part=\"label\">${item.label}</span>\n </${Tag}>\n </div>\n `;\n }\n\n render(): string {\n const hasItems = this.items && this.items.length > 0;\n\n return `\n <nav class=\"bottom-nav\" part=\"container\" role=\"tablist\" aria-label=\"Bottom navigation\">\n ${hasItems ? this.items.map((item, i) => this._renderItem(item, i)).join('') : '<slot></slot>'}\n </nav>\n `;\n }\n}\n",
5
+ "/**\n * DuskMoon Bottom Navigation Element\n *\n * A mobile-first bottom navigation bar component with nav items and icons.\n * Fixed position at the bottom of the viewport for easy thumb access.\n *\n * @element el-dm-bottom-navigation\n *\n * @attr {Array} items - Array of navigation items with { value, label, icon? } structure\n * @attr {string} value - Currently selected item value\n * @attr {string} color - Color theme: primary, secondary, or custom color\n *\n * @slot - Default slot for custom nav items (el-dm-bottom-navigation-item)\n *\n * @csspart container - The navigation container\n * @csspart item - Individual navigation item\n * @csspart icon - Item icon container\n * @csspart label - Item label\n *\n * @fires change - Fired when selection changes, detail: { value, item }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as bottomNavCSS } from '@duskmoon-dev/core/components/bottom-navigation';\n\n/**\n * Navigation item structure\n */\nexport interface BottomNavigationItem {\n /** Unique identifier for the item */\n value: string;\n /** Display label */\n label: string;\n /** Icon HTML or SVG string */\n icon?: string;\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Optional href for link behavior */\n href?: string;\n}\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = bottomNavCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n --bottom-nav-height: 56px;\n --bottom-nav-bg: var(--color-surface, #ffffff);\n --bottom-nav-border: var(--color-border, #e5e7eb);\n --bottom-nav-text: var(--color-text-secondary, #6b7280);\n --bottom-nav-text-active: var(--color-primary, #3b82f6);\n --bottom-nav-icon-size: 24px;\n --bottom-nav-label-size: 0.75rem;\n --bottom-nav-shadow: 0 -1px 3px rgba(0, 0, 0, 0.1);\n\n display: block;\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n :host([position='static']) {\n position: static;\n }\n\n :host([position='sticky']) {\n position: sticky;\n }\n\n /* Import core bottom-navigation styles */\n ${coreStyles}\n\n /* Override core's fixed positioning — :host handles it */\n .bottom-nav {\n position: static;\n height: var(--bottom-nav-height);\n min-height: auto;\n background: var(--bottom-nav-bg);\n border-top: 1px solid var(--bottom-nav-border);\n box-shadow: var(--bottom-nav-shadow);\n }\n\n /* Override core item styles with our custom properties */\n .bottom-nav-item {\n gap: 2px;\n padding: 6px 12px;\n min-width: 0;\n max-width: 168px;\n height: 100%;\n color: var(--bottom-nav-text);\n transition:\n color 0.2s ease,\n transform 0.1s ease;\n -webkit-tap-highlight-color: transparent;\n user-select: none;\n }\n\n .bottom-nav-item:focus {\n outline: none;\n }\n\n .bottom-nav-item:focus-visible {\n outline: 2px solid var(--bottom-nav-text-active);\n outline-offset: -2px;\n border-radius: 4px;\n }\n\n .bottom-nav-item:active:not([disabled]) {\n transform: scale(0.95);\n }\n\n .bottom-nav-item[aria-selected='true'],\n .bottom-nav-item.active {\n color: var(--bottom-nav-text-active);\n }\n\n .bottom-nav-item[disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .bottom-nav-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--bottom-nav-icon-size);\n height: var(--bottom-nav-icon-size);\n flex-shrink: 0;\n }\n\n .bottom-nav-icon ::slotted(*),\n .bottom-nav-icon svg,\n .bottom-nav-icon img {\n width: 100%;\n height: 100%;\n }\n\n .bottom-nav-label {\n font-size: var(--bottom-nav-label-size);\n font-weight: 500;\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n\n /* Hide labels on very small screens */\n @media (max-width: 320px) {\n .bottom-nav-label {\n display: none;\n }\n\n .bottom-nav-icon {\n width: 28px;\n height: 28px;\n }\n }\n\n /* Color variants */\n :host([color='secondary']) {\n --bottom-nav-text-active: var(--color-secondary, #8b5cf6);\n }\n\n :host([color='success']) {\n --bottom-nav-text-active: var(--color-success, #22c55e);\n }\n\n :host([color='warning']) {\n --bottom-nav-text-active: var(--color-warning, #f59e0b);\n }\n\n :host([color='error']) {\n --bottom-nav-text-active: var(--color-error, #ef4444);\n }\n\n /* Badge indicator for items */\n .bottom-nav-badge {\n position: absolute;\n top: 4px;\n right: calc(50% - 18px);\n min-width: 8px;\n height: 8px;\n background: var(--color-error, #ef4444);\n border-radius: 50%;\n }\n\n .bottom-nav-item-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n justify-content: center;\n max-width: 168px;\n }\n\n /* Slot for custom items */\n ::slotted(el-dm-bottom-navigation-item) {\n flex: 1;\n }\n`;\n\nexport class ElDmBottomNavigation extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false, default: [] },\n value: { type: String, reflect: true },\n color: { type: String, reflect: true, default: 'primary' },\n position: { type: String, reflect: true, default: 'fixed' },\n };\n\n /** Array of navigation items */\n declare items: BottomNavigationItem[];\n\n /** Currently selected item value */\n declare value: string;\n\n /** Color theme */\n declare color: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | string;\n\n /** Position of the navigation bar */\n declare position: 'fixed' | 'static' | 'sticky';\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n this.addEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('click', this._handleClick.bind(this));\n this.removeEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n /**\n * Handle click events on nav items\n */\n private _handleClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n const navItem = target.closest('[data-value]') as HTMLElement | null;\n\n if (!navItem || navItem.hasAttribute('disabled')) {\n return;\n }\n\n const value = navItem.dataset.value;\n if (value && value !== this.value) {\n const item = this.items.find((i) => i.value === value);\n this.value = value;\n this.emit('change', { value, item });\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n private _handleKeydown(event: KeyboardEvent): void {\n const target = event.target as HTMLElement;\n if (!target.classList.contains('bottom-nav-item')) return;\n\n const items = Array.from(this.shadowRoot.querySelectorAll('.bottom-nav-item:not([disabled])'));\n const currentIndex = items.indexOf(target);\n\n let nextIndex = -1;\n\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault();\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n break;\n case 'Home':\n event.preventDefault();\n nextIndex = 0;\n break;\n case 'End':\n event.preventDefault();\n nextIndex = items.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n target.click();\n return;\n }\n\n if (nextIndex >= 0 && items[nextIndex]) {\n (items[nextIndex] as HTMLElement).focus();\n }\n }\n\n /**\n * Render a single navigation item\n */\n private _renderItem(item: BottomNavigationItem): string {\n const isSelected = item.value === this.value;\n const Tag = item.href ? 'a' : 'button';\n const hrefAttr = item.href ? `href=\"${item.href}\"` : '';\n const disabledAttr = item.disabled ? 'disabled' : '';\n const typeAttr = Tag === 'button' ? 'type=\"button\"' : '';\n\n return `\n <div class=\"bottom-nav-item-wrapper\">\n <${Tag}\n class=\"bottom-nav-item\"\n part=\"item\"\n role=\"tab\"\n tabindex=\"${item.disabled ? '-1' : '0'}\"\n aria-selected=\"${isSelected}\"\n data-value=\"${item.value}\"\n ${hrefAttr}\n ${disabledAttr}\n ${typeAttr}\n >\n ${\n item.icon\n ? `\n <span class=\"bottom-nav-icon\" part=\"icon\">\n ${item.icon}\n </span>\n `\n : ''\n }\n <span class=\"bottom-nav-label\" part=\"label\">${item.label}</span>\n </${Tag}>\n </div>\n `;\n }\n\n render(): string {\n const hasItems = this.items && this.items.length > 0;\n\n return `\n <nav class=\"bottom-nav\" part=\"container\" role=\"tablist\" aria-label=\"Bottom navigation\">\n ${hasItems ? this.items.map((item) => this._renderItem(item)).join('') : '<slot></slot>'}\n </nav>\n `;\n }\n}\n",
6
6
  "/**\n * @duskmoon-dev/el-bottom-navigation\n *\n * DuskMoon Bottom Navigation custom element\n */\n\nimport { ElDmBottomNavigation } from './el-dm-bottom-navigation.js';\n\nexport { ElDmBottomNavigation };\nexport type { BottomNavigationItem } from './el-dm-bottom-navigation.js';\n\n/**\n * Register the el-dm-bottom-navigation custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-bottom-navigation';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-bottom-navigation')) {\n customElements.define('el-dm-bottom-navigation', ElDmBottomNavigation);\n }\n}\n",
7
7
  "/**\n * Auto-register el-dm-bottom-navigation custom element\n *\n * @example\n * ```ts\n * import '@duskmoon-dev/el-bottom-navigation/register';\n *\n * // Now you can use <el-dm-bottom-navigation> in HTML\n * ```\n */\nimport { register } from './index.js';\n\nregister();\n"
8
8
  ],
9
- "mappings": "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",
10
- "debugId": "D05C25A3A10DC4D464756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "3140AC23DA61283D64756E2164756E21",
11
11
  "names": []
12
12
  }
package/dist/esm/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  // src/el-dm-bottom-navigation.ts
2
- import { BaseElement, css } from "@duskmoon-dev/el-core";
2
+ import { BaseElement, css } from "@duskmoon-dev/el-base";
3
+ import { css as bottomNavCSS } from "@duskmoon-dev/core/components/bottom-navigation";
4
+ var coreStyles = bottomNavCSS.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
3
5
  var styles = css`
4
6
  :host {
5
7
  --bottom-nav-height: 56px;
@@ -31,36 +33,27 @@ var styles = css`
31
33
  position: sticky;
32
34
  }
33
35
 
36
+ /* Import core bottom-navigation styles */
37
+ ${coreStyles}
38
+
39
+ /* Override core's fixed positioning — :host handles it */
34
40
  .bottom-nav {
35
- display: flex;
36
- align-items: center;
37
- justify-content: space-around;
41
+ position: static;
38
42
  height: var(--bottom-nav-height);
43
+ min-height: auto;
39
44
  background: var(--bottom-nav-bg);
40
45
  border-top: 1px solid var(--bottom-nav-border);
41
46
  box-shadow: var(--bottom-nav-shadow);
42
- padding: 0;
43
- margin: 0;
44
- /* Safe area for iOS devices */
45
- padding-bottom: env(safe-area-inset-bottom, 0);
46
47
  }
47
48
 
48
- .nav-item {
49
- flex: 1;
50
- display: flex;
51
- flex-direction: column;
52
- align-items: center;
53
- justify-content: center;
49
+ /* Override core item styles with our custom properties */
50
+ .bottom-nav-item {
54
51
  gap: 2px;
55
52
  padding: 6px 12px;
56
53
  min-width: 0;
57
54
  max-width: 168px;
58
55
  height: 100%;
59
- background: transparent;
60
- border: none;
61
- cursor: pointer;
62
56
  color: var(--bottom-nav-text);
63
- text-decoration: none;
64
57
  transition:
65
58
  color 0.2s ease,
66
59
  transform 0.1s ease;
@@ -68,32 +61,32 @@ var styles = css`
68
61
  user-select: none;
69
62
  }
70
63
 
71
- .nav-item:focus {
64
+ .bottom-nav-item:focus {
72
65
  outline: none;
73
66
  }
74
67
 
75
- .nav-item:focus-visible {
68
+ .bottom-nav-item:focus-visible {
76
69
  outline: 2px solid var(--bottom-nav-text-active);
77
70
  outline-offset: -2px;
78
71
  border-radius: 4px;
79
72
  }
80
73
 
81
- .nav-item:active:not([disabled]) {
74
+ .bottom-nav-item:active:not([disabled]) {
82
75
  transform: scale(0.95);
83
76
  }
84
77
 
85
- .nav-item[aria-selected='true'],
86
- .nav-item.active {
78
+ .bottom-nav-item[aria-selected='true'],
79
+ .bottom-nav-item.active {
87
80
  color: var(--bottom-nav-text-active);
88
81
  }
89
82
 
90
- .nav-item[disabled] {
83
+ .bottom-nav-item[disabled] {
91
84
  opacity: 0.5;
92
85
  cursor: not-allowed;
93
86
  pointer-events: none;
94
87
  }
95
88
 
96
- .nav-icon {
89
+ .bottom-nav-icon {
97
90
  display: flex;
98
91
  align-items: center;
99
92
  justify-content: center;
@@ -102,14 +95,14 @@ var styles = css`
102
95
  flex-shrink: 0;
103
96
  }
104
97
 
105
- .nav-icon ::slotted(*),
106
- .nav-icon svg,
107
- .nav-icon img {
98
+ .bottom-nav-icon ::slotted(*),
99
+ .bottom-nav-icon svg,
100
+ .bottom-nav-icon img {
108
101
  width: 100%;
109
102
  height: 100%;
110
103
  }
111
104
 
112
- .nav-label {
105
+ .bottom-nav-label {
113
106
  font-size: var(--bottom-nav-label-size);
114
107
  font-weight: 500;
115
108
  line-height: 1.2;
@@ -121,11 +114,11 @@ var styles = css`
121
114
 
122
115
  /* Hide labels on very small screens */
123
116
  @media (max-width: 320px) {
124
- .nav-label {
117
+ .bottom-nav-label {
125
118
  display: none;
126
119
  }
127
120
 
128
- .nav-icon {
121
+ .bottom-nav-icon {
129
122
  width: 28px;
130
123
  height: 28px;
131
124
  }
@@ -149,7 +142,7 @@ var styles = css`
149
142
  }
150
143
 
151
144
  /* Badge indicator for items */
152
- .nav-item-badge {
145
+ .bottom-nav-badge {
153
146
  position: absolute;
154
147
  top: 4px;
155
148
  right: calc(50% - 18px);
@@ -159,7 +152,7 @@ var styles = css`
159
152
  border-radius: 50%;
160
153
  }
161
154
 
162
- .nav-item-wrapper {
155
+ .bottom-nav-item-wrapper {
163
156
  position: relative;
164
157
  flex: 1;
165
158
  display: flex;
@@ -209,9 +202,9 @@ class ElDmBottomNavigation extends BaseElement {
209
202
  }
210
203
  _handleKeydown(event) {
211
204
  const target = event.target;
212
- if (!target.classList.contains("nav-item"))
205
+ if (!target.classList.contains("bottom-nav-item"))
213
206
  return;
214
- const items = Array.from(this.shadowRoot.querySelectorAll(".nav-item:not([disabled])"));
207
+ const items = Array.from(this.shadowRoot.querySelectorAll(".bottom-nav-item:not([disabled])"));
215
208
  const currentIndex = items.indexOf(target);
216
209
  let nextIndex = -1;
217
210
  switch (event.key) {
@@ -243,16 +236,16 @@ class ElDmBottomNavigation extends BaseElement {
243
236
  items[nextIndex].focus();
244
237
  }
245
238
  }
246
- _renderItem(item, index) {
239
+ _renderItem(item) {
247
240
  const isSelected = item.value === this.value;
248
241
  const Tag = item.href ? "a" : "button";
249
242
  const hrefAttr = item.href ? `href="${item.href}"` : "";
250
243
  const disabledAttr = item.disabled ? "disabled" : "";
251
244
  const typeAttr = Tag === "button" ? 'type="button"' : "";
252
245
  return `
253
- <div class="nav-item-wrapper">
246
+ <div class="bottom-nav-item-wrapper">
254
247
  <${Tag}
255
- class="nav-item"
248
+ class="bottom-nav-item"
256
249
  part="item"
257
250
  role="tab"
258
251
  tabindex="${item.disabled ? "-1" : "0"}"
@@ -263,11 +256,11 @@ class ElDmBottomNavigation extends BaseElement {
263
256
  ${typeAttr}
264
257
  >
265
258
  ${item.icon ? `
266
- <span class="nav-icon" part="icon">
259
+ <span class="bottom-nav-icon" part="icon">
267
260
  ${item.icon}
268
261
  </span>
269
262
  ` : ""}
270
- <span class="nav-label" part="label">${item.label}</span>
263
+ <span class="bottom-nav-label" part="label">${item.label}</span>
271
264
  </${Tag}>
272
265
  </div>
273
266
  `;
@@ -276,7 +269,7 @@ class ElDmBottomNavigation extends BaseElement {
276
269
  const hasItems = this.items && this.items.length > 0;
277
270
  return `
278
271
  <nav class="bottom-nav" part="container" role="tablist" aria-label="Bottom navigation">
279
- ${hasItems ? this.items.map((item, i) => this._renderItem(item, i)).join("") : "<slot></slot>"}
272
+ ${hasItems ? this.items.map((item) => this._renderItem(item)).join("") : "<slot></slot>"}
280
273
  </nav>
281
274
  `;
282
275
  }
@@ -293,5 +286,5 @@ export {
293
286
  ElDmBottomNavigation
294
287
  };
295
288
 
296
- //# debugId=FE83E40F6863EAC564756E2164756E21
289
+ //# debugId=FCA74FDCAFA9033464756E2164756E21
297
290
  //# sourceMappingURL=index.js.map
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/el-dm-bottom-navigation.ts", "../../src/index.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * DuskMoon Bottom Navigation Element\n *\n * A mobile-first bottom navigation bar component with nav items and icons.\n * Fixed position at the bottom of the viewport for easy thumb access.\n *\n * @element el-dm-bottom-navigation\n *\n * @attr {Array} items - Array of navigation items with { value, label, icon? } structure\n * @attr {string} value - Currently selected item value\n * @attr {string} color - Color theme: primary, secondary, or custom color\n *\n * @slot - Default slot for custom nav items (el-dm-bottom-navigation-item)\n *\n * @csspart container - The navigation container\n * @csspart item - Individual navigation item\n * @csspart icon - Item icon container\n * @csspart label - Item label\n *\n * @fires change - Fired when selection changes, detail: { value, item }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\n/**\n * Navigation item structure\n */\nexport interface BottomNavigationItem {\n /** Unique identifier for the item */\n value: string;\n /** Display label */\n label: string;\n /** Icon HTML or SVG string */\n icon?: string;\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Optional href for link behavior */\n href?: string;\n}\n\nconst styles = css`\n :host {\n --bottom-nav-height: 56px;\n --bottom-nav-bg: var(--color-surface, #ffffff);\n --bottom-nav-border: var(--color-border, #e5e7eb);\n --bottom-nav-text: var(--color-text-secondary, #6b7280);\n --bottom-nav-text-active: var(--color-primary, #3b82f6);\n --bottom-nav-icon-size: 24px;\n --bottom-nav-label-size: 0.75rem;\n --bottom-nav-shadow: 0 -1px 3px rgba(0, 0, 0, 0.1);\n\n display: block;\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n :host([position='static']) {\n position: static;\n }\n\n :host([position='sticky']) {\n position: sticky;\n }\n\n .bottom-nav {\n display: flex;\n align-items: center;\n justify-content: space-around;\n height: var(--bottom-nav-height);\n background: var(--bottom-nav-bg);\n border-top: 1px solid var(--bottom-nav-border);\n box-shadow: var(--bottom-nav-shadow);\n padding: 0;\n margin: 0;\n /* Safe area for iOS devices */\n padding-bottom: env(safe-area-inset-bottom, 0);\n }\n\n .nav-item {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n padding: 6px 12px;\n min-width: 0;\n max-width: 168px;\n height: 100%;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--bottom-nav-text);\n text-decoration: none;\n transition:\n color 0.2s ease,\n transform 0.1s ease;\n -webkit-tap-highlight-color: transparent;\n user-select: none;\n }\n\n .nav-item:focus {\n outline: none;\n }\n\n .nav-item:focus-visible {\n outline: 2px solid var(--bottom-nav-text-active);\n outline-offset: -2px;\n border-radius: 4px;\n }\n\n .nav-item:active:not([disabled]) {\n transform: scale(0.95);\n }\n\n .nav-item[aria-selected='true'],\n .nav-item.active {\n color: var(--bottom-nav-text-active);\n }\n\n .nav-item[disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .nav-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--bottom-nav-icon-size);\n height: var(--bottom-nav-icon-size);\n flex-shrink: 0;\n }\n\n .nav-icon ::slotted(*),\n .nav-icon svg,\n .nav-icon img {\n width: 100%;\n height: 100%;\n }\n\n .nav-label {\n font-size: var(--bottom-nav-label-size);\n font-weight: 500;\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n\n /* Hide labels on very small screens */\n @media (max-width: 320px) {\n .nav-label {\n display: none;\n }\n\n .nav-icon {\n width: 28px;\n height: 28px;\n }\n }\n\n /* Color variants */\n :host([color='secondary']) {\n --bottom-nav-text-active: var(--color-secondary, #8b5cf6);\n }\n\n :host([color='success']) {\n --bottom-nav-text-active: var(--color-success, #22c55e);\n }\n\n :host([color='warning']) {\n --bottom-nav-text-active: var(--color-warning, #f59e0b);\n }\n\n :host([color='error']) {\n --bottom-nav-text-active: var(--color-error, #ef4444);\n }\n\n /* Badge indicator for items */\n .nav-item-badge {\n position: absolute;\n top: 4px;\n right: calc(50% - 18px);\n min-width: 8px;\n height: 8px;\n background: var(--color-error, #ef4444);\n border-radius: 50%;\n }\n\n .nav-item-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n justify-content: center;\n max-width: 168px;\n }\n\n /* Slot for custom items */\n ::slotted(el-dm-bottom-navigation-item) {\n flex: 1;\n }\n`;\n\nexport class ElDmBottomNavigation extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false, default: [] },\n value: { type: String, reflect: true },\n color: { type: String, reflect: true, default: 'primary' },\n position: { type: String, reflect: true, default: 'fixed' },\n };\n\n /** Array of navigation items */\n declare items: BottomNavigationItem[];\n\n /** Currently selected item value */\n declare value: string;\n\n /** Color theme */\n declare color: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | string;\n\n /** Position of the navigation bar */\n declare position: 'fixed' | 'static' | 'sticky';\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n this.addEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('click', this._handleClick.bind(this));\n this.removeEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n /**\n * Handle click events on nav items\n */\n private _handleClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n const navItem = target.closest('[data-value]') as HTMLElement | null;\n\n if (!navItem || navItem.hasAttribute('disabled')) {\n return;\n }\n\n const value = navItem.dataset.value;\n if (value && value !== this.value) {\n const item = this.items.find((i) => i.value === value);\n this.value = value;\n this.emit('change', { value, item });\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n private _handleKeydown(event: KeyboardEvent): void {\n const target = event.target as HTMLElement;\n if (!target.classList.contains('nav-item')) return;\n\n const items = Array.from(this.shadowRoot.querySelectorAll('.nav-item:not([disabled])'));\n const currentIndex = items.indexOf(target);\n\n let nextIndex = -1;\n\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault();\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n break;\n case 'Home':\n event.preventDefault();\n nextIndex = 0;\n break;\n case 'End':\n event.preventDefault();\n nextIndex = items.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n target.click();\n return;\n }\n\n if (nextIndex >= 0 && items[nextIndex]) {\n (items[nextIndex] as HTMLElement).focus();\n }\n }\n\n /**\n * Render a single navigation item\n */\n private _renderItem(item: BottomNavigationItem, index: number): string {\n const isSelected = item.value === this.value;\n const Tag = item.href ? 'a' : 'button';\n const hrefAttr = item.href ? `href=\"${item.href}\"` : '';\n const disabledAttr = item.disabled ? 'disabled' : '';\n const typeAttr = Tag === 'button' ? 'type=\"button\"' : '';\n\n return `\n <div class=\"nav-item-wrapper\">\n <${Tag}\n class=\"nav-item\"\n part=\"item\"\n role=\"tab\"\n tabindex=\"${item.disabled ? '-1' : '0'}\"\n aria-selected=\"${isSelected}\"\n data-value=\"${item.value}\"\n ${hrefAttr}\n ${disabledAttr}\n ${typeAttr}\n >\n ${\n item.icon\n ? `\n <span class=\"nav-icon\" part=\"icon\">\n ${item.icon}\n </span>\n `\n : ''\n }\n <span class=\"nav-label\" part=\"label\">${item.label}</span>\n </${Tag}>\n </div>\n `;\n }\n\n render(): string {\n const hasItems = this.items && this.items.length > 0;\n\n return `\n <nav class=\"bottom-nav\" part=\"container\" role=\"tablist\" aria-label=\"Bottom navigation\">\n ${hasItems ? this.items.map((item, i) => this._renderItem(item, i)).join('') : '<slot></slot>'}\n </nav>\n `;\n }\n}\n",
5
+ "/**\n * DuskMoon Bottom Navigation Element\n *\n * A mobile-first bottom navigation bar component with nav items and icons.\n * Fixed position at the bottom of the viewport for easy thumb access.\n *\n * @element el-dm-bottom-navigation\n *\n * @attr {Array} items - Array of navigation items with { value, label, icon? } structure\n * @attr {string} value - Currently selected item value\n * @attr {string} color - Color theme: primary, secondary, or custom color\n *\n * @slot - Default slot for custom nav items (el-dm-bottom-navigation-item)\n *\n * @csspart container - The navigation container\n * @csspart item - Individual navigation item\n * @csspart icon - Item icon container\n * @csspart label - Item label\n *\n * @fires change - Fired when selection changes, detail: { value, item }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as bottomNavCSS } from '@duskmoon-dev/core/components/bottom-navigation';\n\n/**\n * Navigation item structure\n */\nexport interface BottomNavigationItem {\n /** Unique identifier for the item */\n value: string;\n /** Display label */\n label: string;\n /** Icon HTML or SVG string */\n icon?: string;\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Optional href for link behavior */\n href?: string;\n}\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = bottomNavCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n --bottom-nav-height: 56px;\n --bottom-nav-bg: var(--color-surface, #ffffff);\n --bottom-nav-border: var(--color-border, #e5e7eb);\n --bottom-nav-text: var(--color-text-secondary, #6b7280);\n --bottom-nav-text-active: var(--color-primary, #3b82f6);\n --bottom-nav-icon-size: 24px;\n --bottom-nav-label-size: 0.75rem;\n --bottom-nav-shadow: 0 -1px 3px rgba(0, 0, 0, 0.1);\n\n display: block;\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n :host([position='static']) {\n position: static;\n }\n\n :host([position='sticky']) {\n position: sticky;\n }\n\n /* Import core bottom-navigation styles */\n ${coreStyles}\n\n /* Override core's fixed positioning — :host handles it */\n .bottom-nav {\n position: static;\n height: var(--bottom-nav-height);\n min-height: auto;\n background: var(--bottom-nav-bg);\n border-top: 1px solid var(--bottom-nav-border);\n box-shadow: var(--bottom-nav-shadow);\n }\n\n /* Override core item styles with our custom properties */\n .bottom-nav-item {\n gap: 2px;\n padding: 6px 12px;\n min-width: 0;\n max-width: 168px;\n height: 100%;\n color: var(--bottom-nav-text);\n transition:\n color 0.2s ease,\n transform 0.1s ease;\n -webkit-tap-highlight-color: transparent;\n user-select: none;\n }\n\n .bottom-nav-item:focus {\n outline: none;\n }\n\n .bottom-nav-item:focus-visible {\n outline: 2px solid var(--bottom-nav-text-active);\n outline-offset: -2px;\n border-radius: 4px;\n }\n\n .bottom-nav-item:active:not([disabled]) {\n transform: scale(0.95);\n }\n\n .bottom-nav-item[aria-selected='true'],\n .bottom-nav-item.active {\n color: var(--bottom-nav-text-active);\n }\n\n .bottom-nav-item[disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .bottom-nav-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--bottom-nav-icon-size);\n height: var(--bottom-nav-icon-size);\n flex-shrink: 0;\n }\n\n .bottom-nav-icon ::slotted(*),\n .bottom-nav-icon svg,\n .bottom-nav-icon img {\n width: 100%;\n height: 100%;\n }\n\n .bottom-nav-label {\n font-size: var(--bottom-nav-label-size);\n font-weight: 500;\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n\n /* Hide labels on very small screens */\n @media (max-width: 320px) {\n .bottom-nav-label {\n display: none;\n }\n\n .bottom-nav-icon {\n width: 28px;\n height: 28px;\n }\n }\n\n /* Color variants */\n :host([color='secondary']) {\n --bottom-nav-text-active: var(--color-secondary, #8b5cf6);\n }\n\n :host([color='success']) {\n --bottom-nav-text-active: var(--color-success, #22c55e);\n }\n\n :host([color='warning']) {\n --bottom-nav-text-active: var(--color-warning, #f59e0b);\n }\n\n :host([color='error']) {\n --bottom-nav-text-active: var(--color-error, #ef4444);\n }\n\n /* Badge indicator for items */\n .bottom-nav-badge {\n position: absolute;\n top: 4px;\n right: calc(50% - 18px);\n min-width: 8px;\n height: 8px;\n background: var(--color-error, #ef4444);\n border-radius: 50%;\n }\n\n .bottom-nav-item-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n justify-content: center;\n max-width: 168px;\n }\n\n /* Slot for custom items */\n ::slotted(el-dm-bottom-navigation-item) {\n flex: 1;\n }\n`;\n\nexport class ElDmBottomNavigation extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false, default: [] },\n value: { type: String, reflect: true },\n color: { type: String, reflect: true, default: 'primary' },\n position: { type: String, reflect: true, default: 'fixed' },\n };\n\n /** Array of navigation items */\n declare items: BottomNavigationItem[];\n\n /** Currently selected item value */\n declare value: string;\n\n /** Color theme */\n declare color: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | string;\n\n /** Position of the navigation bar */\n declare position: 'fixed' | 'static' | 'sticky';\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n this.addEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('click', this._handleClick.bind(this));\n this.removeEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n /**\n * Handle click events on nav items\n */\n private _handleClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n const navItem = target.closest('[data-value]') as HTMLElement | null;\n\n if (!navItem || navItem.hasAttribute('disabled')) {\n return;\n }\n\n const value = navItem.dataset.value;\n if (value && value !== this.value) {\n const item = this.items.find((i) => i.value === value);\n this.value = value;\n this.emit('change', { value, item });\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n private _handleKeydown(event: KeyboardEvent): void {\n const target = event.target as HTMLElement;\n if (!target.classList.contains('bottom-nav-item')) return;\n\n const items = Array.from(this.shadowRoot.querySelectorAll('.bottom-nav-item:not([disabled])'));\n const currentIndex = items.indexOf(target);\n\n let nextIndex = -1;\n\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault();\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n break;\n case 'Home':\n event.preventDefault();\n nextIndex = 0;\n break;\n case 'End':\n event.preventDefault();\n nextIndex = items.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n target.click();\n return;\n }\n\n if (nextIndex >= 0 && items[nextIndex]) {\n (items[nextIndex] as HTMLElement).focus();\n }\n }\n\n /**\n * Render a single navigation item\n */\n private _renderItem(item: BottomNavigationItem): string {\n const isSelected = item.value === this.value;\n const Tag = item.href ? 'a' : 'button';\n const hrefAttr = item.href ? `href=\"${item.href}\"` : '';\n const disabledAttr = item.disabled ? 'disabled' : '';\n const typeAttr = Tag === 'button' ? 'type=\"button\"' : '';\n\n return `\n <div class=\"bottom-nav-item-wrapper\">\n <${Tag}\n class=\"bottom-nav-item\"\n part=\"item\"\n role=\"tab\"\n tabindex=\"${item.disabled ? '-1' : '0'}\"\n aria-selected=\"${isSelected}\"\n data-value=\"${item.value}\"\n ${hrefAttr}\n ${disabledAttr}\n ${typeAttr}\n >\n ${\n item.icon\n ? `\n <span class=\"bottom-nav-icon\" part=\"icon\">\n ${item.icon}\n </span>\n `\n : ''\n }\n <span class=\"bottom-nav-label\" part=\"label\">${item.label}</span>\n </${Tag}>\n </div>\n `;\n }\n\n render(): string {\n const hasItems = this.items && this.items.length > 0;\n\n return `\n <nav class=\"bottom-nav\" part=\"container\" role=\"tablist\" aria-label=\"Bottom navigation\">\n ${hasItems ? this.items.map((item) => this._renderItem(item)).join('') : '<slot></slot>'}\n </nav>\n `;\n }\n}\n",
6
6
  "/**\n * @duskmoon-dev/el-bottom-navigation\n *\n * DuskMoon Bottom Navigation custom element\n */\n\nimport { ElDmBottomNavigation } from './el-dm-bottom-navigation.js';\n\nexport { ElDmBottomNavigation };\nexport type { BottomNavigationItem } from './el-dm-bottom-navigation.js';\n\n/**\n * Register the el-dm-bottom-navigation custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-bottom-navigation';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-bottom-navigation')) {\n customElements.define('el-dm-bottom-navigation', ElDmBottomNavigation);\n }\n}\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "FE83E40F6863EAC564756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "FCA74FDCAFA9033464756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -1,5 +1,7 @@
1
1
  // src/el-dm-bottom-navigation.ts
2
- import { BaseElement, css } from "@duskmoon-dev/el-core";
2
+ import { BaseElement, css } from "@duskmoon-dev/el-base";
3
+ import { css as bottomNavCSS } from "@duskmoon-dev/core/components/bottom-navigation";
4
+ var coreStyles = bottomNavCSS.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
3
5
  var styles = css`
4
6
  :host {
5
7
  --bottom-nav-height: 56px;
@@ -31,36 +33,27 @@ var styles = css`
31
33
  position: sticky;
32
34
  }
33
35
 
36
+ /* Import core bottom-navigation styles */
37
+ ${coreStyles}
38
+
39
+ /* Override core's fixed positioning — :host handles it */
34
40
  .bottom-nav {
35
- display: flex;
36
- align-items: center;
37
- justify-content: space-around;
41
+ position: static;
38
42
  height: var(--bottom-nav-height);
43
+ min-height: auto;
39
44
  background: var(--bottom-nav-bg);
40
45
  border-top: 1px solid var(--bottom-nav-border);
41
46
  box-shadow: var(--bottom-nav-shadow);
42
- padding: 0;
43
- margin: 0;
44
- /* Safe area for iOS devices */
45
- padding-bottom: env(safe-area-inset-bottom, 0);
46
47
  }
47
48
 
48
- .nav-item {
49
- flex: 1;
50
- display: flex;
51
- flex-direction: column;
52
- align-items: center;
53
- justify-content: center;
49
+ /* Override core item styles with our custom properties */
50
+ .bottom-nav-item {
54
51
  gap: 2px;
55
52
  padding: 6px 12px;
56
53
  min-width: 0;
57
54
  max-width: 168px;
58
55
  height: 100%;
59
- background: transparent;
60
- border: none;
61
- cursor: pointer;
62
56
  color: var(--bottom-nav-text);
63
- text-decoration: none;
64
57
  transition:
65
58
  color 0.2s ease,
66
59
  transform 0.1s ease;
@@ -68,32 +61,32 @@ var styles = css`
68
61
  user-select: none;
69
62
  }
70
63
 
71
- .nav-item:focus {
64
+ .bottom-nav-item:focus {
72
65
  outline: none;
73
66
  }
74
67
 
75
- .nav-item:focus-visible {
68
+ .bottom-nav-item:focus-visible {
76
69
  outline: 2px solid var(--bottom-nav-text-active);
77
70
  outline-offset: -2px;
78
71
  border-radius: 4px;
79
72
  }
80
73
 
81
- .nav-item:active:not([disabled]) {
74
+ .bottom-nav-item:active:not([disabled]) {
82
75
  transform: scale(0.95);
83
76
  }
84
77
 
85
- .nav-item[aria-selected='true'],
86
- .nav-item.active {
78
+ .bottom-nav-item[aria-selected='true'],
79
+ .bottom-nav-item.active {
87
80
  color: var(--bottom-nav-text-active);
88
81
  }
89
82
 
90
- .nav-item[disabled] {
83
+ .bottom-nav-item[disabled] {
91
84
  opacity: 0.5;
92
85
  cursor: not-allowed;
93
86
  pointer-events: none;
94
87
  }
95
88
 
96
- .nav-icon {
89
+ .bottom-nav-icon {
97
90
  display: flex;
98
91
  align-items: center;
99
92
  justify-content: center;
@@ -102,14 +95,14 @@ var styles = css`
102
95
  flex-shrink: 0;
103
96
  }
104
97
 
105
- .nav-icon ::slotted(*),
106
- .nav-icon svg,
107
- .nav-icon img {
98
+ .bottom-nav-icon ::slotted(*),
99
+ .bottom-nav-icon svg,
100
+ .bottom-nav-icon img {
108
101
  width: 100%;
109
102
  height: 100%;
110
103
  }
111
104
 
112
- .nav-label {
105
+ .bottom-nav-label {
113
106
  font-size: var(--bottom-nav-label-size);
114
107
  font-weight: 500;
115
108
  line-height: 1.2;
@@ -121,11 +114,11 @@ var styles = css`
121
114
 
122
115
  /* Hide labels on very small screens */
123
116
  @media (max-width: 320px) {
124
- .nav-label {
117
+ .bottom-nav-label {
125
118
  display: none;
126
119
  }
127
120
 
128
- .nav-icon {
121
+ .bottom-nav-icon {
129
122
  width: 28px;
130
123
  height: 28px;
131
124
  }
@@ -149,7 +142,7 @@ var styles = css`
149
142
  }
150
143
 
151
144
  /* Badge indicator for items */
152
- .nav-item-badge {
145
+ .bottom-nav-badge {
153
146
  position: absolute;
154
147
  top: 4px;
155
148
  right: calc(50% - 18px);
@@ -159,7 +152,7 @@ var styles = css`
159
152
  border-radius: 50%;
160
153
  }
161
154
 
162
- .nav-item-wrapper {
155
+ .bottom-nav-item-wrapper {
163
156
  position: relative;
164
157
  flex: 1;
165
158
  display: flex;
@@ -209,9 +202,9 @@ class ElDmBottomNavigation extends BaseElement {
209
202
  }
210
203
  _handleKeydown(event) {
211
204
  const target = event.target;
212
- if (!target.classList.contains("nav-item"))
205
+ if (!target.classList.contains("bottom-nav-item"))
213
206
  return;
214
- const items = Array.from(this.shadowRoot.querySelectorAll(".nav-item:not([disabled])"));
207
+ const items = Array.from(this.shadowRoot.querySelectorAll(".bottom-nav-item:not([disabled])"));
215
208
  const currentIndex = items.indexOf(target);
216
209
  let nextIndex = -1;
217
210
  switch (event.key) {
@@ -243,16 +236,16 @@ class ElDmBottomNavigation extends BaseElement {
243
236
  items[nextIndex].focus();
244
237
  }
245
238
  }
246
- _renderItem(item, index) {
239
+ _renderItem(item) {
247
240
  const isSelected = item.value === this.value;
248
241
  const Tag = item.href ? "a" : "button";
249
242
  const hrefAttr = item.href ? `href="${item.href}"` : "";
250
243
  const disabledAttr = item.disabled ? "disabled" : "";
251
244
  const typeAttr = Tag === "button" ? 'type="button"' : "";
252
245
  return `
253
- <div class="nav-item-wrapper">
246
+ <div class="bottom-nav-item-wrapper">
254
247
  <${Tag}
255
- class="nav-item"
248
+ class="bottom-nav-item"
256
249
  part="item"
257
250
  role="tab"
258
251
  tabindex="${item.disabled ? "-1" : "0"}"
@@ -263,11 +256,11 @@ class ElDmBottomNavigation extends BaseElement {
263
256
  ${typeAttr}
264
257
  >
265
258
  ${item.icon ? `
266
- <span class="nav-icon" part="icon">
259
+ <span class="bottom-nav-icon" part="icon">
267
260
  ${item.icon}
268
261
  </span>
269
262
  ` : ""}
270
- <span class="nav-label" part="label">${item.label}</span>
263
+ <span class="bottom-nav-label" part="label">${item.label}</span>
271
264
  </${Tag}>
272
265
  </div>
273
266
  `;
@@ -276,7 +269,7 @@ class ElDmBottomNavigation extends BaseElement {
276
269
  const hasItems = this.items && this.items.length > 0;
277
270
  return `
278
271
  <nav class="bottom-nav" part="container" role="tablist" aria-label="Bottom navigation">
279
- ${hasItems ? this.items.map((item, i) => this._renderItem(item, i)).join("") : "<slot></slot>"}
272
+ ${hasItems ? this.items.map((item) => this._renderItem(item)).join("") : "<slot></slot>"}
280
273
  </nav>
281
274
  `;
282
275
  }
@@ -292,5 +285,5 @@ function register() {
292
285
  // src/register.ts
293
286
  register();
294
287
 
295
- //# debugId=2051760E1F7B1A3A64756E2164756E21
288
+ //# debugId=E662A681DBB2A6AF64756E2164756E21
296
289
  //# sourceMappingURL=register.js.map
@@ -2,11 +2,11 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/el-dm-bottom-navigation.ts", "../../src/index.ts", "../../src/register.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * DuskMoon Bottom Navigation Element\n *\n * A mobile-first bottom navigation bar component with nav items and icons.\n * Fixed position at the bottom of the viewport for easy thumb access.\n *\n * @element el-dm-bottom-navigation\n *\n * @attr {Array} items - Array of navigation items with { value, label, icon? } structure\n * @attr {string} value - Currently selected item value\n * @attr {string} color - Color theme: primary, secondary, or custom color\n *\n * @slot - Default slot for custom nav items (el-dm-bottom-navigation-item)\n *\n * @csspart container - The navigation container\n * @csspart item - Individual navigation item\n * @csspart icon - Item icon container\n * @csspart label - Item label\n *\n * @fires change - Fired when selection changes, detail: { value, item }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\n/**\n * Navigation item structure\n */\nexport interface BottomNavigationItem {\n /** Unique identifier for the item */\n value: string;\n /** Display label */\n label: string;\n /** Icon HTML or SVG string */\n icon?: string;\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Optional href for link behavior */\n href?: string;\n}\n\nconst styles = css`\n :host {\n --bottom-nav-height: 56px;\n --bottom-nav-bg: var(--color-surface, #ffffff);\n --bottom-nav-border: var(--color-border, #e5e7eb);\n --bottom-nav-text: var(--color-text-secondary, #6b7280);\n --bottom-nav-text-active: var(--color-primary, #3b82f6);\n --bottom-nav-icon-size: 24px;\n --bottom-nav-label-size: 0.75rem;\n --bottom-nav-shadow: 0 -1px 3px rgba(0, 0, 0, 0.1);\n\n display: block;\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n :host([position='static']) {\n position: static;\n }\n\n :host([position='sticky']) {\n position: sticky;\n }\n\n .bottom-nav {\n display: flex;\n align-items: center;\n justify-content: space-around;\n height: var(--bottom-nav-height);\n background: var(--bottom-nav-bg);\n border-top: 1px solid var(--bottom-nav-border);\n box-shadow: var(--bottom-nav-shadow);\n padding: 0;\n margin: 0;\n /* Safe area for iOS devices */\n padding-bottom: env(safe-area-inset-bottom, 0);\n }\n\n .nav-item {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n padding: 6px 12px;\n min-width: 0;\n max-width: 168px;\n height: 100%;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--bottom-nav-text);\n text-decoration: none;\n transition:\n color 0.2s ease,\n transform 0.1s ease;\n -webkit-tap-highlight-color: transparent;\n user-select: none;\n }\n\n .nav-item:focus {\n outline: none;\n }\n\n .nav-item:focus-visible {\n outline: 2px solid var(--bottom-nav-text-active);\n outline-offset: -2px;\n border-radius: 4px;\n }\n\n .nav-item:active:not([disabled]) {\n transform: scale(0.95);\n }\n\n .nav-item[aria-selected='true'],\n .nav-item.active {\n color: var(--bottom-nav-text-active);\n }\n\n .nav-item[disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .nav-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--bottom-nav-icon-size);\n height: var(--bottom-nav-icon-size);\n flex-shrink: 0;\n }\n\n .nav-icon ::slotted(*),\n .nav-icon svg,\n .nav-icon img {\n width: 100%;\n height: 100%;\n }\n\n .nav-label {\n font-size: var(--bottom-nav-label-size);\n font-weight: 500;\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n\n /* Hide labels on very small screens */\n @media (max-width: 320px) {\n .nav-label {\n display: none;\n }\n\n .nav-icon {\n width: 28px;\n height: 28px;\n }\n }\n\n /* Color variants */\n :host([color='secondary']) {\n --bottom-nav-text-active: var(--color-secondary, #8b5cf6);\n }\n\n :host([color='success']) {\n --bottom-nav-text-active: var(--color-success, #22c55e);\n }\n\n :host([color='warning']) {\n --bottom-nav-text-active: var(--color-warning, #f59e0b);\n }\n\n :host([color='error']) {\n --bottom-nav-text-active: var(--color-error, #ef4444);\n }\n\n /* Badge indicator for items */\n .nav-item-badge {\n position: absolute;\n top: 4px;\n right: calc(50% - 18px);\n min-width: 8px;\n height: 8px;\n background: var(--color-error, #ef4444);\n border-radius: 50%;\n }\n\n .nav-item-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n justify-content: center;\n max-width: 168px;\n }\n\n /* Slot for custom items */\n ::slotted(el-dm-bottom-navigation-item) {\n flex: 1;\n }\n`;\n\nexport class ElDmBottomNavigation extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false, default: [] },\n value: { type: String, reflect: true },\n color: { type: String, reflect: true, default: 'primary' },\n position: { type: String, reflect: true, default: 'fixed' },\n };\n\n /** Array of navigation items */\n declare items: BottomNavigationItem[];\n\n /** Currently selected item value */\n declare value: string;\n\n /** Color theme */\n declare color: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | string;\n\n /** Position of the navigation bar */\n declare position: 'fixed' | 'static' | 'sticky';\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n this.addEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('click', this._handleClick.bind(this));\n this.removeEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n /**\n * Handle click events on nav items\n */\n private _handleClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n const navItem = target.closest('[data-value]') as HTMLElement | null;\n\n if (!navItem || navItem.hasAttribute('disabled')) {\n return;\n }\n\n const value = navItem.dataset.value;\n if (value && value !== this.value) {\n const item = this.items.find((i) => i.value === value);\n this.value = value;\n this.emit('change', { value, item });\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n private _handleKeydown(event: KeyboardEvent): void {\n const target = event.target as HTMLElement;\n if (!target.classList.contains('nav-item')) return;\n\n const items = Array.from(this.shadowRoot.querySelectorAll('.nav-item:not([disabled])'));\n const currentIndex = items.indexOf(target);\n\n let nextIndex = -1;\n\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault();\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n break;\n case 'Home':\n event.preventDefault();\n nextIndex = 0;\n break;\n case 'End':\n event.preventDefault();\n nextIndex = items.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n target.click();\n return;\n }\n\n if (nextIndex >= 0 && items[nextIndex]) {\n (items[nextIndex] as HTMLElement).focus();\n }\n }\n\n /**\n * Render a single navigation item\n */\n private _renderItem(item: BottomNavigationItem, index: number): string {\n const isSelected = item.value === this.value;\n const Tag = item.href ? 'a' : 'button';\n const hrefAttr = item.href ? `href=\"${item.href}\"` : '';\n const disabledAttr = item.disabled ? 'disabled' : '';\n const typeAttr = Tag === 'button' ? 'type=\"button\"' : '';\n\n return `\n <div class=\"nav-item-wrapper\">\n <${Tag}\n class=\"nav-item\"\n part=\"item\"\n role=\"tab\"\n tabindex=\"${item.disabled ? '-1' : '0'}\"\n aria-selected=\"${isSelected}\"\n data-value=\"${item.value}\"\n ${hrefAttr}\n ${disabledAttr}\n ${typeAttr}\n >\n ${\n item.icon\n ? `\n <span class=\"nav-icon\" part=\"icon\">\n ${item.icon}\n </span>\n `\n : ''\n }\n <span class=\"nav-label\" part=\"label\">${item.label}</span>\n </${Tag}>\n </div>\n `;\n }\n\n render(): string {\n const hasItems = this.items && this.items.length > 0;\n\n return `\n <nav class=\"bottom-nav\" part=\"container\" role=\"tablist\" aria-label=\"Bottom navigation\">\n ${hasItems ? this.items.map((item, i) => this._renderItem(item, i)).join('') : '<slot></slot>'}\n </nav>\n `;\n }\n}\n",
5
+ "/**\n * DuskMoon Bottom Navigation Element\n *\n * A mobile-first bottom navigation bar component with nav items and icons.\n * Fixed position at the bottom of the viewport for easy thumb access.\n *\n * @element el-dm-bottom-navigation\n *\n * @attr {Array} items - Array of navigation items with { value, label, icon? } structure\n * @attr {string} value - Currently selected item value\n * @attr {string} color - Color theme: primary, secondary, or custom color\n *\n * @slot - Default slot for custom nav items (el-dm-bottom-navigation-item)\n *\n * @csspart container - The navigation container\n * @csspart item - Individual navigation item\n * @csspart icon - Item icon container\n * @csspart label - Item label\n *\n * @fires change - Fired when selection changes, detail: { value, item }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as bottomNavCSS } from '@duskmoon-dev/core/components/bottom-navigation';\n\n/**\n * Navigation item structure\n */\nexport interface BottomNavigationItem {\n /** Unique identifier for the item */\n value: string;\n /** Display label */\n label: string;\n /** Icon HTML or SVG string */\n icon?: string;\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Optional href for link behavior */\n href?: string;\n}\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = bottomNavCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n --bottom-nav-height: 56px;\n --bottom-nav-bg: var(--color-surface, #ffffff);\n --bottom-nav-border: var(--color-border, #e5e7eb);\n --bottom-nav-text: var(--color-text-secondary, #6b7280);\n --bottom-nav-text-active: var(--color-primary, #3b82f6);\n --bottom-nav-icon-size: 24px;\n --bottom-nav-label-size: 0.75rem;\n --bottom-nav-shadow: 0 -1px 3px rgba(0, 0, 0, 0.1);\n\n display: block;\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n :host([position='static']) {\n position: static;\n }\n\n :host([position='sticky']) {\n position: sticky;\n }\n\n /* Import core bottom-navigation styles */\n ${coreStyles}\n\n /* Override core's fixed positioning — :host handles it */\n .bottom-nav {\n position: static;\n height: var(--bottom-nav-height);\n min-height: auto;\n background: var(--bottom-nav-bg);\n border-top: 1px solid var(--bottom-nav-border);\n box-shadow: var(--bottom-nav-shadow);\n }\n\n /* Override core item styles with our custom properties */\n .bottom-nav-item {\n gap: 2px;\n padding: 6px 12px;\n min-width: 0;\n max-width: 168px;\n height: 100%;\n color: var(--bottom-nav-text);\n transition:\n color 0.2s ease,\n transform 0.1s ease;\n -webkit-tap-highlight-color: transparent;\n user-select: none;\n }\n\n .bottom-nav-item:focus {\n outline: none;\n }\n\n .bottom-nav-item:focus-visible {\n outline: 2px solid var(--bottom-nav-text-active);\n outline-offset: -2px;\n border-radius: 4px;\n }\n\n .bottom-nav-item:active:not([disabled]) {\n transform: scale(0.95);\n }\n\n .bottom-nav-item[aria-selected='true'],\n .bottom-nav-item.active {\n color: var(--bottom-nav-text-active);\n }\n\n .bottom-nav-item[disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .bottom-nav-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--bottom-nav-icon-size);\n height: var(--bottom-nav-icon-size);\n flex-shrink: 0;\n }\n\n .bottom-nav-icon ::slotted(*),\n .bottom-nav-icon svg,\n .bottom-nav-icon img {\n width: 100%;\n height: 100%;\n }\n\n .bottom-nav-label {\n font-size: var(--bottom-nav-label-size);\n font-weight: 500;\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n\n /* Hide labels on very small screens */\n @media (max-width: 320px) {\n .bottom-nav-label {\n display: none;\n }\n\n .bottom-nav-icon {\n width: 28px;\n height: 28px;\n }\n }\n\n /* Color variants */\n :host([color='secondary']) {\n --bottom-nav-text-active: var(--color-secondary, #8b5cf6);\n }\n\n :host([color='success']) {\n --bottom-nav-text-active: var(--color-success, #22c55e);\n }\n\n :host([color='warning']) {\n --bottom-nav-text-active: var(--color-warning, #f59e0b);\n }\n\n :host([color='error']) {\n --bottom-nav-text-active: var(--color-error, #ef4444);\n }\n\n /* Badge indicator for items */\n .bottom-nav-badge {\n position: absolute;\n top: 4px;\n right: calc(50% - 18px);\n min-width: 8px;\n height: 8px;\n background: var(--color-error, #ef4444);\n border-radius: 50%;\n }\n\n .bottom-nav-item-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n justify-content: center;\n max-width: 168px;\n }\n\n /* Slot for custom items */\n ::slotted(el-dm-bottom-navigation-item) {\n flex: 1;\n }\n`;\n\nexport class ElDmBottomNavigation extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false, default: [] },\n value: { type: String, reflect: true },\n color: { type: String, reflect: true, default: 'primary' },\n position: { type: String, reflect: true, default: 'fixed' },\n };\n\n /** Array of navigation items */\n declare items: BottomNavigationItem[];\n\n /** Currently selected item value */\n declare value: string;\n\n /** Color theme */\n declare color: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | string;\n\n /** Position of the navigation bar */\n declare position: 'fixed' | 'static' | 'sticky';\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n this.addEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('click', this._handleClick.bind(this));\n this.removeEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n /**\n * Handle click events on nav items\n */\n private _handleClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n const navItem = target.closest('[data-value]') as HTMLElement | null;\n\n if (!navItem || navItem.hasAttribute('disabled')) {\n return;\n }\n\n const value = navItem.dataset.value;\n if (value && value !== this.value) {\n const item = this.items.find((i) => i.value === value);\n this.value = value;\n this.emit('change', { value, item });\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n private _handleKeydown(event: KeyboardEvent): void {\n const target = event.target as HTMLElement;\n if (!target.classList.contains('bottom-nav-item')) return;\n\n const items = Array.from(this.shadowRoot.querySelectorAll('.bottom-nav-item:not([disabled])'));\n const currentIndex = items.indexOf(target);\n\n let nextIndex = -1;\n\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault();\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault();\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n break;\n case 'Home':\n event.preventDefault();\n nextIndex = 0;\n break;\n case 'End':\n event.preventDefault();\n nextIndex = items.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n target.click();\n return;\n }\n\n if (nextIndex >= 0 && items[nextIndex]) {\n (items[nextIndex] as HTMLElement).focus();\n }\n }\n\n /**\n * Render a single navigation item\n */\n private _renderItem(item: BottomNavigationItem): string {\n const isSelected = item.value === this.value;\n const Tag = item.href ? 'a' : 'button';\n const hrefAttr = item.href ? `href=\"${item.href}\"` : '';\n const disabledAttr = item.disabled ? 'disabled' : '';\n const typeAttr = Tag === 'button' ? 'type=\"button\"' : '';\n\n return `\n <div class=\"bottom-nav-item-wrapper\">\n <${Tag}\n class=\"bottom-nav-item\"\n part=\"item\"\n role=\"tab\"\n tabindex=\"${item.disabled ? '-1' : '0'}\"\n aria-selected=\"${isSelected}\"\n data-value=\"${item.value}\"\n ${hrefAttr}\n ${disabledAttr}\n ${typeAttr}\n >\n ${\n item.icon\n ? `\n <span class=\"bottom-nav-icon\" part=\"icon\">\n ${item.icon}\n </span>\n `\n : ''\n }\n <span class=\"bottom-nav-label\" part=\"label\">${item.label}</span>\n </${Tag}>\n </div>\n `;\n }\n\n render(): string {\n const hasItems = this.items && this.items.length > 0;\n\n return `\n <nav class=\"bottom-nav\" part=\"container\" role=\"tablist\" aria-label=\"Bottom navigation\">\n ${hasItems ? this.items.map((item) => this._renderItem(item)).join('') : '<slot></slot>'}\n </nav>\n `;\n }\n}\n",
6
6
  "/**\n * @duskmoon-dev/el-bottom-navigation\n *\n * DuskMoon Bottom Navigation custom element\n */\n\nimport { ElDmBottomNavigation } from './el-dm-bottom-navigation.js';\n\nexport { ElDmBottomNavigation };\nexport type { BottomNavigationItem } from './el-dm-bottom-navigation.js';\n\n/**\n * Register the el-dm-bottom-navigation custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-bottom-navigation';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-bottom-navigation')) {\n customElements.define('el-dm-bottom-navigation', ElDmBottomNavigation);\n }\n}\n",
7
7
  "/**\n * Auto-register el-dm-bottom-navigation custom element\n *\n * @example\n * ```ts\n * import '@duskmoon-dev/el-bottom-navigation/register';\n *\n * // Now you can use <el-dm-bottom-navigation> in HTML\n * ```\n */\nimport { register } from './index.js';\n\nregister();\n"
8
8
  ],
9
- "mappings": "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",
10
- "debugId": "2051760E1F7B1A3A64756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "E662A681DBB2A6AF64756E2164756E21",
11
11
  "names": []
12
12
  }