@sekiui/elements 0.0.56 → 0.0.59

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.
Files changed (269) hide show
  1. package/dist/cdn/index.js +1053 -91
  2. package/dist/cdn/p-BJCq8m2o.js +138 -0
  3. package/dist/cdn/p-Cpa2leXN.js +111 -0
  4. package/dist/cdn/{p-bMBhrs0a.js → p-DxUZSKfL.js} +467 -9
  5. package/dist/cdn/seki-badge.d.ts +11 -0
  6. package/dist/cdn/seki-badge.js +109 -0
  7. package/dist/cdn/seki-button.js +1 -1
  8. package/dist/cdn/seki-card-action.js +1 -1
  9. package/dist/cdn/seki-card-content.js +1 -1
  10. package/dist/cdn/seki-card-description.js +1 -1
  11. package/dist/cdn/seki-card-footer.js +1 -1
  12. package/dist/cdn/seki-card-header.js +1 -1
  13. package/dist/cdn/seki-card-title.js +1 -1
  14. package/dist/cdn/seki-card.js +1 -1
  15. package/dist/cdn/seki-field-description.js +1 -1
  16. package/dist/cdn/seki-field-error.js +1 -1
  17. package/dist/cdn/seki-field-group.js +1 -1
  18. package/dist/cdn/seki-field-label.js +1 -1
  19. package/dist/cdn/seki-field-legend.js +1 -1
  20. package/dist/cdn/seki-field.js +1 -1
  21. package/dist/cdn/seki-fieldset.js +1 -1
  22. package/dist/cdn/seki-input.js +1 -1
  23. package/dist/cdn/seki-select-content.js +1 -1
  24. package/dist/cdn/seki-select-group.js +1 -1
  25. package/dist/cdn/seki-select-option.js +1 -1
  26. package/dist/cdn/seki-select-trigger.js +1 -1
  27. package/dist/cdn/seki-select.js +1 -1
  28. package/dist/cdn/seki-sidebar-content.d.ts +11 -0
  29. package/dist/cdn/seki-sidebar-content.js +38 -0
  30. package/dist/cdn/seki-sidebar-footer.d.ts +11 -0
  31. package/dist/cdn/seki-sidebar-footer.js +38 -0
  32. package/dist/cdn/seki-sidebar-group.d.ts +11 -0
  33. package/dist/cdn/seki-sidebar-group.js +131 -0
  34. package/dist/cdn/seki-sidebar-header.d.ts +11 -0
  35. package/dist/cdn/seki-sidebar-header.js +38 -0
  36. package/dist/cdn/seki-sidebar-menu-item.d.ts +11 -0
  37. package/dist/cdn/seki-sidebar-menu-item.js +200 -0
  38. package/dist/cdn/seki-sidebar-menu-sub.d.ts +11 -0
  39. package/dist/cdn/seki-sidebar-menu-sub.js +123 -0
  40. package/dist/cdn/seki-sidebar-menu.d.ts +11 -0
  41. package/dist/cdn/seki-sidebar-menu.js +38 -0
  42. package/dist/cdn/seki-sidebar-trigger.d.ts +11 -0
  43. package/dist/cdn/seki-sidebar-trigger.js +109 -0
  44. package/dist/cdn/seki-sidebar.d.ts +11 -0
  45. package/dist/cdn/seki-sidebar.js +380 -0
  46. package/dist/cdn/seki-skeleton.js +2 -2
  47. package/dist/cdn/seki-switch.js +1 -1
  48. package/dist/cdn/seki-tooltip.js +1 -1
  49. package/dist/cjs/{index-Dd6_-KaR.js → index-D4RM3EID.js} +466 -8
  50. package/dist/cjs/index.cjs.js +1115 -63
  51. package/dist/cjs/keyboard-Cjl5HYES.js +142 -0
  52. package/dist/cjs/loader.cjs.js +2 -2
  53. package/dist/cjs/seki-badge.cjs.entry.js +85 -0
  54. package/dist/cjs/seki-button.cjs.entry.js +1 -1
  55. package/dist/cjs/seki-card-action.cjs.entry.js +1 -1
  56. package/dist/cjs/seki-card-content.cjs.entry.js +1 -1
  57. package/dist/cjs/seki-card-description.cjs.entry.js +1 -1
  58. package/dist/cjs/seki-card-footer.cjs.entry.js +1 -1
  59. package/dist/cjs/seki-card-header.cjs.entry.js +1 -1
  60. package/dist/cjs/seki-card-title.cjs.entry.js +1 -1
  61. package/dist/cjs/seki-card.cjs.entry.js +1 -1
  62. package/dist/cjs/seki-field-description.cjs.entry.js +1 -1
  63. package/dist/cjs/seki-field-error.cjs.entry.js +1 -1
  64. package/dist/cjs/seki-field-group.cjs.entry.js +1 -1
  65. package/dist/cjs/seki-field-label.cjs.entry.js +1 -1
  66. package/dist/cjs/seki-field-legend.cjs.entry.js +1 -1
  67. package/dist/cjs/seki-field.cjs.entry.js +1 -1
  68. package/dist/cjs/seki-fieldset.cjs.entry.js +1 -1
  69. package/dist/cjs/seki-input.cjs.entry.js +1 -1
  70. package/dist/cjs/seki-select-content.cjs.entry.js +1 -1
  71. package/dist/cjs/seki-select-group.cjs.entry.js +1 -1
  72. package/dist/cjs/seki-select-option.cjs.entry.js +1 -1
  73. package/dist/cjs/seki-select-trigger.cjs.entry.js +1 -1
  74. package/dist/cjs/seki-select.cjs.entry.js +1 -1
  75. package/dist/cjs/seki-sidebar-content.cjs.entry.js +20 -0
  76. package/dist/cjs/seki-sidebar-footer.cjs.entry.js +20 -0
  77. package/dist/cjs/seki-sidebar-group.cjs.entry.js +105 -0
  78. package/dist/cjs/seki-sidebar-header.cjs.entry.js +20 -0
  79. package/dist/cjs/seki-sidebar-menu-item.cjs.entry.js +174 -0
  80. package/dist/cjs/seki-sidebar-menu-sub.cjs.entry.js +99 -0
  81. package/dist/cjs/seki-sidebar-menu.cjs.entry.js +20 -0
  82. package/dist/cjs/seki-sidebar-trigger.cjs.entry.js +86 -0
  83. package/dist/cjs/seki-sidebar.cjs.entry.js +342 -0
  84. package/dist/cjs/seki-skeleton.cjs.entry.js +2 -2
  85. package/dist/cjs/seki-switch.cjs.entry.js +81 -3
  86. package/dist/cjs/seki-tooltip.cjs.entry.js +1 -1
  87. package/dist/cjs/sekiui.cjs.js +3 -3
  88. package/dist/collection/collection-manifest.json +12 -2
  89. package/dist/collection/components/badge/seki-badge.css +140 -0
  90. package/dist/collection/components/badge/seki-badge.interface.js +1 -0
  91. package/dist/collection/components/badge/seki-badge.js +199 -0
  92. package/dist/collection/components/sidebar/seki-sidebar-content.css +82 -0
  93. package/dist/collection/components/sidebar/seki-sidebar-content.js +33 -0
  94. package/dist/collection/components/sidebar/seki-sidebar-footer.css +44 -0
  95. package/dist/collection/components/sidebar/seki-sidebar-footer.js +31 -0
  96. package/dist/collection/components/sidebar/seki-sidebar-group.css +158 -0
  97. package/dist/collection/components/sidebar/seki-sidebar-group.js +300 -0
  98. package/dist/collection/components/sidebar/seki-sidebar-header.css +44 -0
  99. package/dist/collection/components/sidebar/seki-sidebar-header.js +32 -0
  100. package/dist/collection/components/sidebar/seki-sidebar-menu-item.css +196 -0
  101. package/dist/collection/components/sidebar/seki-sidebar-menu-item.js +403 -0
  102. package/dist/collection/components/sidebar/seki-sidebar-menu-sub.css +357 -0
  103. package/dist/collection/components/sidebar/seki-sidebar-menu-sub.js +256 -0
  104. package/dist/collection/components/sidebar/seki-sidebar-menu.css +25 -0
  105. package/dist/collection/components/sidebar/seki-sidebar-menu.js +32 -0
  106. package/dist/collection/components/sidebar/seki-sidebar-trigger.css +68 -0
  107. package/dist/collection/components/sidebar/seki-sidebar-trigger.js +175 -0
  108. package/dist/collection/components/sidebar/seki-sidebar.css +352 -0
  109. package/dist/collection/components/sidebar/seki-sidebar.js +812 -0
  110. package/dist/collection/components/sidebar/types.js +18 -0
  111. package/dist/collection/components/skeleton/seki-skeleton.js +1 -1
  112. package/dist/collection/index.js +7 -0
  113. package/dist/collection/services/focus.js +192 -0
  114. package/dist/collection/services/index.js +7 -0
  115. package/dist/collection/services/keyboard.js +136 -0
  116. package/dist/collection/services/media-query.js +254 -0
  117. package/dist/collection/types.js +41 -0
  118. package/dist/collection/utils/a11y.js +291 -0
  119. package/dist/collection/utils/common.js +286 -0
  120. package/dist/components/index.js +1053 -91
  121. package/dist/components/p-BJCq8m2o.js +138 -0
  122. package/dist/components/{p-QhPshhKB.js → p-BU1kuAZS.js} +467 -9
  123. package/dist/components/p-wQy1sEm6.js +111 -0
  124. package/dist/components/seki-badge.d.ts +11 -0
  125. package/dist/components/seki-badge.js +109 -0
  126. package/dist/components/seki-button.js +1 -1
  127. package/dist/components/seki-card-action.js +1 -1
  128. package/dist/components/seki-card-content.js +1 -1
  129. package/dist/components/seki-card-description.js +1 -1
  130. package/dist/components/seki-card-footer.js +1 -1
  131. package/dist/components/seki-card-header.js +1 -1
  132. package/dist/components/seki-card-title.js +1 -1
  133. package/dist/components/seki-card.js +1 -1
  134. package/dist/components/seki-field-description.js +1 -1
  135. package/dist/components/seki-field-error.js +1 -1
  136. package/dist/components/seki-field-group.js +1 -1
  137. package/dist/components/seki-field-label.js +1 -1
  138. package/dist/components/seki-field-legend.js +1 -1
  139. package/dist/components/seki-field.js +1 -1
  140. package/dist/components/seki-fieldset.js +1 -1
  141. package/dist/components/seki-input.js +1 -1
  142. package/dist/components/seki-select-content.js +1 -1
  143. package/dist/components/seki-select-group.js +1 -1
  144. package/dist/components/seki-select-option.js +1 -1
  145. package/dist/components/seki-select-trigger.js +1 -1
  146. package/dist/components/seki-select.js +1 -1
  147. package/dist/components/seki-sidebar-content.d.ts +11 -0
  148. package/dist/components/seki-sidebar-content.js +38 -0
  149. package/dist/components/seki-sidebar-footer.d.ts +11 -0
  150. package/dist/components/seki-sidebar-footer.js +38 -0
  151. package/dist/components/seki-sidebar-group.d.ts +11 -0
  152. package/dist/components/seki-sidebar-group.js +131 -0
  153. package/dist/components/seki-sidebar-header.d.ts +11 -0
  154. package/dist/components/seki-sidebar-header.js +38 -0
  155. package/dist/components/seki-sidebar-menu-item.d.ts +11 -0
  156. package/dist/components/seki-sidebar-menu-item.js +200 -0
  157. package/dist/components/seki-sidebar-menu-sub.d.ts +11 -0
  158. package/dist/components/seki-sidebar-menu-sub.js +123 -0
  159. package/dist/components/seki-sidebar-menu.d.ts +11 -0
  160. package/dist/components/seki-sidebar-menu.js +38 -0
  161. package/dist/components/seki-sidebar-trigger.d.ts +11 -0
  162. package/dist/components/seki-sidebar-trigger.js +109 -0
  163. package/dist/components/seki-sidebar.d.ts +11 -0
  164. package/dist/components/seki-sidebar.js +380 -0
  165. package/dist/components/seki-skeleton.js +2 -2
  166. package/dist/components/seki-switch.js +1 -1
  167. package/dist/components/seki-tooltip.js +1 -1
  168. package/dist/esm/{index-CuXbV_yz.js → index-DI_YjzRi.js} +466 -8
  169. package/dist/esm/index.js +1053 -63
  170. package/dist/esm/keyboard-BJCq8m2o.js +138 -0
  171. package/dist/esm/loader.js +3 -3
  172. package/dist/esm/seki-badge.entry.js +83 -0
  173. package/dist/esm/seki-button.entry.js +1 -1
  174. package/dist/esm/seki-card-action.entry.js +1 -1
  175. package/dist/esm/seki-card-content.entry.js +1 -1
  176. package/dist/esm/seki-card-description.entry.js +1 -1
  177. package/dist/esm/seki-card-footer.entry.js +1 -1
  178. package/dist/esm/seki-card-header.entry.js +1 -1
  179. package/dist/esm/seki-card-title.entry.js +1 -1
  180. package/dist/esm/seki-card.entry.js +1 -1
  181. package/dist/esm/seki-field-description.entry.js +1 -1
  182. package/dist/esm/seki-field-error.entry.js +1 -1
  183. package/dist/esm/seki-field-group.entry.js +1 -1
  184. package/dist/esm/seki-field-label.entry.js +1 -1
  185. package/dist/esm/seki-field-legend.entry.js +1 -1
  186. package/dist/esm/seki-field.entry.js +1 -1
  187. package/dist/esm/seki-fieldset.entry.js +1 -1
  188. package/dist/esm/seki-input.entry.js +1 -1
  189. package/dist/esm/seki-select-content.entry.js +1 -1
  190. package/dist/esm/seki-select-group.entry.js +1 -1
  191. package/dist/esm/seki-select-option.entry.js +1 -1
  192. package/dist/esm/seki-select-trigger.entry.js +1 -1
  193. package/dist/esm/seki-select.entry.js +1 -1
  194. package/dist/esm/seki-sidebar-content.entry.js +18 -0
  195. package/dist/esm/seki-sidebar-footer.entry.js +18 -0
  196. package/dist/esm/seki-sidebar-group.entry.js +103 -0
  197. package/dist/esm/seki-sidebar-header.entry.js +18 -0
  198. package/dist/esm/seki-sidebar-menu-item.entry.js +172 -0
  199. package/dist/esm/seki-sidebar-menu-sub.entry.js +97 -0
  200. package/dist/esm/seki-sidebar-menu.entry.js +18 -0
  201. package/dist/esm/seki-sidebar-trigger.entry.js +84 -0
  202. package/dist/esm/seki-sidebar.entry.js +340 -0
  203. package/dist/esm/seki-skeleton.entry.js +2 -2
  204. package/dist/esm/seki-switch.entry.js +84 -2
  205. package/dist/esm/seki-tooltip.entry.js +1 -1
  206. package/dist/esm/sekiui.js +4 -4
  207. package/dist/sekiui/index.esm.js +1 -1
  208. package/dist/sekiui/p-0af1b81a.entry.js +1 -0
  209. package/dist/sekiui/p-0ca6b9f0.entry.js +1 -0
  210. package/dist/sekiui/{p-cf11115c.entry.js → p-1480b41a.entry.js} +1 -1
  211. package/dist/sekiui/{p-dd1e3e87.entry.js → p-161be4d4.entry.js} +1 -1
  212. package/dist/sekiui/{p-e71ad432.entry.js → p-1685e673.entry.js} +1 -1
  213. package/dist/sekiui/p-26b629bc.entry.js +1 -0
  214. package/dist/sekiui/{p-0544d787.entry.js → p-27deb555.entry.js} +1 -1
  215. package/dist/sekiui/p-37fa684c.entry.js +1 -0
  216. package/dist/sekiui/{p-1607dc4d.entry.js → p-402a5db6.entry.js} +1 -1
  217. package/dist/sekiui/{p-6bde807e.entry.js → p-40ba3ad6.entry.js} +1 -1
  218. package/dist/sekiui/{p-d4c92041.entry.js → p-4867d02d.entry.js} +1 -1
  219. package/dist/sekiui/p-4b29dbda.entry.js +1 -0
  220. package/dist/sekiui/{p-b10d81a6.entry.js → p-587fd313.entry.js} +1 -1
  221. package/dist/sekiui/{p-3e088b5a.entry.js → p-58ab95eb.entry.js} +1 -1
  222. package/dist/sekiui/p-60ff3543.entry.js +1 -0
  223. package/dist/sekiui/{p-9af5286b.entry.js → p-68b1fa1a.entry.js} +1 -1
  224. package/dist/sekiui/{p-43f7c542.entry.js → p-6a922121.entry.js} +1 -1
  225. package/dist/sekiui/{p-4d57c6ea.entry.js → p-6f5bf5af.entry.js} +1 -1
  226. package/dist/sekiui/{p-88f91658.entry.js → p-84d47cab.entry.js} +1 -1
  227. package/dist/sekiui/p-9dcd07b2.entry.js +1 -0
  228. package/dist/sekiui/p-BJCq8m2o.js +1 -0
  229. package/dist/sekiui/p-DI_YjzRi.js +2 -0
  230. package/dist/sekiui/p-ab9d1ba5.entry.js +1 -0
  231. package/dist/sekiui/p-b525d85a.entry.js +1 -0
  232. package/dist/sekiui/{p-ed440425.entry.js → p-b64e7007.entry.js} +1 -1
  233. package/dist/sekiui/{p-6e238adf.entry.js → p-b7f2b568.entry.js} +1 -1
  234. package/dist/sekiui/{p-009183ab.entry.js → p-c642ab55.entry.js} +1 -1
  235. package/dist/sekiui/{p-eefbc037.entry.js → p-c74bd925.entry.js} +1 -1
  236. package/dist/sekiui/p-c83d94c4.entry.js +1 -0
  237. package/dist/sekiui/p-ce1bbe04.entry.js +1 -0
  238. package/dist/sekiui/{p-b22df79e.entry.js → p-cf552ff9.entry.js} +1 -1
  239. package/dist/sekiui/{p-81709fc2.entry.js → p-d194caf1.entry.js} +1 -1
  240. package/dist/sekiui/{p-b479935d.entry.js → p-dfa2f8cd.entry.js} +1 -1
  241. package/dist/sekiui/{p-eedf44b5.entry.js → p-e6d5f56e.entry.js} +1 -1
  242. package/dist/sekiui/{p-97e6e5ce.entry.js → p-f1ffc3fa.entry.js} +1 -1
  243. package/dist/sekiui/{p-35f8f9c4.entry.js → p-f863f36b.entry.js} +1 -1
  244. package/dist/sekiui/sekiui.esm.js +1 -1
  245. package/dist/types/components/badge/seki-badge.d.ts +43 -0
  246. package/dist/types/components/badge/seki-badge.interface.d.ts +88 -0
  247. package/dist/types/components/sidebar/seki-sidebar-content.d.ts +18 -0
  248. package/dist/types/components/sidebar/seki-sidebar-footer.d.ts +16 -0
  249. package/dist/types/components/sidebar/seki-sidebar-group.d.ts +81 -0
  250. package/dist/types/components/sidebar/seki-sidebar-header.d.ts +17 -0
  251. package/dist/types/components/sidebar/seki-sidebar-menu-item.d.ts +104 -0
  252. package/dist/types/components/sidebar/seki-sidebar-menu-sub.d.ts +81 -0
  253. package/dist/types/components/sidebar/seki-sidebar-menu.d.ts +17 -0
  254. package/dist/types/components/sidebar/seki-sidebar-trigger.d.ts +53 -0
  255. package/dist/types/components/sidebar/seki-sidebar.d.ts +185 -0
  256. package/dist/types/components/sidebar/types.d.ts +245 -0
  257. package/dist/types/components.d.ts +599 -0
  258. package/dist/types/index.d.ts +4 -0
  259. package/dist/types/services/focus.d.ts +74 -0
  260. package/dist/types/services/index.d.ts +7 -0
  261. package/dist/types/services/keyboard.d.ts +74 -0
  262. package/dist/types/services/media-query.d.ts +121 -0
  263. package/dist/types/stencil-public-runtime.d.ts +19 -9
  264. package/dist/types/types.d.ts +105 -0
  265. package/dist/types/utils/a11y.d.ts +130 -0
  266. package/dist/types/utils/common.d.ts +142 -0
  267. package/package.json +10 -2
  268. package/dist/sekiui/p-9fe07f6e.entry.js +0 -1
  269. package/dist/sekiui/p-CuXbV_yz.js +0 -2
