luxen-ui 0.3.0 → 0.5.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.
Files changed (385) hide show
  1. package/cdn/chunks/decorate.js +1 -1
  2. package/cdn/chunks/decorate.js.map +1 -1
  3. package/cdn/chunks/map.js +2 -0
  4. package/cdn/chunks/map.js.map +1 -0
  5. package/cdn/custom-elements.json +6707 -4242
  6. package/cdn/elements/avatar/avatar.d.ts +1 -1
  7. package/cdn/elements/avatar/avatar.d.ts.map +1 -1
  8. package/cdn/elements/avatar/avatar.js +3 -3
  9. package/cdn/elements/avatar/avatar.js.map +1 -1
  10. package/cdn/elements/avatar/index.d.ts +2 -2
  11. package/cdn/elements/avatar/index.d.ts.map +1 -1
  12. package/cdn/elements/avatar/index.js +1 -1
  13. package/cdn/elements/avatar/index.js.map +1 -1
  14. package/cdn/elements/badge/badge.d.ts +1 -1
  15. package/cdn/elements/badge/badge.d.ts.map +1 -1
  16. package/cdn/elements/badge/badge.js +1 -1
  17. package/cdn/elements/badge/badge.js.map +1 -1
  18. package/cdn/elements/badge/index.d.ts +2 -2
  19. package/cdn/elements/badge/index.d.ts.map +1 -1
  20. package/cdn/elements/badge/index.js +1 -1
  21. package/cdn/elements/badge/index.js.map +1 -1
  22. package/cdn/elements/carousel/carousel.d.ts +18 -11
  23. package/cdn/elements/carousel/carousel.d.ts.map +1 -1
  24. package/cdn/elements/carousel/carousel.js +21 -20
  25. package/cdn/elements/carousel/carousel.js.map +1 -1
  26. package/cdn/elements/carousel/index.d.ts +2 -2
  27. package/cdn/elements/carousel/index.d.ts.map +1 -1
  28. package/cdn/elements/carousel/index.js +1 -1
  29. package/cdn/elements/carousel/index.js.map +1 -1
  30. package/cdn/elements/carousel-item/carousel-item.d.ts +1 -1
  31. package/cdn/elements/carousel-item/carousel-item.d.ts.map +1 -1
  32. package/cdn/elements/carousel-item/carousel-item.js +1 -1
  33. package/cdn/elements/carousel-item/carousel-item.js.map +1 -1
  34. package/cdn/elements/carousel-item/index.d.ts +2 -2
  35. package/cdn/elements/carousel-item/index.d.ts.map +1 -1
  36. package/cdn/elements/carousel-item/index.js +1 -1
  37. package/cdn/elements/carousel-item/index.js.map +1 -1
  38. package/cdn/elements/dialog/dialog.d.ts +1 -1
  39. package/cdn/elements/dialog/dialog.d.ts.map +1 -1
  40. package/cdn/elements/dialog/dialog.js +2 -2
  41. package/cdn/elements/dialog/dialog.js.map +1 -1
  42. package/cdn/elements/dialog/dialog.styles.js.map +1 -1
  43. package/cdn/elements/dialog/index.d.ts +2 -2
  44. package/cdn/elements/dialog/index.d.ts.map +1 -1
  45. package/cdn/elements/dialog/index.js +1 -1
  46. package/cdn/elements/dialog/index.js.map +1 -1
  47. package/cdn/elements/divider/divider.d.ts +1 -1
  48. package/cdn/elements/divider/divider.d.ts.map +1 -1
  49. package/cdn/elements/divider/divider.js +1 -1
  50. package/cdn/elements/divider/divider.js.map +1 -1
  51. package/cdn/elements/divider/index.d.ts +2 -2
  52. package/cdn/elements/divider/index.d.ts.map +1 -1
  53. package/cdn/elements/divider/index.js +1 -1
  54. package/cdn/elements/divider/index.js.map +1 -1
  55. package/cdn/elements/drawer/drawer.d.ts +2 -2
  56. package/cdn/elements/drawer/drawer.d.ts.map +1 -1
  57. package/cdn/elements/drawer/drawer.js +1 -1
  58. package/cdn/elements/drawer/drawer.js.map +1 -1
  59. package/cdn/elements/drawer/index.d.ts +2 -2
  60. package/cdn/elements/drawer/index.d.ts.map +1 -1
  61. package/cdn/elements/drawer/index.js +1 -1
  62. package/cdn/elements/drawer/index.js.map +1 -1
  63. package/cdn/elements/dropdown/dropdown.d.ts +7 -4
  64. package/cdn/elements/dropdown/dropdown.d.ts.map +1 -1
  65. package/cdn/elements/dropdown/dropdown.js +7 -4
  66. package/cdn/elements/dropdown/dropdown.js.map +1 -1
  67. package/cdn/elements/dropdown/index.d.ts +2 -2
  68. package/cdn/elements/dropdown/index.d.ts.map +1 -1
  69. package/cdn/elements/dropdown/index.js +1 -1
  70. package/cdn/elements/dropdown/index.js.map +1 -1
  71. package/cdn/elements/dropdown-item/dropdown-item.d.ts +1 -1
  72. package/cdn/elements/dropdown-item/dropdown-item.d.ts.map +1 -1
  73. package/cdn/elements/dropdown-item/dropdown-item.js +2 -2
  74. package/cdn/elements/dropdown-item/dropdown-item.js.map +1 -1
  75. package/cdn/elements/dropdown-item/index.d.ts +2 -2
  76. package/cdn/elements/dropdown-item/index.d.ts.map +1 -1
  77. package/cdn/elements/dropdown-item/index.js +1 -1
  78. package/cdn/elements/dropdown-item/index.js.map +1 -1
  79. package/cdn/elements/icon/icon.d.ts +1 -1
  80. package/cdn/elements/icon/icon.d.ts.map +1 -1
  81. package/cdn/elements/icon/icon.js +2 -2
  82. package/cdn/elements/icon/icon.js.map +1 -1
  83. package/cdn/elements/icon/index.d.ts +2 -2
  84. package/cdn/elements/icon/index.d.ts.map +1 -1
  85. package/cdn/elements/icon/index.js +1 -1
  86. package/cdn/elements/icon/index.js.map +1 -1
  87. package/cdn/elements/input-otp/index.d.ts +2 -2
  88. package/cdn/elements/input-otp/index.d.ts.map +1 -1
  89. package/cdn/elements/input-otp/index.js +1 -1
  90. package/cdn/elements/input-otp/index.js.map +1 -1
  91. package/cdn/elements/input-otp/input-otp.d.ts +1 -1
  92. package/cdn/elements/input-otp/input-otp.d.ts.map +1 -1
  93. package/cdn/elements/input-otp/input-otp.js +1 -1
  94. package/cdn/elements/input-otp/input-otp.js.map +1 -1
  95. package/cdn/elements/input-stepper/index.d.ts +2 -2
  96. package/cdn/elements/input-stepper/index.d.ts.map +1 -1
  97. package/cdn/elements/input-stepper/index.js +1 -1
  98. package/cdn/elements/input-stepper/index.js.map +1 -1
  99. package/cdn/elements/input-stepper/input-stepper.d.ts +1 -1
  100. package/cdn/elements/input-stepper/input-stepper.d.ts.map +1 -1
  101. package/cdn/elements/input-stepper/input-stepper.js +1 -1
  102. package/cdn/elements/input-stepper/input-stepper.js.map +1 -1
  103. package/cdn/elements/popover/index.d.ts +2 -2
  104. package/cdn/elements/popover/index.d.ts.map +1 -1
  105. package/cdn/elements/popover/index.js +1 -1
  106. package/cdn/elements/popover/index.js.map +1 -1
  107. package/cdn/elements/popover/popover.d.ts +1 -1
  108. package/cdn/elements/popover/popover.d.ts.map +1 -1
  109. package/cdn/elements/popover/popover.js +2 -2
  110. package/cdn/elements/popover/popover.js.map +1 -1
  111. package/cdn/elements/rating/index.d.ts +2 -2
  112. package/cdn/elements/rating/index.d.ts.map +1 -1
  113. package/cdn/elements/rating/index.js +1 -1
  114. package/cdn/elements/rating/index.js.map +1 -1
  115. package/cdn/elements/rating/rating.d.ts +1 -1
  116. package/cdn/elements/rating/rating.d.ts.map +1 -1
  117. package/cdn/elements/rating/rating.js +2 -2
  118. package/cdn/elements/rating/rating.js.map +1 -1
  119. package/cdn/elements/skeleton/index.d.ts +2 -2
  120. package/cdn/elements/skeleton/index.d.ts.map +1 -1
  121. package/cdn/elements/skeleton/index.js +1 -1
  122. package/cdn/elements/skeleton/index.js.map +1 -1
  123. package/cdn/elements/skeleton/skeleton.d.ts +1 -1
  124. package/cdn/elements/skeleton/skeleton.d.ts.map +1 -1
  125. package/cdn/elements/skeleton/skeleton.js +1 -1
  126. package/cdn/elements/skeleton/skeleton.js.map +1 -1
  127. package/cdn/elements/spinner/index.d.ts +2 -2
  128. package/cdn/elements/spinner/index.d.ts.map +1 -1
  129. package/cdn/elements/spinner/index.js +1 -1
  130. package/cdn/elements/spinner/index.js.map +1 -1
  131. package/cdn/elements/spinner/spinner.d.ts +1 -1
  132. package/cdn/elements/spinner/spinner.d.ts.map +1 -1
  133. package/cdn/elements/spinner/spinner.js +1 -1
  134. package/cdn/elements/spinner/spinner.js.map +1 -1
  135. package/cdn/elements/sticky-bar/index.d.ts +8 -0
  136. package/cdn/elements/sticky-bar/index.d.ts.map +1 -0
  137. package/cdn/elements/sticky-bar/index.js +2 -0
  138. package/cdn/elements/sticky-bar/index.js.map +1 -0
  139. package/cdn/elements/sticky-bar/sticky-bar.d.ts +46 -0
  140. package/cdn/elements/sticky-bar/sticky-bar.d.ts.map +1 -0
  141. package/cdn/elements/sticky-bar/sticky-bar.js +2 -0
  142. package/cdn/elements/sticky-bar/sticky-bar.js.map +1 -0
  143. package/cdn/elements/stories/index.d.ts +8 -0
  144. package/cdn/elements/stories/index.d.ts.map +1 -0
  145. package/cdn/elements/stories/index.js +2 -0
  146. package/cdn/elements/stories/index.js.map +1 -0
  147. package/cdn/elements/stories/stories.d.ts +50 -0
  148. package/cdn/elements/stories/stories.d.ts.map +1 -0
  149. package/cdn/elements/stories/stories.js +2 -0
  150. package/cdn/elements/stories/stories.js.map +1 -0
  151. package/cdn/elements/stories-viewer/index.d.ts +8 -0
  152. package/cdn/elements/stories-viewer/index.d.ts.map +1 -0
  153. package/cdn/elements/stories-viewer/index.js +2 -0
  154. package/cdn/elements/stories-viewer/index.js.map +1 -0
  155. package/cdn/elements/stories-viewer/stories-viewer.d.ts +136 -0
  156. package/cdn/elements/stories-viewer/stories-viewer.d.ts.map +1 -0
  157. package/cdn/elements/stories-viewer/stories-viewer.js +160 -0
  158. package/cdn/elements/stories-viewer/stories-viewer.js.map +1 -0
  159. package/cdn/elements/story/index.d.ts +8 -0
  160. package/cdn/elements/story/index.d.ts.map +1 -0
  161. package/cdn/elements/story/index.js +2 -0
  162. package/cdn/elements/story/index.js.map +1 -0
  163. package/cdn/elements/story/story.d.ts +48 -0
  164. package/cdn/elements/story/story.d.ts.map +1 -0
  165. package/cdn/elements/story/story.js +35 -0
  166. package/cdn/elements/story/story.js.map +1 -0
  167. package/cdn/elements/tabs/index.d.ts +2 -2
  168. package/cdn/elements/tabs/index.d.ts.map +1 -1
  169. package/cdn/elements/tabs/index.js +1 -1
  170. package/cdn/elements/tabs/index.js.map +1 -1
  171. package/cdn/elements/tabs/tabs.d.ts +1 -1
  172. package/cdn/elements/tabs/tabs.d.ts.map +1 -1
  173. package/cdn/elements/tabs/tabs.js +1 -1
  174. package/cdn/elements/tabs/tabs.js.map +1 -1
  175. package/cdn/elements/toast/index.d.ts +3 -3
  176. package/cdn/elements/toast/index.d.ts.map +1 -1
  177. package/cdn/elements/toast/index.js +1 -1
  178. package/cdn/elements/toast/index.js.map +1 -1
  179. package/cdn/elements/toast/toast.d.ts +2 -2
  180. package/cdn/elements/toast/toast.d.ts.map +1 -1
  181. package/cdn/elements/toast/toast.js +1 -1
  182. package/cdn/elements/toast/toast.js.map +1 -1
  183. package/cdn/elements/tooltip/index.d.ts +2 -2
  184. package/cdn/elements/tooltip/index.d.ts.map +1 -1
  185. package/cdn/elements/tooltip/index.js +1 -1
  186. package/cdn/elements/tooltip/index.js.map +1 -1
  187. package/cdn/elements/tooltip/tooltip.d.ts +4 -4
  188. package/cdn/elements/tooltip/tooltip.d.ts.map +1 -1
  189. package/cdn/elements/tooltip/tooltip.js +2 -2
  190. package/cdn/elements/tooltip/tooltip.js.map +1 -1
  191. package/cdn/elements/tree/index.d.ts +2 -2
  192. package/cdn/elements/tree/index.d.ts.map +1 -1
  193. package/cdn/elements/tree/index.js +1 -1
  194. package/cdn/elements/tree/index.js.map +1 -1
  195. package/cdn/elements/tree/tree.d.ts +5 -5
  196. package/cdn/elements/tree/tree.d.ts.map +1 -1
  197. package/cdn/elements/tree/tree.js +2 -2
  198. package/cdn/elements/tree/tree.js.map +1 -1
  199. package/cdn/elements/tree-item/index.d.ts +2 -2
  200. package/cdn/elements/tree-item/index.d.ts.map +1 -1
  201. package/cdn/elements/tree-item/index.js +1 -1
  202. package/cdn/elements/tree-item/index.js.map +1 -1
  203. package/cdn/elements/tree-item/tree-item.d.ts +2 -2
  204. package/cdn/elements/tree-item/tree-item.d.ts.map +1 -1
  205. package/cdn/elements/tree-item/tree-item.js +2 -2
  206. package/cdn/elements/tree-item/tree-item.js.map +1 -1
  207. package/cdn/registry.d.ts +1 -1
  208. package/cdn/registry.d.ts.map +1 -1
  209. package/cdn/registry.js.map +1 -1
  210. package/cdn/shared/controllers/popover.js.map +1 -1
  211. package/cdn/shared/luxen-form-associated-element.js +1 -1
  212. package/cdn/shared/styles/host.styles.js.map +1 -1
  213. package/cdn/styles/elements/divider.css +7 -0
  214. package/cdn/styles/elements/select.css +3 -3
  215. package/cdn/styles/elements/stories.css +63 -0
  216. package/cdn/styles/elements/story.css +192 -0
  217. package/cdn/styles/index.css +3 -0
  218. package/dist/css/elements/divider.css +7 -0
  219. package/dist/css/elements/select.css +3 -3
  220. package/dist/css/elements/stories.css +63 -0
  221. package/dist/css/elements/story.css +192 -0
  222. package/dist/css/index.css +3 -0
  223. package/dist/custom-elements.json +6707 -4242
  224. package/dist/elements/avatar/avatar.css +13 -7
  225. package/dist/elements/avatar/avatar.d.ts +1 -1
  226. package/dist/elements/avatar/avatar.d.ts.map +1 -1
  227. package/dist/elements/avatar/avatar.js +11 -11
  228. package/dist/elements/avatar/index.d.ts +2 -2
  229. package/dist/elements/avatar/index.d.ts.map +1 -1
  230. package/dist/elements/avatar/index.js +2 -2
  231. package/dist/elements/badge/badge.d.ts +1 -1
  232. package/dist/elements/badge/badge.d.ts.map +1 -1
  233. package/dist/elements/badge/badge.js +5 -5
  234. package/dist/elements/badge/index.d.ts +2 -2
  235. package/dist/elements/badge/index.d.ts.map +1 -1
  236. package/dist/elements/badge/index.js +2 -2
  237. package/dist/elements/carousel/carousel.css +7 -0
  238. package/dist/elements/carousel/carousel.d.ts +18 -11
  239. package/dist/elements/carousel/carousel.d.ts.map +1 -1
  240. package/dist/elements/carousel/carousel.js +193 -167
  241. package/dist/elements/carousel/index.d.ts +2 -2
  242. package/dist/elements/carousel/index.d.ts.map +1 -1
  243. package/dist/elements/carousel/index.js +2 -2
  244. package/dist/elements/carousel-item/carousel-item.d.ts +1 -1
  245. package/dist/elements/carousel-item/carousel-item.d.ts.map +1 -1
  246. package/dist/elements/carousel-item/carousel-item.js +2 -2
  247. package/dist/elements/carousel-item/index.d.ts +2 -2
  248. package/dist/elements/carousel-item/index.d.ts.map +1 -1
  249. package/dist/elements/carousel-item/index.js +2 -2
  250. package/dist/elements/dialog/dialog.d.ts +1 -1
  251. package/dist/elements/dialog/dialog.d.ts.map +1 -1
  252. package/dist/elements/dialog/dialog.js +9 -9
  253. package/dist/elements/dialog/index.d.ts +2 -2
  254. package/dist/elements/dialog/index.d.ts.map +1 -1
  255. package/dist/elements/dialog/index.js +2 -2
  256. package/dist/elements/divider/divider.d.ts +1 -1
  257. package/dist/elements/divider/divider.d.ts.map +1 -1
  258. package/dist/elements/divider/divider.js +3 -3
  259. package/dist/elements/divider/index.d.ts +2 -2
  260. package/dist/elements/divider/index.d.ts.map +1 -1
  261. package/dist/elements/divider/index.js +2 -2
  262. package/dist/elements/drawer/drawer.d.ts +2 -2
  263. package/dist/elements/drawer/drawer.d.ts.map +1 -1
  264. package/dist/elements/drawer/drawer.js +4 -4
  265. package/dist/elements/drawer/index.d.ts +2 -2
  266. package/dist/elements/drawer/index.d.ts.map +1 -1
  267. package/dist/elements/drawer/index.js +2 -2
  268. package/dist/elements/dropdown/dropdown.css +14 -3
  269. package/dist/elements/dropdown/dropdown.d.ts +7 -4
  270. package/dist/elements/dropdown/dropdown.d.ts.map +1 -1
  271. package/dist/elements/dropdown/dropdown.js +41 -29
  272. package/dist/elements/dropdown/index.d.ts +2 -2
  273. package/dist/elements/dropdown/index.d.ts.map +1 -1
  274. package/dist/elements/dropdown/index.js +2 -2
  275. package/dist/elements/dropdown-item/dropdown-item.d.ts +1 -1
  276. package/dist/elements/dropdown-item/dropdown-item.d.ts.map +1 -1
  277. package/dist/elements/dropdown-item/dropdown-item.js +20 -20
  278. package/dist/elements/dropdown-item/index.d.ts +2 -2
  279. package/dist/elements/dropdown-item/index.d.ts.map +1 -1
  280. package/dist/elements/dropdown-item/index.js +2 -2
  281. package/dist/elements/icon/icon.d.ts +1 -1
  282. package/dist/elements/icon/icon.d.ts.map +1 -1
  283. package/dist/elements/icon/icon.js +4 -4
  284. package/dist/elements/icon/index.d.ts +2 -2
  285. package/dist/elements/icon/index.d.ts.map +1 -1
  286. package/dist/elements/icon/index.js +2 -2
  287. package/dist/elements/input-otp/index.d.ts +2 -2
  288. package/dist/elements/input-otp/index.d.ts.map +1 -1
  289. package/dist/elements/input-otp/index.js +2 -2
  290. package/dist/elements/input-otp/input-otp.d.ts +1 -1
  291. package/dist/elements/input-otp/input-otp.d.ts.map +1 -1
  292. package/dist/elements/input-otp/input-otp.js +2 -2
  293. package/dist/elements/input-stepper/index.d.ts +2 -2
  294. package/dist/elements/input-stepper/index.d.ts.map +1 -1
  295. package/dist/elements/input-stepper/index.js +2 -2
  296. package/dist/elements/input-stepper/input-stepper.d.ts +1 -1
  297. package/dist/elements/input-stepper/input-stepper.d.ts.map +1 -1
  298. package/dist/elements/input-stepper/input-stepper.js +8 -8
  299. package/dist/elements/popover/index.d.ts +2 -2
  300. package/dist/elements/popover/index.d.ts.map +1 -1
  301. package/dist/elements/popover/index.js +2 -2
  302. package/dist/elements/popover/popover.d.ts +1 -1
  303. package/dist/elements/popover/popover.d.ts.map +1 -1
  304. package/dist/elements/popover/popover.js +33 -33
  305. package/dist/elements/rating/index.d.ts +2 -2
  306. package/dist/elements/rating/index.d.ts.map +1 -1
  307. package/dist/elements/rating/index.js +2 -2
  308. package/dist/elements/rating/rating.d.ts +1 -1
  309. package/dist/elements/rating/rating.d.ts.map +1 -1
  310. package/dist/elements/rating/rating.js +48 -48
  311. package/dist/elements/skeleton/index.d.ts +2 -2
  312. package/dist/elements/skeleton/index.d.ts.map +1 -1
  313. package/dist/elements/skeleton/index.js +2 -2
  314. package/dist/elements/skeleton/skeleton.d.ts +1 -1
  315. package/dist/elements/skeleton/skeleton.d.ts.map +1 -1
  316. package/dist/elements/skeleton/skeleton.js +1 -1
  317. package/dist/elements/spinner/index.d.ts +2 -2
  318. package/dist/elements/spinner/index.d.ts.map +1 -1
  319. package/dist/elements/spinner/index.js +2 -2
  320. package/dist/elements/spinner/spinner.d.ts +1 -1
  321. package/dist/elements/spinner/spinner.d.ts.map +1 -1
  322. package/dist/elements/spinner/spinner.js +2 -2
  323. package/dist/elements/sticky-bar/index.d.ts +8 -0
  324. package/dist/elements/sticky-bar/index.d.ts.map +1 -0
  325. package/dist/elements/sticky-bar/index.js +4 -0
  326. package/dist/elements/sticky-bar/sticky-bar.css +56 -0
  327. package/dist/elements/sticky-bar/sticky-bar.d.ts +46 -0
  328. package/dist/elements/sticky-bar/sticky-bar.d.ts.map +1 -0
  329. package/dist/elements/sticky-bar/sticky-bar.js +146 -0
  330. package/dist/elements/stories/index.d.ts +8 -0
  331. package/dist/elements/stories/index.d.ts.map +1 -0
  332. package/dist/elements/stories/index.js +4 -0
  333. package/dist/elements/stories/stories.d.ts +50 -0
  334. package/dist/elements/stories/stories.d.ts.map +1 -0
  335. package/dist/elements/stories/stories.js +113 -0
  336. package/dist/elements/stories-viewer/index.d.ts +8 -0
  337. package/dist/elements/stories-viewer/index.d.ts.map +1 -0
  338. package/dist/elements/stories-viewer/index.js +4 -0
  339. package/dist/elements/stories-viewer/stories-viewer.css +337 -0
  340. package/dist/elements/stories-viewer/stories-viewer.d.ts +136 -0
  341. package/dist/elements/stories-viewer/stories-viewer.d.ts.map +1 -0
  342. package/dist/elements/stories-viewer/stories-viewer.js +719 -0
  343. package/dist/elements/story/index.d.ts +8 -0
  344. package/dist/elements/story/index.d.ts.map +1 -0
  345. package/dist/elements/story/index.js +4 -0
  346. package/dist/elements/story/story.d.ts +48 -0
  347. package/dist/elements/story/story.d.ts.map +1 -0
  348. package/dist/elements/story/story.js +161 -0
  349. package/dist/elements/tabs/index.d.ts +2 -2
  350. package/dist/elements/tabs/index.d.ts.map +1 -1
  351. package/dist/elements/tabs/index.js +2 -2
  352. package/dist/elements/tabs/tabs.d.ts +1 -1
  353. package/dist/elements/tabs/tabs.d.ts.map +1 -1
  354. package/dist/elements/tabs/tabs.js +5 -5
  355. package/dist/elements/toast/index.d.ts +3 -3
  356. package/dist/elements/toast/index.d.ts.map +1 -1
  357. package/dist/elements/toast/index.js +3 -3
  358. package/dist/elements/toast/toast.d.ts +2 -2
  359. package/dist/elements/toast/toast.d.ts.map +1 -1
  360. package/dist/elements/toast/toast.js +5 -5
  361. package/dist/elements/tooltip/index.d.ts +2 -2
  362. package/dist/elements/tooltip/index.d.ts.map +1 -1
  363. package/dist/elements/tooltip/index.js +2 -2
  364. package/dist/elements/tooltip/tooltip.css +15 -7
  365. package/dist/elements/tooltip/tooltip.d.ts +4 -4
  366. package/dist/elements/tooltip/tooltip.d.ts.map +1 -1
  367. package/dist/elements/tooltip/tooltip.js +32 -32
  368. package/dist/elements/tree/index.d.ts +2 -2
  369. package/dist/elements/tree/index.d.ts.map +1 -1
  370. package/dist/elements/tree/index.js +2 -2
  371. package/dist/elements/tree/tree.d.ts +5 -5
  372. package/dist/elements/tree/tree.d.ts.map +1 -1
  373. package/dist/elements/tree/tree.js +14 -16
  374. package/dist/elements/tree-item/index.d.ts +2 -2
  375. package/dist/elements/tree-item/index.d.ts.map +1 -1
  376. package/dist/elements/tree-item/index.js +2 -2
  377. package/dist/elements/tree-item/tree-item.d.ts +2 -2
  378. package/dist/elements/tree-item/tree-item.d.ts.map +1 -1
  379. package/dist/elements/tree-item/tree-item.js +28 -28
  380. package/dist/registry.d.ts +1 -1
  381. package/dist/registry.d.ts.map +1 -1
  382. package/dist/skills/luxen-ui/SKILL.md +1 -0
  383. package/dist/skills/luxen-ui/references/select.md +1 -1
  384. package/dist/skills/luxen-ui/references/sticky-bar.md +148 -0
  385. package/package.json +4 -4
