@sekiui/elements 0.0.55 → 0.0.57

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 (298) hide show
  1. package/dist/cdn/index.js +1053 -91
  2. package/dist/cdn/p-BJCq8m2o.js +138 -0
  3. package/dist/cdn/p-BfRJQMIU.js +111 -0
  4. package/dist/cdn/{p-bMBhrs0a.js → p-Bp7tjKwQ.js} +427 -7
  5. package/dist/cdn/seki-button.js +1 -1
  6. package/dist/cdn/seki-card-action.d.ts +11 -0
  7. package/dist/cdn/seki-card-action.js +38 -0
  8. package/dist/cdn/seki-card-content.d.ts +11 -0
  9. package/dist/cdn/seki-card-content.js +38 -0
  10. package/dist/cdn/seki-card-description.d.ts +11 -0
  11. package/dist/cdn/seki-card-description.js +38 -0
  12. package/dist/cdn/seki-card-footer.d.ts +11 -0
  13. package/dist/cdn/seki-card-footer.js +44 -0
  14. package/dist/cdn/seki-card-header.d.ts +11 -0
  15. package/dist/cdn/seki-card-header.js +38 -0
  16. package/dist/cdn/seki-card-title.d.ts +11 -0
  17. package/dist/cdn/seki-card-title.js +59 -0
  18. package/dist/cdn/seki-card.d.ts +11 -0
  19. package/dist/cdn/seki-card.js +39 -0
  20. package/dist/cdn/seki-field-description.js +2 -2
  21. package/dist/cdn/seki-field-error.js +2 -2
  22. package/dist/cdn/seki-field-group.js +2 -2
  23. package/dist/cdn/seki-field-label.js +2 -2
  24. package/dist/cdn/seki-field-legend.js +2 -2
  25. package/dist/cdn/seki-field.js +2 -2
  26. package/dist/cdn/seki-fieldset.js +2 -2
  27. package/dist/cdn/seki-input.js +2 -2
  28. package/dist/cdn/seki-select-content.js +1 -1
  29. package/dist/cdn/seki-select-group.js +2 -2
  30. package/dist/cdn/seki-select-option.js +2 -2
  31. package/dist/cdn/seki-select-trigger.js +1 -1
  32. package/dist/cdn/seki-select.js +2 -2
  33. package/dist/cdn/seki-sidebar-content.d.ts +11 -0
  34. package/dist/cdn/seki-sidebar-content.js +38 -0
  35. package/dist/cdn/seki-sidebar-footer.d.ts +11 -0
  36. package/dist/cdn/seki-sidebar-footer.js +38 -0
  37. package/dist/cdn/seki-sidebar-group.d.ts +11 -0
  38. package/dist/cdn/seki-sidebar-group.js +131 -0
  39. package/dist/cdn/seki-sidebar-header.d.ts +11 -0
  40. package/dist/cdn/seki-sidebar-header.js +38 -0
  41. package/dist/cdn/seki-sidebar-menu-item.d.ts +11 -0
  42. package/dist/cdn/seki-sidebar-menu-item.js +200 -0
  43. package/dist/cdn/seki-sidebar-menu-sub.d.ts +11 -0
  44. package/dist/cdn/seki-sidebar-menu-sub.js +123 -0
  45. package/dist/cdn/seki-sidebar-menu.d.ts +11 -0
  46. package/dist/cdn/seki-sidebar-menu.js +38 -0
  47. package/dist/cdn/seki-sidebar-trigger.d.ts +11 -0
  48. package/dist/cdn/seki-sidebar-trigger.js +109 -0
  49. package/dist/cdn/seki-sidebar.d.ts +11 -0
  50. package/dist/cdn/seki-sidebar.js +380 -0
  51. package/dist/cdn/seki-skeleton.js +2 -2
  52. package/dist/cdn/seki-switch.js +1 -1
  53. package/dist/cdn/seki-tooltip.js +1 -1
  54. package/dist/cjs/{index-Dd6_-KaR.js → index-tQYksITZ.js} +426 -6
  55. package/dist/cjs/index.cjs.js +1115 -63
  56. package/dist/cjs/keyboard-Cjl5HYES.js +142 -0
  57. package/dist/cjs/loader.cjs.js +2 -2
  58. package/dist/cjs/seki-button.cjs.entry.js +1 -1
  59. package/dist/cjs/seki-card-action.cjs.entry.js +17 -0
  60. package/dist/cjs/seki-card-content.cjs.entry.js +17 -0
  61. package/dist/cjs/seki-card-description.cjs.entry.js +17 -0
  62. package/dist/cjs/seki-card-footer.cjs.entry.js +22 -0
  63. package/dist/cjs/seki-card-header.cjs.entry.js +17 -0
  64. package/dist/cjs/seki-card-title.cjs.entry.js +37 -0
  65. package/dist/cjs/seki-card.cjs.entry.js +17 -0
  66. package/dist/cjs/seki-field-description.cjs.entry.js +2 -2
  67. package/dist/cjs/seki-field-error.cjs.entry.js +2 -2
  68. package/dist/cjs/seki-field-group.cjs.entry.js +2 -2
  69. package/dist/cjs/seki-field-label.cjs.entry.js +2 -2
  70. package/dist/cjs/seki-field-legend.cjs.entry.js +2 -2
  71. package/dist/cjs/seki-field.cjs.entry.js +2 -2
  72. package/dist/cjs/seki-fieldset.cjs.entry.js +2 -2
  73. package/dist/cjs/seki-input.cjs.entry.js +2 -2
  74. package/dist/cjs/seki-select-content.cjs.entry.js +1 -1
  75. package/dist/cjs/seki-select-group.cjs.entry.js +2 -2
  76. package/dist/cjs/seki-select-option.cjs.entry.js +2 -2
  77. package/dist/cjs/seki-select-trigger.cjs.entry.js +1 -1
  78. package/dist/cjs/seki-select.cjs.entry.js +2 -2
  79. package/dist/cjs/seki-sidebar-content.cjs.entry.js +20 -0
  80. package/dist/cjs/seki-sidebar-footer.cjs.entry.js +20 -0
  81. package/dist/cjs/seki-sidebar-group.cjs.entry.js +105 -0
  82. package/dist/cjs/seki-sidebar-header.cjs.entry.js +20 -0
  83. package/dist/cjs/seki-sidebar-menu-item.cjs.entry.js +174 -0
  84. package/dist/cjs/seki-sidebar-menu-sub.cjs.entry.js +99 -0
  85. package/dist/cjs/seki-sidebar-menu.cjs.entry.js +20 -0
  86. package/dist/cjs/seki-sidebar-trigger.cjs.entry.js +86 -0
  87. package/dist/cjs/seki-sidebar.cjs.entry.js +342 -0
  88. package/dist/cjs/seki-skeleton.cjs.entry.js +2 -2
  89. package/dist/cjs/seki-switch.cjs.entry.js +81 -3
  90. package/dist/cjs/seki-tooltip.cjs.entry.js +1 -1
  91. package/dist/cjs/sekiui.cjs.js +2 -2
  92. package/dist/collection/collection-manifest.json +16 -0
  93. package/dist/collection/components/card/seki-card-action.js +50 -0
  94. package/dist/collection/components/card/seki-card-content.js +51 -0
  95. package/dist/collection/components/card/seki-card-description.js +48 -0
  96. package/dist/collection/components/card/seki-card-footer.js +83 -0
  97. package/dist/collection/components/card/seki-card-header.js +54 -0
  98. package/dist/collection/components/card/seki-card-title.js +95 -0
  99. package/dist/collection/components/card/seki-card.a11y.js +363 -0
  100. package/dist/collection/components/card/seki-card.css +608 -0
  101. package/dist/collection/components/card/seki-card.js +72 -0
  102. package/dist/collection/components/field/seki-field.js +1 -1
  103. package/dist/collection/components/field-description/seki-field-description.js +1 -1
  104. package/dist/collection/components/field-error/seki-field-error.js +1 -1
  105. package/dist/collection/components/field-group/seki-field-group.js +1 -1
  106. package/dist/collection/components/field-label/seki-field-label.js +1 -1
  107. package/dist/collection/components/field-legend/seki-field-legend.js +1 -1
  108. package/dist/collection/components/fieldset/seki-fieldset.js +1 -1
  109. package/dist/collection/components/input/seki-input.js +1 -1
  110. package/dist/collection/components/select/seki-select.js +1 -1
  111. package/dist/collection/components/select-group/seki-select-group.js +1 -1
  112. package/dist/collection/components/select-option/seki-select-option.js +1 -1
  113. package/dist/collection/components/sidebar/seki-sidebar-content.css +82 -0
  114. package/dist/collection/components/sidebar/seki-sidebar-content.js +33 -0
  115. package/dist/collection/components/sidebar/seki-sidebar-footer.css +44 -0
  116. package/dist/collection/components/sidebar/seki-sidebar-footer.js +31 -0
  117. package/dist/collection/components/sidebar/seki-sidebar-group.css +158 -0
  118. package/dist/collection/components/sidebar/seki-sidebar-group.js +300 -0
  119. package/dist/collection/components/sidebar/seki-sidebar-header.css +44 -0
  120. package/dist/collection/components/sidebar/seki-sidebar-header.js +32 -0
  121. package/dist/collection/components/sidebar/seki-sidebar-menu-item.css +196 -0
  122. package/dist/collection/components/sidebar/seki-sidebar-menu-item.js +403 -0
  123. package/dist/collection/components/sidebar/seki-sidebar-menu-sub.css +357 -0
  124. package/dist/collection/components/sidebar/seki-sidebar-menu-sub.js +256 -0
  125. package/dist/collection/components/sidebar/seki-sidebar-menu.css +25 -0
  126. package/dist/collection/components/sidebar/seki-sidebar-menu.js +32 -0
  127. package/dist/collection/components/sidebar/seki-sidebar-trigger.css +68 -0
  128. package/dist/collection/components/sidebar/seki-sidebar-trigger.js +175 -0
  129. package/dist/collection/components/sidebar/seki-sidebar.css +352 -0
  130. package/dist/collection/components/sidebar/seki-sidebar.js +812 -0
  131. package/dist/collection/components/sidebar/types.js +18 -0
  132. package/dist/collection/components/skeleton/seki-skeleton.js +1 -1
  133. package/dist/collection/index.js +7 -0
  134. package/dist/collection/services/focus.js +192 -0
  135. package/dist/collection/services/index.js +7 -0
  136. package/dist/collection/services/keyboard.js +136 -0
  137. package/dist/collection/services/media-query.js +254 -0
  138. package/dist/collection/types.js +41 -0
  139. package/dist/collection/utils/a11y.js +291 -0
  140. package/dist/collection/utils/common.js +286 -0
  141. package/dist/components/index.js +1053 -91
  142. package/dist/components/p-BJCq8m2o.js +138 -0
  143. package/dist/components/{p-QhPshhKB.js → p-BzYKy7d3.js} +427 -7
  144. package/dist/components/p-DwTISp-i.js +111 -0
  145. package/dist/components/seki-button.js +1 -1
  146. package/dist/components/seki-card-action.d.ts +11 -0
  147. package/dist/components/seki-card-action.js +38 -0
  148. package/dist/components/seki-card-content.d.ts +11 -0
  149. package/dist/components/seki-card-content.js +38 -0
  150. package/dist/components/seki-card-description.d.ts +11 -0
  151. package/dist/components/seki-card-description.js +38 -0
  152. package/dist/components/seki-card-footer.d.ts +11 -0
  153. package/dist/components/seki-card-footer.js +44 -0
  154. package/dist/components/seki-card-header.d.ts +11 -0
  155. package/dist/components/seki-card-header.js +38 -0
  156. package/dist/components/seki-card-title.d.ts +11 -0
  157. package/dist/components/seki-card-title.js +59 -0
  158. package/dist/components/seki-card.d.ts +11 -0
  159. package/dist/components/seki-card.js +39 -0
  160. package/dist/components/seki-field-description.js +2 -2
  161. package/dist/components/seki-field-error.js +2 -2
  162. package/dist/components/seki-field-group.js +2 -2
  163. package/dist/components/seki-field-label.js +2 -2
  164. package/dist/components/seki-field-legend.js +2 -2
  165. package/dist/components/seki-field.js +2 -2
  166. package/dist/components/seki-fieldset.js +2 -2
  167. package/dist/components/seki-input.js +2 -2
  168. package/dist/components/seki-select-content.js +1 -1
  169. package/dist/components/seki-select-group.js +2 -2
  170. package/dist/components/seki-select-option.js +2 -2
  171. package/dist/components/seki-select-trigger.js +1 -1
  172. package/dist/components/seki-select.js +2 -2
  173. package/dist/components/seki-sidebar-content.d.ts +11 -0
  174. package/dist/components/seki-sidebar-content.js +38 -0
  175. package/dist/components/seki-sidebar-footer.d.ts +11 -0
  176. package/dist/components/seki-sidebar-footer.js +38 -0
  177. package/dist/components/seki-sidebar-group.d.ts +11 -0
  178. package/dist/components/seki-sidebar-group.js +131 -0
  179. package/dist/components/seki-sidebar-header.d.ts +11 -0
  180. package/dist/components/seki-sidebar-header.js +38 -0
  181. package/dist/components/seki-sidebar-menu-item.d.ts +11 -0
  182. package/dist/components/seki-sidebar-menu-item.js +200 -0
  183. package/dist/components/seki-sidebar-menu-sub.d.ts +11 -0
  184. package/dist/components/seki-sidebar-menu-sub.js +123 -0
  185. package/dist/components/seki-sidebar-menu.d.ts +11 -0
  186. package/dist/components/seki-sidebar-menu.js +38 -0
  187. package/dist/components/seki-sidebar-trigger.d.ts +11 -0
  188. package/dist/components/seki-sidebar-trigger.js +109 -0
  189. package/dist/components/seki-sidebar.d.ts +11 -0
  190. package/dist/components/seki-sidebar.js +380 -0
  191. package/dist/components/seki-skeleton.js +2 -2
  192. package/dist/components/seki-switch.js +1 -1
  193. package/dist/components/seki-tooltip.js +1 -1
  194. package/dist/esm/{index-CuXbV_yz.js → index-Dfzpqq0a.js} +426 -6
  195. package/dist/esm/index.js +1053 -63
  196. package/dist/esm/keyboard-BJCq8m2o.js +138 -0
  197. package/dist/esm/loader.js +3 -3
  198. package/dist/esm/seki-button.entry.js +1 -1
  199. package/dist/esm/seki-card-action.entry.js +15 -0
  200. package/dist/esm/seki-card-content.entry.js +15 -0
  201. package/dist/esm/seki-card-description.entry.js +15 -0
  202. package/dist/esm/seki-card-footer.entry.js +20 -0
  203. package/dist/esm/seki-card-header.entry.js +15 -0
  204. package/dist/esm/seki-card-title.entry.js +35 -0
  205. package/dist/esm/seki-card.entry.js +15 -0
  206. package/dist/esm/seki-field-description.entry.js +2 -2
  207. package/dist/esm/seki-field-error.entry.js +2 -2
  208. package/dist/esm/seki-field-group.entry.js +2 -2
  209. package/dist/esm/seki-field-label.entry.js +2 -2
  210. package/dist/esm/seki-field-legend.entry.js +2 -2
  211. package/dist/esm/seki-field.entry.js +2 -2
  212. package/dist/esm/seki-fieldset.entry.js +2 -2
  213. package/dist/esm/seki-input.entry.js +2 -2
  214. package/dist/esm/seki-select-content.entry.js +1 -1
  215. package/dist/esm/seki-select-group.entry.js +2 -2
  216. package/dist/esm/seki-select-option.entry.js +2 -2
  217. package/dist/esm/seki-select-trigger.entry.js +1 -1
  218. package/dist/esm/seki-select.entry.js +2 -2
  219. package/dist/esm/seki-sidebar-content.entry.js +18 -0
  220. package/dist/esm/seki-sidebar-footer.entry.js +18 -0
  221. package/dist/esm/seki-sidebar-group.entry.js +103 -0
  222. package/dist/esm/seki-sidebar-header.entry.js +18 -0
  223. package/dist/esm/seki-sidebar-menu-item.entry.js +172 -0
  224. package/dist/esm/seki-sidebar-menu-sub.entry.js +97 -0
  225. package/dist/esm/seki-sidebar-menu.entry.js +18 -0
  226. package/dist/esm/seki-sidebar-trigger.entry.js +84 -0
  227. package/dist/esm/seki-sidebar.entry.js +340 -0
  228. package/dist/esm/seki-skeleton.entry.js +2 -2
  229. package/dist/esm/seki-switch.entry.js +84 -2
  230. package/dist/esm/seki-tooltip.entry.js +1 -1
  231. package/dist/esm/sekiui.js +3 -3
  232. package/dist/sekiui/index.esm.js +1 -1
  233. package/dist/sekiui/p-01cfb4e7.entry.js +1 -0
  234. package/dist/sekiui/{p-431f46a1.entry.js → p-042ec460.entry.js} +1 -1
  235. package/dist/sekiui/{p-a36f1ac4.entry.js → p-10c008fc.entry.js} +1 -1
  236. package/dist/sekiui/p-352bd295.entry.js +1 -0
  237. package/dist/sekiui/p-37c5f4d9.entry.js +1 -0
  238. package/dist/sekiui/p-40fb71d6.entry.js +1 -0
  239. package/dist/sekiui/{p-eefbc037.entry.js → p-44191aed.entry.js} +1 -1
  240. package/dist/sekiui/{p-81709fc2.entry.js → p-4423d621.entry.js} +1 -1
  241. package/dist/sekiui/{p-e679d501.entry.js → p-4636588f.entry.js} +1 -1
  242. package/dist/sekiui/p-471b97a5.entry.js +1 -0
  243. package/dist/sekiui/{p-de4735fb.entry.js → p-56f0d754.entry.js} +1 -1
  244. package/dist/sekiui/p-5bc0f5aa.entry.js +1 -0
  245. package/dist/sekiui/p-6164cd8a.entry.js +1 -0
  246. package/dist/sekiui/{p-0fba4e2d.entry.js → p-635f4098.entry.js} +1 -1
  247. package/dist/sekiui/{p-434be19f.entry.js → p-743fc6d9.entry.js} +1 -1
  248. package/dist/sekiui/p-83e65cbe.entry.js +1 -0
  249. package/dist/sekiui/p-8b7bd061.entry.js +1 -0
  250. package/dist/sekiui/p-8d9a4878.entry.js +1 -0
  251. package/dist/sekiui/p-9cb9cdfe.entry.js +1 -0
  252. package/dist/sekiui/p-9f2d95d7.entry.js +1 -0
  253. package/dist/sekiui/p-BJCq8m2o.js +1 -0
  254. package/dist/sekiui/p-Dfzpqq0a.js +2 -0
  255. package/dist/sekiui/p-a1a71958.entry.js +1 -0
  256. package/dist/sekiui/{p-bf942ad5.entry.js → p-a71e0c55.entry.js} +1 -1
  257. package/dist/sekiui/{p-6ff91f7f.entry.js → p-ae227955.entry.js} +1 -1
  258. package/dist/sekiui/{p-80a41058.entry.js → p-b365f5fb.entry.js} +1 -1
  259. package/dist/sekiui/{p-6bde807e.entry.js → p-b387a2a5.entry.js} +1 -1
  260. package/dist/sekiui/p-b8590f4d.entry.js +1 -0
  261. package/dist/sekiui/p-c98b6d6a.entry.js +1 -0
  262. package/dist/sekiui/{p-7c2245be.entry.js → p-d73cdb9a.entry.js} +1 -1
  263. package/dist/sekiui/{p-a56602b3.entry.js → p-d96e770e.entry.js} +1 -1
  264. package/dist/sekiui/p-e62dd89b.entry.js +1 -0
  265. package/dist/sekiui/{p-386c00ac.entry.js → p-e7bb140c.entry.js} +1 -1
  266. package/dist/sekiui/{p-6e238adf.entry.js → p-eecc18f3.entry.js} +1 -1
  267. package/dist/sekiui/p-ff636955.entry.js +1 -0
  268. package/dist/sekiui/sekiui.esm.js +1 -1
  269. package/dist/types/components/card/seki-card-action.d.ts +16 -0
  270. package/dist/types/components/card/seki-card-content.d.ts +17 -0
  271. package/dist/types/components/card/seki-card-description.d.ts +14 -0
  272. package/dist/types/components/card/seki-card-footer.d.ts +24 -0
  273. package/dist/types/components/card/seki-card-header.d.ts +20 -0
  274. package/dist/types/components/card/seki-card-title.d.ts +20 -0
  275. package/dist/types/components/card/seki-card.a11y.d.ts +1 -0
  276. package/dist/types/components/card/seki-card.d.ts +23 -0
  277. package/dist/types/components/sidebar/seki-sidebar-content.d.ts +18 -0
  278. package/dist/types/components/sidebar/seki-sidebar-footer.d.ts +16 -0
  279. package/dist/types/components/sidebar/seki-sidebar-group.d.ts +81 -0
  280. package/dist/types/components/sidebar/seki-sidebar-header.d.ts +17 -0
  281. package/dist/types/components/sidebar/seki-sidebar-menu-item.d.ts +104 -0
  282. package/dist/types/components/sidebar/seki-sidebar-menu-sub.d.ts +81 -0
  283. package/dist/types/components/sidebar/seki-sidebar-menu.d.ts +17 -0
  284. package/dist/types/components/sidebar/seki-sidebar-trigger.d.ts +53 -0
  285. package/dist/types/components/sidebar/seki-sidebar.d.ts +185 -0
  286. package/dist/types/components/sidebar/types.d.ts +245 -0
  287. package/dist/types/components.d.ts +899 -0
  288. package/dist/types/index.d.ts +4 -0
  289. package/dist/types/services/focus.d.ts +74 -0
  290. package/dist/types/services/index.d.ts +7 -0
  291. package/dist/types/services/keyboard.d.ts +74 -0
  292. package/dist/types/services/media-query.d.ts +121 -0
  293. package/dist/types/types.d.ts +105 -0
  294. package/dist/types/utils/a11y.d.ts +130 -0
  295. package/dist/types/utils/common.d.ts +142 -0
  296. package/package.json +2 -1
  297. package/dist/sekiui/p-9fe07f6e.entry.js +0 -1
  298. 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
+ }