@@ -0,0 +1,357 @@
1
+ /**
2
+ * SekiSidebarMenuSub CSS
3
+ * Styling for nested submenu items in the sidebar
4
+ * Supports:
5
+ * - Expandable/collapsible submenus with smooth animations (200ms)
6
+ * - Icon + text display when expanded
7
+ * - Icon-only + tooltip when parent sidebar is collapsed
8
+ * - Multi-level nesting with proper indentation
9
+ * - Full keyboard and screen reader accessibility
10
+ * - Dark mode and reduced motion support
11
+ */
12
+
13
+ :host {
14
+ display: block;
15
+ width: 100%;
16
+ --submenu-indent-level: 1;
17
+ }
18
+
19
+ .submenu-wrapper {
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: var(--sidebar-gap, 0.5rem);
23
+ width: 100%;
24
+ margin-left: calc(var(--sidebar-submenu-indent, 1rem) * var(--submenu-indent-level, 1));
25
+ }
26
+
27
+ /* === Submenu Trigger (Parent Item Style) === */
28
+
29
+ .submenu-trigger {
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: flex-start;
33
+ gap: var(--sidebar-gap, 0.5rem);
34
+ padding: var(--sidebar-item-padding, 0.5rem 0.75rem);
35
+ background-color: transparent;
36
+ border: none;
37
+ border-radius: var(--sidebar-radius-sm, 0.25rem);
38
+ color: var(--sidebar-item-foreground, var(--seki-color-text));
39
+ cursor: pointer;
40
+ transition: all var(--sidebar-transition, 200ms) ease-out;
41
+ width: 100%;
42
+ text-align: left;
43
+ position: relative;
44
+ /* Use built-in typography */
45
+ font-size: var(--seki-font-size-sm);
46
+ font-weight: var(--seki-font-weight-medium);
47
+ font-family: var(--seki-font-sans);
48
+ line-height: 1.25rem;
49
+ }
50
+
51
+ :host([data-theme="dark"]) .submenu-trigger {
52
+ color: var(--sidebar-item-foreground-dark, #f1f5f9);
53
+ }
54
+
55
+ .submenu-trigger:hover {
56
+ background-color: var(--sidebar-item-hover-bg, #f3f4f6);
57
+ }
58
+
59
+ :host([data-theme="dark"]) .submenu-trigger:hover {
60
+ background-color: var(--sidebar-item-hover-bg-dark, #27272a);
61
+ }
62
+
63
+ .submenu-trigger:focus-visible {
64
+ outline: 2px solid var(--sidebar-primary, #3b82f6);
65
+ outline-offset: -2px;
66
+ }
67
+
68
+ .submenu-trigger:active {
69
+ background-color: var(--sidebar-item-active-bg, #e0e7ff);
70
+ }
71
+
72
+ :host([data-theme="dark"]) .submenu-trigger:active {
73
+ background-color: var(--sidebar-item-active-bg-dark, #3f3f46);
74
+ }
75
+
76
+ /* === Trigger Icon (Submenu Item Icon) === */
77
+
78
+ .submenu-trigger-label {
79
+ display: inline-flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ width: 1.25rem;
83
+ height: 1.25rem;
84
+ flex-shrink: 0;
85
+ color: inherit;
86
+ }
87
+
88
+ .submenu-trigger-label ::slotted(*) {
89
+ width: 100%;
90
+ height: 100%;
91
+ }
92
+
93
+ /* === Trigger Text (Submenu Item Label) === */
94
+
95
+ .submenu-trigger-text {
96
+ flex: 1;
97
+ white-space: nowrap;
98
+ overflow: hidden;
99
+ text-overflow: ellipsis;
100
+ transition: opacity var(--sidebar-transition, 200ms) ease-linear;
101
+ }
102
+
103
+ /* When parent sidebar is in icon-only mode, hide the text */
104
+ :host-context(seki-sidebar[data-collapse-mode="icon"]) .submenu-trigger-text {
105
+ opacity: 0;
106
+ width: 0;
107
+ overflow: hidden;
108
+ }
109
+
110
+ /* === Trigger Expand Arrow === */
111
+
112
+ .submenu-trigger-icon {
113
+ display: inline-block;
114
+ width: 1rem;
115
+ height: 1rem;
116
+ transition: transform var(--sidebar-transition, 200ms) ease-out;
117
+ flex-shrink: 0;
118
+ color: inherit;
119
+ }
120
+
121
+ /* Arrow rotates 90deg when submenu is EXPANDED (not collapsed) */
122
+ :host([data-collapsed="false"]) .submenu-trigger-icon {
123
+ transform: rotate(90deg);
124
+ }
125
+
126
+ /* === Submenu Content Container === */
127
+
128
+ .submenu-content {
129
+ display: flex;
130
+ flex-direction: column;
131
+ list-style: none;
132
+ margin: 0;
133
+ padding: 0;
134
+ gap: var(--sidebar-gap, 0.5rem);
135
+ max-height: auto;
136
+ overflow: hidden;
137
+ transition: max-height var(--sidebar-transition, 200ms) ease-out,
138
+ opacity var(--sidebar-transition, 200ms) ease-out;
139
+ }
140
+
141
+ .submenu-content ul {
142
+ display: flex;
143
+ flex-direction: column;
144
+ gap: var(--sidebar-gap, 0.5rem);
145
+ list-style: none;
146
+ margin: 0;
147
+ padding: 0;
148
+ width: 100%;
149
+ }
150
+
151
+ /* When submenu is collapsed, hide content with animation */
152
+ :host([data-collapsed="true"]) .submenu-content {
153
+ max-height: 0;
154
+ opacity: 0;
155
+ overflow: hidden;
156
+ margin-bottom: 0;
157
+ }
158
+
159
+ /* When submenu is expanded, show content */
160
+ :host([data-collapsed="false"]) .submenu-content {
161
+ max-height: 10000px;
162
+ opacity: 1;
163
+ overflow: visible;
164
+ }
165
+
166
+ /* === Tooltip/Hover Behavior for Icon-Only Mode === */
167
+
168
+ /* When parent sidebar is in icon-only mode, show tooltip on hover */
169
+ :host-context(seki-sidebar[data-collapse-mode="icon"]) .submenu-trigger::after {
170
+ content: attr(title);
171
+ position: absolute;
172
+ left: calc(100% + 0.5rem);
173
+ top: 50%;
174
+ transform: translateY(-50%);
175
+ background-color: var(--sidebar-tooltip-bg, #1f2937);
176
+ color: var(--sidebar-tooltip-text, #ffffff);
177
+ padding: 0.375rem 0.625rem;
178
+ border-radius: var(--sidebar-radius-sm, 0.25rem);
179
+ white-space: nowrap;
180
+ z-index: 1000;
181
+ opacity: 0;
182
+ pointer-events: none;
183
+ transition: opacity var(--sidebar-transition, 200ms) ease-out;
184
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
185
+ /* Use built-in typography */
186
+ font-size: var(--seki-font-size-xs);
187
+ font-weight: var(--seki-font-weight-medium);
188
+ font-family: var(--seki-font-sans);
189
+ }
190
+
191
+ :host-context(seki-sidebar[data-theme="dark"]) .submenu-trigger::after {
192
+ background-color: var(--sidebar-tooltip-bg-dark, #27272a);
193
+ color: var(--sidebar-tooltip-text-dark, #fafafa);
194
+ }
195
+
196
+ :host-context(seki-sidebar[data-collapse-mode="icon"]) .submenu-trigger:hover::after,
197
+ :host-context(seki-sidebar[data-collapse-mode="icon"]) .submenu-trigger:focus-visible::after {
198
+ opacity: 1;
199
+ }
200
+
201
+ /* === Animations === */
202
+
203
+ @keyframes slideDown {
204
+ from {
205
+ opacity: 0;
206
+ max-height: 0;
207
+ margin-bottom: 0;
208
+ }
209
+ to {
210
+ opacity: 1;
211
+ max-height: 10000px;
212
+ margin-bottom: 0;
213
+ }
214
+ }
215
+
216
+ @keyframes slideUp {
217
+ from {
218
+ opacity: 1;
219
+ max-height: 10000px;
220
+ margin-bottom: 0;
221
+ }
222
+ to {
223
+ opacity: 0;
224
+ max-height: 0;
225
+ margin-bottom: 0;
226
+ }
227
+ }
228
+
229
+ /* === Print Styles === */
230
+
231
+ @media print {
232
+ .submenu-trigger-icon {
233
+ display: none;
234
+ }
235
+
236
+ :host([data-collapsed="true"]) .submenu-content {
237
+ max-height: none !important;
238
+ opacity: 1 !important;
239
+ overflow: visible !important;
240
+ display: block !important;
241
+ }
242
+ }
243
+
244
+ /* === High Contrast Mode Support === */
245
+
246
+ @media (prefers-contrast: more) {
247
+ .submenu-trigger {
248
+ border: 1px solid transparent;
249
+ }
250
+
251
+ .submenu-trigger:focus-visible {
252
+ border-color: var(--sidebar-primary, #3b82f6);
253
+ }
254
+
255
+ .submenu-trigger-icon {
256
+ border: 1px solid currentColor;
257
+ border-radius: 2px;
258
+ }
259
+ }
260
+
261
+ /* === Reduced Motion Support === */
262
+
263
+ @media (prefers-reduced-motion: reduce) {
264
+ .submenu-trigger,
265
+ .submenu-trigger-icon,
266
+ .submenu-trigger-text,
267
+ .submenu-content {
268
+ transition: none;
269
+ animation: none;
270
+ }
271
+ }
272
+
273
+ /* === Mobile/Responsive Adjustments === */
274
+
275
+ @media (max-width: 768px) {
276
+ .submenu-wrapper {
277
+ margin-left: var(--sidebar-submenu-indent-mobile, 0.75rem);
278
+ }
279
+
280
+ .submenu-trigger-label {
281
+ width: 1rem;
282
+ height: 1rem;
283
+ }
284
+
285
+ .submenu-trigger {
286
+ padding: var(--sidebar-item-padding-mobile, 0.5rem 0.5rem);
287
+ }
288
+
289
+ /* On mobile, when sidebar is in icon mode, show tooltip below instead of to the right */
290
+ :host-context(seki-sidebar[data-collapse-mode="icon"]) .submenu-trigger::after {
291
+ left: 50%;
292
+ top: calc(100% + 0.25rem);
293
+ transform: translateX(-50%);
294
+ }
295
+ }
296
+
297
+ /* ============================================================================
298
+ Floating Variant Submenu Styles
299
+ ============================================================================ */
300
+
301
+ /* When parent sidebar is floating variant, submenus display as popovers */
302
+ :host-context(seki-sidebar[data-variant="floating"]) .submenu-wrapper {
303
+ position: relative;
304
+ }
305
+
306
+ :host-context(seki-sidebar[data-variant="floating"]) .submenu-content {
307
+ position: absolute;
308
+ top: 0;
309
+ left: calc(100% + 0.25rem);
310
+ min-width: 200px;
311
+ background-color: var(--sidebar-bg, #f9fafb);
312
+ border: 1px solid var(--sidebar-border, #e5e7eb);
313
+ border-radius: var(--sidebar-radius-sm, 0.375rem);
314
+ box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
315
+ z-index: 1000;
316
+ padding: var(--sidebar-padding, 0.5rem);
317
+ margin: 0;
318
+ }
319
+
320
+ :host-context(seki-sidebar[data-variant="floating"][data-theme="dark"]) .submenu-content {
321
+ background-color: var(--sidebar-bg-dark, #1f2937);
322
+ border-color: var(--sidebar-border-dark, #374151);
323
+ }
324
+
325
+ /* When collapsed in floating variant, hide the popover */
326
+ :host-context(seki-sidebar[data-variant="floating"]) :host([data-collapsed="true"]) .submenu-content {
327
+ opacity: 0;
328
+ visibility: hidden;
329
+ pointer-events: none;
330
+ transition: opacity var(--sidebar-transition, 200ms) ease-out,
331
+ visibility var(--sidebar-transition, 200ms) ease-out;
332
+ }
333
+
334
+ /* When expanded in floating variant, show the popover */
335
+ :host-context(seki-sidebar[data-variant="floating"]) :host([data-collapsed="false"]) .submenu-content {
336
+ opacity: 1;
337
+ visibility: visible;
338
+ pointer-events: auto;
339
+ transition: opacity var(--sidebar-transition, 200ms) ease-out,
340
+ visibility var(--sidebar-transition, 200ms) ease-out;
341
+ }
342
+
343
+ /* Remove indentation for floating variant submenus since they're positioned absolutely */
344
+ :host-context(seki-sidebar[data-variant="floating"]) .submenu-wrapper {
345
+ margin-left: 0;
346
+ }
347
+
348
+ /* Adjust submenu content layout for floating variant */
349
+ :host-context(seki-sidebar[data-variant="floating"]) .submenu-content ul {
350
+ flex-direction: column;
351
+ gap: var(--sidebar-gap, 0.5rem);
352
+ }
353
+
354
+ /* Floating variant submenu items should have slightly different styling */
355
+ :host-context(seki-sidebar[data-variant="floating"]) .submenu-content li {
356
+ width: 100%;
357
+ }
@@ -0,0 +1,256 @@
1
+ /**
2
+ * SekiSidebarMenuSub Component
3
+ * @description Nested submenu container for collapsible menu items
4
+ * Provides expandable/collapsible sub-navigation structure with support for:
5
+ * - Multi-level nesting (unlimited depth)
6
+ * - Smooth animations (200ms transitions)
7
+ * - Icon-only display when parent sidebar is collapsed
8
+ * - Tooltip support for collapsed state
9
+ * - Full keyboard navigation and accessibility
10
+ * @component
11
+ * @example
12
+ * <seki-sidebar-menu-item>
13
+ * <span slot="icon">⚙️</span>
14
+ * Settings
15
+ * <seki-sidebar-menu-sub slot="submenu">
16
+ * <seki-sidebar-menu-item href="/settings/profile">
17
+ * <span slot="icon">👤</span>
18
+ * Profile
19
+ * </seki-sidebar-menu-item>
20
+ * <seki-sidebar-menu-item href="/settings/security">
21
+ * <span slot="icon">🔒</span>
22
+ * Security
23
+ * </seki-sidebar-menu-item>
24
+ * </seki-sidebar-menu-sub>
25
+ * </seki-sidebar-menu-item>
26
+ */
27
+ import { h, Host } from "@stencil/core";
28
+ export class SekiSidebarMenuSub {
29
+ constructor() {
30
+ /**
31
+ * Initial collapsed state
32
+ * @type {boolean}
33
+ * @default false
34
+ */
35
+ this.defaultCollapsed = false;
36
+ /**
37
+ * Internal state: whether submenu is collapsed
38
+ */
39
+ this.isCollapsed = false;
40
+ /**
41
+ * Toggle collapsed state
42
+ */
43
+ this.handleToggle = () => {
44
+ this.isCollapsed = !this.isCollapsed;
45
+ this.collapsedChange.emit({ isCollapsed: this.isCollapsed });
46
+ };
47
+ /**
48
+ * Handle keyboard navigation
49
+ * - Enter: toggle submenu
50
+ * - ArrowDown: focus next submenu item
51
+ * - ArrowUp: focus previous submenu item
52
+ * - Escape: close submenu
53
+ */
54
+ this.handleKeyDown = (event) => {
55
+ const content = this.el.querySelector('.submenu-content');
56
+ const items = content ? Array.from(content.querySelectorAll('[role="menuitem"], a, button')) : [];
57
+ switch (event.key) {
58
+ case 'Enter':
59
+ case ' ':
60
+ event.preventDefault();
61
+ this.handleToggle();
62
+ break;
63
+ case 'ArrowDown':
64
+ event.preventDefault();
65
+ if (!this.isCollapsed && items.length > 0) {
66
+ items[0].focus();
67
+ }
68
+ break;
69
+ case 'ArrowUp':
70
+ event.preventDefault();
71
+ if (!this.isCollapsed && items.length > 0) {
72
+ items[items.length - 1].focus();
73
+ }
74
+ break;
75
+ case 'Escape':
76
+ event.preventDefault();
77
+ if (!this.isCollapsed) {
78
+ this.isCollapsed = true;
79
+ this.collapsedChange.emit({ isCollapsed: true });
80
+ }
81
+ break;
82
+ }
83
+ };
84
+ }
85
+ /**
86
+ * Component lifecycle: initialize state
87
+ */
88
+ componentWillLoad() {
89
+ this.isCollapsed = Boolean(this.defaultCollapsed);
90
+ }
91
+ /**
92
+ * Get current collapsed state
93
+ */
94
+ async isCollapsedState() {
95
+ return Boolean(this.isCollapsed);
96
+ }
97
+ /**
98
+ * Set collapsed state
99
+ */
100
+ async setCollapsed(collapsed) {
101
+ this.isCollapsed = collapsed;
102
+ this.collapsedChange.emit({ isCollapsed: collapsed });
103
+ }
104
+ /**
105
+ * Render the component
106
+ */
107
+ render() {
108
+ const labelText = this.label || 'Submenu';
109
+ return (h(Host, { key: '1779e6c0bce966ec710bc019ae6ed4067df3d302', "data-collapsed": this.isCollapsed }, h("div", { key: '254328133fd704ab7d93e51cc1a76eb393c00354', class: "submenu-wrapper" }, h("button", { key: '61b3185705e444d6aa53f10dc7357b7f564dfdc9', class: "submenu-trigger", "aria-expanded": !this.isCollapsed, "aria-label": `Toggle ${labelText}`, "aria-controls": "submenu-content", onClick: this.handleToggle, onKeyDown: this.handleKeyDown, type: "button", title: labelText }, h("span", { key: '4ad58cc92ea8287d8811144089ad50c007625c8c', class: "submenu-trigger-label" }, h("slot", { key: '951b2e27a90c1bdcecc3bf1ec056b20085d1f502', name: "icon" })), h("span", { key: '24f5aa65777c565af787cdcfab3b850938c2e028', class: "submenu-trigger-text" }, this.label), h("span", { key: '3409c122f0315c82df9bc838e80838829b9546f0', class: "submenu-trigger-icon", "aria-hidden": "true" }, "\u25B6")), h("div", { key: 'fc369580c63d58790327494c39d29cb714ef4d30', id: "submenu-content", class: "submenu-content", role: "region", "aria-hidden": this.isCollapsed, "aria-label": `${labelText} submenu`, style: {
110
+ maxHeight: this.isCollapsed ? '0' : 'auto',
111
+ overflow: this.isCollapsed ? 'hidden' : 'visible',
112
+ } }, h("ul", { key: 'aca9bc1c8ff43de9fb0c45c86b0b0bca25525940', role: "menu" }, h("slot", { key: '6ccc8c3738fd3232e775d1b61ff5f342435bee18' }))))));
113
+ }
114
+ static get is() { return "seki-sidebar-menu-sub"; }
115
+ static get encapsulation() { return "scoped"; }
116
+ static get originalStyleUrls() {
117
+ return {
118
+ "$": ["seki-sidebar-menu-sub.css"]
119
+ };
120
+ }
121
+ static get styleUrls() {
122
+ return {
123
+ "$": ["seki-sidebar-menu-sub.css"]
124
+ };
125
+ }
126
+ static get properties() {
127
+ return {
128
+ "label": {
129
+ "type": "string",
130
+ "mutable": false,
131
+ "complexType": {
132
+ "original": "SidebarMenuSubProps['label']",
133
+ "resolved": "string | undefined",
134
+ "references": {
135
+ "SidebarMenuSubProps": {
136
+ "location": "import",
137
+ "path": "./types",
138
+ "id": "src/components/sidebar/types.ts::SidebarMenuSubProps"
139
+ }
140
+ }
141
+ },
142
+ "required": false,
143
+ "optional": true,
144
+ "docs": {
145
+ "tags": [{
146
+ "name": "type",
147
+ "text": "{string}"
148
+ }],
149
+ "text": "Label for the submenu (shown when expanded)"
150
+ },
151
+ "getter": false,
152
+ "setter": false,
153
+ "reflect": false,
154
+ "attribute": "label"
155
+ },
156
+ "defaultCollapsed": {
157
+ "type": "boolean",
158
+ "mutable": false,
159
+ "complexType": {
160
+ "original": "boolean",
161
+ "resolved": "boolean",
162
+ "references": {}
163
+ },
164
+ "required": false,
165
+ "optional": false,
166
+ "docs": {
167
+ "tags": [{
168
+ "name": "type",
169
+ "text": "{boolean}"
170
+ }, {
171
+ "name": "default",
172
+ "text": "false"
173
+ }],
174
+ "text": "Initial collapsed state"
175
+ },
176
+ "getter": false,
177
+ "setter": false,
178
+ "reflect": true,
179
+ "attribute": "default-collapsed",
180
+ "defaultValue": "false"
181
+ }
182
+ };
183
+ }
184
+ static get states() {
185
+ return {
186
+ "isCollapsed": {}
187
+ };
188
+ }
189
+ static get events() {
190
+ return [{
191
+ "method": "collapsedChange",
192
+ "name": "collapsedChange",
193
+ "bubbles": true,
194
+ "cancelable": true,
195
+ "composed": true,
196
+ "docs": {
197
+ "tags": [],
198
+ "text": "Event fired when collapsed state changes"
199
+ },
200
+ "complexType": {
201
+ "original": "CollapsedChangeDetail",
202
+ "resolved": "CollapsedChangeDetail",
203
+ "references": {
204
+ "CollapsedChangeDetail": {
205
+ "location": "import",
206
+ "path": "./types",
207
+ "id": "src/components/sidebar/types.ts::CollapsedChangeDetail"
208
+ }
209
+ }
210
+ }
211
+ }];
212
+ }
213
+ static get methods() {
214
+ return {
215
+ "isCollapsedState": {
216
+ "complexType": {
217
+ "signature": "() => Promise<boolean>",
218
+ "parameters": [],
219
+ "references": {
220
+ "Promise": {
221
+ "location": "global",
222
+ "id": "global::Promise"
223
+ }
224
+ },
225
+ "return": "Promise<boolean>"
226
+ },
227
+ "docs": {
228
+ "text": "Get current collapsed state",
229
+ "tags": []
230
+ }
231
+ },
232
+ "setCollapsed": {
233
+ "complexType": {
234
+ "signature": "(collapsed: boolean) => Promise<void>",
235
+ "parameters": [{
236
+ "name": "collapsed",
237
+ "type": "boolean",
238
+ "docs": ""
239
+ }],
240
+ "references": {
241
+ "Promise": {
242
+ "location": "global",
243
+ "id": "global::Promise"
244
+ }
245
+ },
246
+ "return": "Promise<void>"
247
+ },
248
+ "docs": {
249
+ "text": "Set collapsed state",
250
+ "tags": []
251
+ }
252
+ }
253
+ };
254
+ }
255
+ static get elementRef() { return "el"; }
256
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * SekiSidebarMenu CSS
3
+ * Styling for menu lists within the sidebar
4
+ */
5
+
6
+ :host {
7
+ display: block;
8
+ width: 100%;
9
+ }
10
+
11
+ .menu-list {
12
+ display: flex;
13
+ flex-direction: column;
14
+ list-style: none;
15
+ margin: 0;
16
+ padding: 0;
17
+ gap: var(--sidebar-gap, 0.5rem);
18
+ }
19
+
20
+ /* Print styles */
21
+ @media print {
22
+ :host {
23
+ display: block;
24
+ }
25
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * SekiSidebarMenu Component
3
+ * @description List container for menu items within a sidebar
4
+ * Provides semantic menu structure with proper ARIA attributes
5
+ * @component
6
+ * @example
7
+ * <seki-sidebar-menu>
8
+ * <seki-sidebar-menu-item href="/dashboard">Dashboard</seki-sidebar-menu-item>
9
+ * <seki-sidebar-menu-item href="/settings">Settings</seki-sidebar-menu-item>
10
+ * </seki-sidebar-menu>
11
+ */
12
+ import { h, Host } from "@stencil/core";
13
+ export class SekiSidebarMenu {
14
+ /**
15
+ * Render the component
16
+ */
17
+ render() {
18
+ return (h(Host, { key: '542879d57e0282876798877a04613a178b316d79', role: "navigation" }, h("ul", { key: 'cddecf985ef93eb6f7dac920867cbcfa7fc90eaf', class: "menu-list" }, h("slot", { key: '52781b245fc5dc54e90f9b90c3afa38efbccbac0' }))));
19
+ }
20
+ static get is() { return "seki-sidebar-menu"; }
21
+ static get encapsulation() { return "scoped"; }
22
+ static get originalStyleUrls() {
23
+ return {
24
+ "$": ["seki-sidebar-menu.css"]
25
+ };
26
+ }
27
+ static get styleUrls() {
28
+ return {
29
+ "$": ["seki-sidebar-menu.css"]
30
+ };
31
+ }
32
+ }