@@ -0,0 +1,719 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { html, nothing, unsafeCSS } from 'lit';
8
+ import { property, query, state } from 'lit/decorators.js';
9
+ import { map } from 'lit/directives/map.js';
10
+ import { LuxenElement } from '../../shared/luxen-element';
11
+ import hostStyles from '../../shared/styles/host.styles';
12
+ import rawStyles from './stories-viewer.css?inline';
13
+ const styles = unsafeCSS(rawStyles);
14
+ const SCROLL_LOCK_SHEET = Symbol.for('luxen-stories-viewer-scroll-lock');
15
+ if (typeof document !== 'undefined' && !(SCROLL_LOCK_SHEET in document)) {
16
+ const sheet = new CSSStyleSheet();
17
+ sheet.replaceSync(`html:has(l-stories-viewer[data-modal]) { overflow: hidden; scrollbar-gutter: stable; }`);
18
+ document.adoptedStyleSheets.push(sheet);
19
+ Object.defineProperty(document, SCROLL_LOCK_SHEET, { value: sheet });
20
+ }
21
+ /**
22
+ * @summary Fullscreen modal that plays a sequence of `<l-story>` videos with an
23
+ * Instagram-style segmented progress bar, previous/next navigation, mute toggle,
24
+ * and auto-advance.
25
+ *
26
+ * Linked to one or more `<l-stories>` rows via matching `id` ↔ `for`. Open
27
+ * programmatically via `open()` or by clicking a thumbnail in a linked row.
28
+ *
29
+ * @slot cta - Default CTA overlay (e.g. shoppable card). Per-story `slot="cta"` inside `<l-story>` overrides this when that story is active.
30
+ * @slot header - Default header overlay (e.g. avatar + author). Per-story override available the same way.
31
+ * @slot close - Override the default close button.
32
+ *
33
+ * @csspart dialog - The native `<dialog>` element.
34
+ * @csspart frame - The aspect-ratio video frame.
35
+ * @csspart progress - The progress bar wrapper.
36
+ * @csspart progress-segment - A single progress segment.
37
+ * @csspart progress-fill - The fill element inside an active segment.
38
+ * @csspart video - The `<video>` element.
39
+ * @csspart overlay - The overlay wrapper that hosts CTA/header slots.
40
+ * @csspart header - The top-left header area (story thumbnail + label fallback, or consumer-supplied content via the `header` slot).
41
+ * @csspart header-label - The default story label inside the header.
42
+ * @csspart actions - The top-right vertical button stack (close, play/pause, mute).
43
+ * @csspart button-close - The close button.
44
+ * @csspart button-pause - The play/pause toggle.
45
+ * @csspart button-mute - The mute toggle.
46
+ * @csspart button-previous - The previous story button.
47
+ * @csspart button-next - The next story button.
48
+ * @csspart spinner - The loading spinner shown while the current video is buffering.
49
+ *
50
+ * @cssproperty --width - Frame width. Default `min(420px, 100vw)`.
51
+ * @cssproperty --progress-color - Active progress fill color. Default `white`.
52
+ * @cssproperty --progress-bg - Inactive progress segment background. Default `rgb(255 255 255 / 35%)`.
53
+ * @cssproperty --progress-gap - Gap between segments. Default `4px`.
54
+ * @cssproperty --show-duration - Open transition duration. Default `200ms`.
55
+ * @cssproperty --hide-duration - Close transition duration. Default `200ms`.
56
+ * @cssproperty --backdrop - Backdrop color. Default `var(--l-backdrop-strong)` — darker than `--l-backdrop` to focus attention on the immersive frame, but still translucent so the page stays perceptible.
57
+ *
58
+ * @event show - Fired when the viewer opens.
59
+ * @event after-show - Fired after the open transition completes.
60
+ * @event hide - Fired when the viewer is about to close. Cancelable.
61
+ * @event after-hide - Fired after the close transition completes.
62
+ * @event story-change - Fired when the active story changes. Detail: `{ index: number, story: LuxenStory }`.
63
+ * @event story-end - Fired when the active story finishes playback. Detail: `{ index: number }`.
64
+ * @event chapter-change - Fired when the active chapter (within a story) changes. Detail: `{ chapter: number, story: LuxenStory }`.
65
+ * @event mute-change - Fired when the mute state changes. Detail: `{ muted: boolean }`.
66
+ *
67
+ * @customElement l-stories-viewer
68
+ */
69
+ export class LuxenStoriesViewer extends LuxenElement {
70
+ constructor() {
71
+ super(...arguments);
72
+ /** Whether the viewer is open. */
73
+ this.open = false;
74
+ /** Active story index (0-based). */
75
+ this.index = 0;
76
+ /** Whether playback is muted. Defaults to `true` so autoplay always succeeds across browsers. The user can unmute via the dedicated button or the `m` keyboard shortcut. */
77
+ this.muted = true;
78
+ /** Loop the active story instead of advancing. */
79
+ this.loop = false;
80
+ /** Move to the next story when the current one ends; close after the last story. */
81
+ this.autoAdvance = true;
82
+ /** Close when the backdrop is clicked. */
83
+ this.lightDismiss = true;
84
+ /** Active chapter index within the current story. Reflected. */
85
+ this.chapter = 0;
86
+ /** Internal: the playlist set by the source `<l-stories>`. */
87
+ this.stories = [];
88
+ /** Internal: the source `<l-stories>` element that opened the viewer. */
89
+ this.source = null;
90
+ /** Tracks the underlying `<video>` paused state so the play/pause button stays in sync. */
91
+ this._paused = false;
92
+ /** True while the video is buffering / waiting for data. Drives the loading spinner. */
93
+ this._loading = false;
94
+ this._raf = 0;
95
+ this._holdTimer = 0;
96
+ this._pointerStart = null;
97
+ this._segments = [];
98
+ this._chapterStarts = [0];
99
+ /** Tracks the URL we've already injected a prefetch hint for so we don't duplicate. */
100
+ this._prefetchedSrc = null;
101
+ // --- Keyboard ---
102
+ this._onKeyDown = (e) => {
103
+ if (!this.open)
104
+ return;
105
+ switch (e.key) {
106
+ case 'ArrowLeft':
107
+ e.preventDefault();
108
+ this.previous();
109
+ break;
110
+ case 'ArrowRight':
111
+ e.preventDefault();
112
+ this.next();
113
+ break;
114
+ case ' ':
115
+ e.preventDefault();
116
+ if (this._video.paused)
117
+ this.play();
118
+ else
119
+ this.pause();
120
+ break;
121
+ case 'm':
122
+ case 'M':
123
+ e.preventDefault();
124
+ this.muted = !this.muted;
125
+ this.emit('mute-change', { detail: { muted: this.muted } });
126
+ break;
127
+ }
128
+ };
129
+ // --- Pointer / touch (long-press to pause, tap-to-advance, swipe to close) ---
130
+ this._onFramePointerDown = (e) => {
131
+ // Skip buttons, links, and explicitly-marked no-gesture areas.
132
+ if (e.target.closest('button, a, [data-no-gesture]'))
133
+ return;
134
+ this._pointerStart = { x: e.clientX, y: e.clientY, t: performance.now() };
135
+ this._holdTimer = window.setTimeout(() => this.pause(), 200);
136
+ };
137
+ this._onFramePointerUp = (e) => {
138
+ clearTimeout(this._holdTimer);
139
+ const start = this._pointerStart;
140
+ this._pointerStart = null;
141
+ if (!start)
142
+ return;
143
+ const dx = e.clientX - start.x;
144
+ const dy = e.clientY - start.y;
145
+ const elapsed = performance.now() - start.t;
146
+ const isTap = elapsed < 200 && Math.abs(dx) < 10 && Math.abs(dy) < 10;
147
+ const wasLongPress = elapsed >= 200 && Math.abs(dx) < 10 && Math.abs(dy) < 10;
148
+ const SWIPE = 50;
149
+ if (wasLongPress) {
150
+ if (this._video.paused)
151
+ this.play();
152
+ return;
153
+ }
154
+ if (isTap) {
155
+ // Tap zones: chapter-aware nav. Left ~30% = previous chapter (or previous
156
+ // story at the chapter boundary), anywhere else = next chapter (or next
157
+ // story at the last chapter). Chevron buttons remain story-to-story.
158
+ const tap = e.target.closest('[data-tap]');
159
+ if (tap?.dataset.tap === 'previous')
160
+ this.previous();
161
+ else
162
+ this.next();
163
+ return;
164
+ }
165
+ if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > SWIPE) {
166
+ if (dx < 0)
167
+ this.nextStory();
168
+ else
169
+ this.previousStory();
170
+ }
171
+ else if (dy > SWIPE) {
172
+ this.close();
173
+ }
174
+ };
175
+ this._tick = () => {
176
+ if (!this.open)
177
+ return;
178
+ const v = this._video;
179
+ const seg = this._segments[this.chapter];
180
+ if (v && seg) {
181
+ const start = this._chapterStarts[this.chapter] ?? 0;
182
+ const end = this._chapterStarts[this.chapter + 1] ?? v.duration;
183
+ const span = Math.max(0, end - start);
184
+ const p = span ? Math.max(0, Math.min((v.currentTime - start) / span, 1)) : 0;
185
+ seg.style.setProperty('--p', String(p));
186
+ // Auto-advance chapter when its segment is full and there's a next chapter in this story.
187
+ // (The video element's `ended` event handles the last chapter via `_onEnded`.)
188
+ if (p >= 1 && this.chapter < this._lastChapter) {
189
+ this._advance(1);
190
+ }
191
+ }
192
+ this._raf = requestAnimationFrame(this._tick);
193
+ };
194
+ }
195
+ // --- Lifecycle ---
196
+ connectedCallback() {
197
+ super.connectedCallback();
198
+ this.addEventListener('keydown', this._onKeyDown);
199
+ }
200
+ disconnectedCallback() {
201
+ super.disconnectedCallback();
202
+ this.removeEventListener('keydown', this._onKeyDown);
203
+ cancelAnimationFrame(this._raf);
204
+ clearTimeout(this._holdTimer);
205
+ this._clearPrefetchHints();
206
+ }
207
+ firstUpdated() {
208
+ this._dialog.addEventListener('cancel', (e) => this._onCancel(e));
209
+ this._dialog.addEventListener('close', () => this._onNativeClose());
210
+ this._dialog.addEventListener('click', (e) => this._onDialogClick(e));
211
+ this._video.addEventListener('ended', () => this._onEnded());
212
+ this._video.addEventListener('loadedmetadata', () => this._tick());
213
+ this._video.addEventListener('play', () => (this._paused = false));
214
+ this._video.addEventListener('pause', () => (this._paused = true));
215
+ // Loading spinner state — shown during initial buffer and any subsequent stalls,
216
+ // hidden as soon as the video is actually painting frames.
217
+ this._video.addEventListener('loadstart', () => (this._loading = true));
218
+ this._video.addEventListener('waiting', () => (this._loading = true));
219
+ this._video.addEventListener('playing', () => (this._loading = false));
220
+ this._video.addEventListener('canplay', () => (this._loading = false));
221
+ this._video.addEventListener('error', () => (this._loading = false));
222
+ // Prefetch the next story's video once the current one is past 50% so the
223
+ // transition feels instantaneous. Idempotent via `_prefetchedSrc`.
224
+ this._video.addEventListener('timeupdate', () => this._maybePrefetchNext());
225
+ }
226
+ updated(changed) {
227
+ if (changed.has('open')) {
228
+ if (this.open && !this._dialog.open) {
229
+ this.emit('show');
230
+ this.toggleAttribute('data-modal', true);
231
+ this._dialog.showModal();
232
+ this._loadCurrent();
233
+ void this._emitAfter('after-show');
234
+ }
235
+ else if (!this.open && this._dialog.open) {
236
+ if (!this.emit('hide', { cancelable: true })) {
237
+ this.open = true;
238
+ return;
239
+ }
240
+ this._dialog.close();
241
+ }
242
+ }
243
+ // Story change → reload current story (refreshes chapters, segments, slots, video).
244
+ if (changed.has('index') && this.open) {
245
+ this._loadCurrent();
246
+ const story = this.stories[this.index];
247
+ if (story)
248
+ this.emit('story-change', { detail: { index: this.index, story } });
249
+ }
250
+ // Chapter change within the current story → seek + refresh segment fills.
251
+ if (changed.has('chapter') && this.open && !changed.has('index')) {
252
+ this._applyChapterSeek();
253
+ }
254
+ if (changed.has('muted') && this._video) {
255
+ this._video.muted = this.muted;
256
+ }
257
+ }
258
+ // --- Dialog event handlers ---
259
+ _onCancel(e) {
260
+ if (!this.emit('hide', { cancelable: true })) {
261
+ e.preventDefault();
262
+ }
263
+ }
264
+ _onNativeClose() {
265
+ cancelAnimationFrame(this._raf);
266
+ this._video.pause();
267
+ this._video.removeAttribute('src');
268
+ this._video.load();
269
+ this._clearPrefetchHints();
270
+ // Mark all stories up to and including this.index as seen.
271
+ for (let i = 0; i <= this.index && i < this.stories.length; i++) {
272
+ this.stories[i].seen = true;
273
+ }
274
+ this._restoreFocus();
275
+ this.open = false;
276
+ this.removeAttribute('data-modal');
277
+ void this._emitAfter('after-hide');
278
+ }
279
+ _onDialogClick(e) {
280
+ if (!this.lightDismiss)
281
+ return;
282
+ // Backdrop click: target is the <dialog>, not a child.
283
+ if (e.target === this._dialog) {
284
+ this.open = false;
285
+ }
286
+ }
287
+ // --- Segments / progress (chapter-based) ---
288
+ _refreshSegmentRefs() {
289
+ this._segments = Array.from(this.shadowRoot.querySelectorAll('[part~="progress-fill"]'));
290
+ }
291
+ _resetSegmentFills() {
292
+ this._refreshSegmentRefs();
293
+ for (let i = 0; i < this._segments.length; i++) {
294
+ const p = i < this.chapter ? 1 : 0;
295
+ this._segments[i].style.setProperty('--p', String(p));
296
+ }
297
+ }
298
+ _loadCurrent() {
299
+ const story = this.stories[this.index];
300
+ if (!story)
301
+ return;
302
+ cancelAnimationFrame(this._raf);
303
+ // Reset the prefetch tracker when the active story changes — the next
304
+ // candidate has shifted and may need its own preload hint.
305
+ this._prefetchedSrc = null;
306
+ this._chapterStarts = story.getChapterStarts();
307
+ this.chapter = 0;
308
+ this._syncSlots(story);
309
+ this._video.muted = this.muted;
310
+ this._video.loop = this.loop;
311
+ if (this._video.src !== story.src) {
312
+ this._video.src = story.src;
313
+ }
314
+ else {
315
+ this._video.currentTime = 0;
316
+ }
317
+ // Wait one frame for the new segment DOM to render before resetting fills.
318
+ requestAnimationFrame(() => this._resetSegmentFills());
319
+ this._video.play().catch(() => {
320
+ // Autoplay-with-sound rejection: force muted, retry.
321
+ this.muted = true;
322
+ this._video.muted = true;
323
+ this._video.play().catch(() => { });
324
+ });
325
+ }
326
+ /**
327
+ * Inject a `<link rel="preload" as="video">` for the next story once the
328
+ * current video crosses 50% playback. Idempotent: tracked by `_prefetchedSrc`,
329
+ * cleaned up on viewer close.
330
+ */
331
+ _maybePrefetchNext() {
332
+ const v = this._video;
333
+ if (!v.duration || v.currentTime / v.duration < 0.5)
334
+ return;
335
+ const nextStory = this.stories[this.index + 1];
336
+ if (!nextStory?.src)
337
+ return;
338
+ if (this._prefetchedSrc === nextStory.src)
339
+ return;
340
+ this._prefetchedSrc = nextStory.src;
341
+ const link = document.createElement('link');
342
+ link.rel = 'preload';
343
+ link.as = 'video';
344
+ link.href = nextStory.src;
345
+ link.crossOrigin = 'anonymous';
346
+ link.dataset.luxenStoriesPrefetch = '';
347
+ document.head.appendChild(link);
348
+ }
349
+ /** Remove every prefetch hint we've injected. Called when the viewer closes. */
350
+ _clearPrefetchHints() {
351
+ const links = document.head.querySelectorAll('link[data-luxen-stories-prefetch]');
352
+ for (const link of links)
353
+ link.remove();
354
+ this._prefetchedSrc = null;
355
+ }
356
+ _applyChapterSeek() {
357
+ const target = this._chapterStarts[this.chapter] ?? 0;
358
+ this._video.currentTime = target;
359
+ this._resetSegmentFills();
360
+ const story = this.stories[this.index];
361
+ if (story)
362
+ this.emit('chapter-change', { detail: { chapter: this.chapter, story } });
363
+ }
364
+ get _lastChapter() {
365
+ return Math.max(0, this._chapterStarts.length - 1);
366
+ }
367
+ // Clone the active story's slot-marked children (cta, header) into the
368
+ // viewer's own light DOM so the shadow root's `<slot name="cta">` and
369
+ // `<slot name="header">` project them. Originals stay attached to the
370
+ // story (hidden via CSS) and are reused on every `index` change.
371
+ _syncSlots(story) {
372
+ for (const node of Array.from(this.children)) {
373
+ if (node.dataset.storySlot !== undefined)
374
+ node.remove();
375
+ }
376
+ for (const child of Array.from(story.children)) {
377
+ const slotName = child.getAttribute?.('slot');
378
+ if (!slotName)
379
+ continue;
380
+ const clone = child.cloneNode(true);
381
+ clone.dataset.storySlot = '';
382
+ this.appendChild(clone);
383
+ }
384
+ }
385
+ _onEnded() {
386
+ // Last chapter of the current story finished.
387
+ const story = this.stories[this.index];
388
+ if (story)
389
+ this.emit('story-end', { detail: { index: this.index } });
390
+ if (this.loop) {
391
+ this._video.currentTime = this._chapterStarts[0] ?? 0;
392
+ this.chapter = 0;
393
+ this._video.play().catch(() => { });
394
+ return;
395
+ }
396
+ if (!this.autoAdvance)
397
+ return;
398
+ if (this.index < this.stories.length - 1) {
399
+ this.index = this.index + 1;
400
+ }
401
+ else {
402
+ this.close();
403
+ }
404
+ }
405
+ /** chapter-then-story navigation. */
406
+ _advance(direction) {
407
+ if (direction === 1) {
408
+ if (this.chapter < this._lastChapter) {
409
+ this.chapter = this.chapter + 1;
410
+ }
411
+ else if (this.index < this.stories.length - 1) {
412
+ this.index = this.index + 1;
413
+ }
414
+ else {
415
+ this.close();
416
+ }
417
+ return;
418
+ }
419
+ // direction === -1: Instagram pattern — restart the current chapter if past 1s in.
420
+ const start = this._chapterStarts[this.chapter] ?? 0;
421
+ if (this._video.currentTime > start + 1) {
422
+ this._video.currentTime = start;
423
+ this._resetSegmentFills();
424
+ return;
425
+ }
426
+ if (this.chapter > 0) {
427
+ this.chapter = this.chapter - 1;
428
+ }
429
+ else if (this.index > 0) {
430
+ // Crossing into the previous story: load it, then jump to its last chapter.
431
+ const previousStory = this.stories[this.index - 1];
432
+ const previousLast = Math.max(0, previousStory.getChapterStarts().length - 1);
433
+ this.index = this.index - 1;
434
+ // After `index` updates, `_loadCurrent()` runs and resets `chapter` to 0.
435
+ // Set `chapter` to the previous story's last chapter on the next microtask.
436
+ queueMicrotask(() => {
437
+ this.chapter = previousLast;
438
+ });
439
+ }
440
+ }
441
+ // --- Public API ---
442
+ /** Open the viewer at the given index with an explicit playlist. */
443
+ openAt(stories, index = 0, source = null) {
444
+ this.stories = stories;
445
+ this.source = source;
446
+ this.index = Math.max(0, Math.min(index, stories.length - 1));
447
+ this.open = true;
448
+ }
449
+ close() {
450
+ this.open = false;
451
+ }
452
+ /** Advance one chapter, or to the next story at the chapter boundary. */
453
+ next() {
454
+ this._advance(1);
455
+ }
456
+ /** Retreat one chapter, restart the current chapter past 1s in, or cross into the previous story. */
457
+ previous() {
458
+ this._advance(-1);
459
+ }
460
+ /** Jump to the next story, skipping any remaining chapters in the current story. */
461
+ nextStory() {
462
+ if (this.index < this.stories.length - 1) {
463
+ this.index = this.index + 1;
464
+ }
465
+ else {
466
+ this.close();
467
+ }
468
+ }
469
+ /** Jump to the previous story regardless of current chapter. Lands on chapter 0 of the previous story. */
470
+ previousStory() {
471
+ if (this.index > 0) {
472
+ this.index = this.index - 1;
473
+ }
474
+ }
475
+ play() {
476
+ this._video?.play().catch(() => { });
477
+ this._raf = requestAnimationFrame(this._tick);
478
+ }
479
+ pause() {
480
+ this._video?.pause();
481
+ cancelAnimationFrame(this._raf);
482
+ }
483
+ // --- Helpers ---
484
+ async _emitAfter(name) {
485
+ await new Promise((r) => requestAnimationFrame(() => r(null)));
486
+ const anims = this._dialog.getAnimations({ subtree: false });
487
+ await Promise.all(anims.map((a) => a.finished.catch(() => { })));
488
+ if ((name === 'after-show') !== this.open)
489
+ return;
490
+ this.emit(name);
491
+ if (name === 'after-show') {
492
+ this._raf = requestAnimationFrame(this._tick);
493
+ }
494
+ }
495
+ _restoreFocus() {
496
+ const stories = this.source?.stories() ?? this.stories;
497
+ const story = stories[this.index];
498
+ const trigger = story?.querySelector('button[data-story-trigger]');
499
+ trigger?.focus({ preventScroll: false });
500
+ }
501
+ render() {
502
+ const total = this.stories.length;
503
+ const currentStory = this.stories[this.index];
504
+ // Chevrons navigate story-to-story, so visibility depends on `index` only (not chapter).
505
+ const isFirstStory = this.index === 0;
506
+ const isLastStory = this.index >= total - 1;
507
+ // Render one segment per chapter of the CURRENT story. Use `_chapterStarts` if present
508
+ // (set after `_loadCurrent`), or fall back to the current story's parsed chapters.
509
+ const chapterStarts = this._chapterStarts.length
510
+ ? this._chapterStarts
511
+ : (currentStory?.getChapterStarts() ?? [0]);
512
+ return html `
513
+ <dialog
514
+ part="dialog"
515
+ aria-label="Stories"
516
+ >
517
+ <div
518
+ part="frame"
519
+ class="frame"
520
+ @pointerdown=${this._onFramePointerDown}
521
+ @pointerup=${this._onFramePointerUp}
522
+ @pointercancel=${this._onFramePointerUp}
523
+ >
524
+ <div
525
+ part="progress"
526
+ class="progress"
527
+ role="progressbar"
528
+ aria-valuenow=${this.chapter + 1}
529
+ aria-valuemin="1"
530
+ aria-valuemax=${chapterStarts.length || 1}
531
+ >
532
+ ${map(chapterStarts, (_, i) => html `
533
+ <span
534
+ part="progress-segment"
535
+ class="progress-segment"
536
+ data-state=${i < this.chapter ? 'past' : i === this.chapter ? 'active' : 'future'}
537
+ >
538
+ <span
539
+ part="progress-fill"
540
+ class="progress-fill"
541
+ ></span>
542
+ </span>
543
+ `)}
544
+ </div>
545
+
546
+ <header
547
+ part="header"
548
+ class="header"
549
+ data-no-gesture
550
+ >
551
+ <slot name="header">
552
+ ${currentStory?.poster
553
+ ? html `<img
554
+ class="header-thumb"
555
+ src=${currentStory.poster}
556
+ alt=""
557
+ />`
558
+ : nothing}
559
+ ${currentStory?.label
560
+ ? html `<div class="header-text">
561
+ <div
562
+ part="header-label"
563
+ class="header-label"
564
+ >
565
+ ${currentStory.label}
566
+ </div>
567
+ </div>`
568
+ : nothing}
569
+ </slot>
570
+ </header>
571
+
572
+ <div
573
+ part="actions"
574
+ class="actions"
575
+ data-no-gesture
576
+ >
577
+ <slot name="close">
578
+ <button
579
+ type="button"
580
+ part="button-close"
581
+ class="btn btn-close"
582
+ aria-label="Close"
583
+ @click=${() => this.close()}
584
+ >
585
+ <l-icon name="mdi:close"></l-icon>
586
+ </button>
587
+ </slot>
588
+ <button
589
+ type="button"
590
+ part="button-pause"
591
+ class="btn btn-pause"
592
+ aria-label=${this._paused ? 'Play' : 'Pause'}
593
+ aria-pressed=${this._paused ? 'true' : 'false'}
594
+ @click=${() => (this._paused ? this.play() : this.pause())}
595
+ >
596
+ <l-icon name=${this._paused ? 'mdi:play' : 'mdi:pause'}></l-icon>
597
+ </button>
598
+ <button
599
+ type="button"
600
+ part="button-mute"
601
+ class="btn btn-mute"
602
+ aria-label=${this.muted ? 'Unmute' : 'Mute'}
603
+ aria-pressed=${this.muted ? 'false' : 'true'}
604
+ @click=${() => {
605
+ this.muted = !this.muted;
606
+ this.emit('mute-change', { detail: { muted: this.muted } });
607
+ }}
608
+ >
609
+ <l-icon name=${this.muted ? 'mdi:volume-off' : 'mdi:volume-high'}></l-icon>
610
+ </button>
611
+ </div>
612
+
613
+ <video
614
+ part="video"
615
+ class="video"
616
+ playsinline
617
+ preload="metadata"
618
+ ?muted=${this.muted}
619
+ ></video>
620
+
621
+ <l-spinner
622
+ part="spinner"
623
+ class="spinner"
624
+ aria-label="Loading"
625
+ data-no-gesture
626
+ data-state=${this._loading ? 'loading' : 'idle'}
627
+ ></l-spinner>
628
+
629
+ <!-- Tap zones: invisible overlays that translate clicks into previous/next.
630
+ Sit BELOW header / overlay / chevron buttons in z-order, above the video. -->
631
+ <div
632
+ class="tap-zone tap-previous"
633
+ data-tap="previous"
634
+ aria-hidden="true"
635
+ ></div>
636
+ <div
637
+ class="tap-zone tap-next"
638
+ data-tap="next"
639
+ aria-hidden="true"
640
+ ></div>
641
+
642
+ <div
643
+ part="overlay"
644
+ class="overlay"
645
+ data-no-gesture
646
+ >
647
+ <slot name="cta"></slot>
648
+ </div>
649
+
650
+ <div
651
+ class="sr-only"
652
+ aria-live="polite"
653
+ >
654
+ ${total
655
+ ? `Story ${this.index + 1} of ${total}${this.stories[this.index]?.label ? ` — ${this.stories[this.index].label}` : ''}${chapterStarts.length > 1 ? ` — chapter ${this.chapter + 1} of ${chapterStarts.length}` : ''}`
656
+ : ''}
657
+ </div>
658
+ </div>
659
+
660
+ ${isFirstStory
661
+ ? nothing
662
+ : html `<button
663
+ type="button"
664
+ part="button-previous"
665
+ class="btn btn-nav btn-previous"
666
+ aria-label="Previous story"
667
+ @click=${() => this.previousStory()}
668
+ >
669
+ <l-icon name="mdi:chevron-left"></l-icon>
670
+ </button>`}
671
+ ${isLastStory
672
+ ? nothing
673
+ : html `<button
674
+ type="button"
675
+ part="button-next"
676
+ class="btn btn-nav btn-next"
677
+ aria-label="Next story"
678
+ @click=${() => this.nextStory()}
679
+ >
680
+ <l-icon name="mdi:chevron-right"></l-icon>
681
+ </button>`}
682
+ </dialog>
683
+ `;
684
+ }
685
+ }
686
+ LuxenStoriesViewer.styles = [hostStyles, styles];
687
+ __decorate([
688
+ property({ type: Boolean, reflect: true })
689
+ ], LuxenStoriesViewer.prototype, "open", void 0);
690
+ __decorate([
691
+ property({ type: Number, reflect: true })
692
+ ], LuxenStoriesViewer.prototype, "index", void 0);
693
+ __decorate([
694
+ property({ type: Boolean, reflect: true })
695
+ ], LuxenStoriesViewer.prototype, "muted", void 0);
696
+ __decorate([
697
+ property({ type: Boolean, reflect: true })
698
+ ], LuxenStoriesViewer.prototype, "loop", void 0);
699
+ __decorate([
700
+ property({ type: Boolean, reflect: true, attribute: 'auto-advance' })
701
+ ], LuxenStoriesViewer.prototype, "autoAdvance", void 0);
702
+ __decorate([
703
+ property({ type: Boolean, reflect: true, attribute: 'light-dismiss' })
704
+ ], LuxenStoriesViewer.prototype, "lightDismiss", void 0);
705
+ __decorate([
706
+ property({ type: Number, reflect: true })
707
+ ], LuxenStoriesViewer.prototype, "chapter", void 0);
708
+ __decorate([
709
+ query('dialog')
710
+ ], LuxenStoriesViewer.prototype, "_dialog", void 0);
711
+ __decorate([
712
+ query('video')
713
+ ], LuxenStoriesViewer.prototype, "_video", void 0);
714
+ __decorate([
715
+ state()
716
+ ], LuxenStoriesViewer.prototype, "_paused", void 0);
717
+ __decorate([
718
+ state()
719
+ ], LuxenStoriesViewer.prototype, "_loading", void 0);