@0001-labs/design-system-1 0.3.0-alpha.13 → 0.3.0-alpha.15

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 (722) hide show
  1. package/DS1/0-face/calendar.ts +194 -0
  2. package/DS1/0-face/carousel.ts +623 -0
  3. package/DS1/0-face/component-visibility.ts +14 -0
  4. package/DS1/0-face/copy-text.ts +96 -0
  5. package/DS1/0-face/device.ts +8 -58
  6. package/DS1/0-face/dialog-swipe.ts +249 -0
  7. package/DS1/0-face/dialogs.ts +208 -0
  8. package/DS1/0-face/drawer.ts +258 -0
  9. package/DS1/0-face/feedback-words.ts +36 -0
  10. package/DS1/0-face/feedback.ts +40 -0
  11. package/DS1/0-face/format.ts +700 -0
  12. package/DS1/0-face/generated/toast-assets.ts +18 -0
  13. package/DS1/0-face/grid-fit.ts +1 -1
  14. package/DS1/0-face/grid.ts +3 -2
  15. package/DS1/0-face/header.ts +78 -0
  16. package/DS1/0-face/i18n.ts +93 -18
  17. package/DS1/0-face/keys.ts +276 -0
  18. package/DS1/0-face/languages.ts +4 -4
  19. package/DS1/0-face/layout-inspector.ts +6 -6
  20. package/DS1/0-face/library-styles.ts +33 -0
  21. package/DS1/0-face/load-toaster.ts +7 -0
  22. package/DS1/0-face/preference-options.ts +29 -0
  23. package/DS1/0-face/preferences.ts +3 -11
  24. package/DS1/0-face/pricing.ts +98 -43
  25. package/DS1/0-face/scaling.ts +160 -4
  26. package/DS1/0-face/shared-words.ts +9 -4
  27. package/DS1/0-face/sidebar.ts +201 -0
  28. package/DS1/0-face/theme-bootstrap.js +184 -0
  29. package/DS1/0-face/theme.ts +89 -47
  30. package/DS1/0-face/toast-queue.ts +157 -0
  31. package/DS1/0-face/toaster.ts +384 -0
  32. package/DS1/0-face/tooltips.ts +157 -15
  33. package/DS1/0-face/translations/da.json +60 -1
  34. package/DS1/0-face/translations/de.json +60 -1
  35. package/DS1/0-face/translations/en.json +60 -1
  36. package/DS1/0-face/translations/es.json +60 -1
  37. package/DS1/0-face/translations/fi.json +60 -1
  38. package/DS1/0-face/translations/fr.json +60 -1
  39. package/DS1/0-face/translations/is.json +60 -1
  40. package/DS1/0-face/translations/it.json +60 -1
  41. package/DS1/0-face/translations/ja.json +60 -1
  42. package/DS1/0-face/translations/ko.json +60 -1
  43. package/DS1/0-face/translations/nb.json +60 -1
  44. package/DS1/0-face/translations/pt-BR.json +60 -1
  45. package/DS1/0-face/translations/pt.json +60 -1
  46. package/DS1/0-face/translations/sv.json +60 -1
  47. package/DS1/0-face/translations/zh.json +60 -1
  48. package/DS1/0-face/translations-format.ts +3 -4
  49. package/DS1/1-root/card.css +192 -0
  50. package/DS1/1-root/carousel.css +136 -0
  51. package/DS1/1-root/cjk.css +23 -0
  52. package/DS1/1-root/component-metrics.css +1 -0
  53. package/DS1/1-root/component-tokens.css +51 -8
  54. package/DS1/1-root/controls.css +891 -14
  55. package/DS1/1-root/dialog-placement.css +191 -0
  56. package/DS1/1-root/document.css +183 -0
  57. package/DS1/1-root/drawer.css +83 -0
  58. package/DS1/1-root/empty.css +83 -0
  59. package/DS1/1-root/figures.css +141 -0
  60. package/DS1/1-root/fonts/Iosevka-LICENSE.md +3 -1
  61. package/DS1/1-root/fonts/Iosevka-Regular.woff2 +0 -0
  62. package/DS1/1-root/fonts.css +69 -0
  63. package/DS1/1-root/footer.css +186 -0
  64. package/DS1/1-root/header.css +165 -0
  65. package/DS1/1-root/library-tokens.ts +91 -0
  66. package/DS1/1-root/measures.ts +53 -0
  67. package/DS1/1-root/notice.css +165 -0
  68. package/DS1/1-root/one.css +14 -84
  69. package/DS1/1-root/one.semantic.css +200 -148
  70. package/DS1/1-root/palette.css +58 -0
  71. package/DS1/1-root/palette.ts +19 -0
  72. package/DS1/1-root/progress.css +356 -0
  73. package/DS1/1-root/prose.css +202 -0
  74. package/DS1/1-root/row.css +300 -0
  75. package/DS1/1-root/table.css +111 -0
  76. package/DS1/1-root/text.css +70 -0
  77. package/DS1/2-core/button-split.ts +55 -0
  78. package/DS1/2-core/chart/chart.css +169 -0
  79. package/DS1/2-core/chart/grid-chart.ts +554 -0
  80. package/DS1/2-core/ds-avatar.ts +25 -6
  81. package/DS1/2-core/ds-badge.ts +10 -10
  82. package/DS1/2-core/ds-button.ts +111 -26
  83. package/DS1/2-core/ds-card.ts +135 -105
  84. package/DS1/2-core/ds-chart.ts +327 -0
  85. package/DS1/2-core/ds-composer.ts +8 -2
  86. package/DS1/2-core/ds-cycle.ts +97 -21
  87. package/DS1/2-core/ds-empty.ts +120 -0
  88. package/DS1/2-core/ds-icon.ts +11 -2
  89. package/DS1/2-core/ds-input.ts +165 -6
  90. package/DS1/2-core/ds-message.ts +218 -0
  91. package/DS1/2-core/ds-notice.ts +10 -0
  92. package/DS1/2-core/ds-progress.ts +380 -0
  93. package/DS1/2-core/ds-stat.ts +174 -0
  94. package/DS1/2-core/ds-switch.ts +1 -0
  95. package/DS1/2-core/ds-text.ts +15 -2
  96. package/DS1/2-core/ds-toast.ts +354 -0
  97. package/DS1/2-core/figures.ts +105 -0
  98. package/DS1/2-core/generated/ds-icon-map.ts +238 -128
  99. package/DS1/2-core/generated/icon-avatar.ts +2 -0
  100. package/DS1/2-core/generated/icons-extra.ts +120 -65
  101. package/DS1/2-core/generated/icons-immediate.ts +1 -1
  102. package/DS1/2-core/styles/ds-avatar.css +9 -8
  103. package/DS1/2-core/styles/ds-button-host.css +26 -3
  104. package/DS1/2-core/styles/ds-button-split.css +67 -0
  105. package/DS1/2-core/styles/ds-button.css +49 -15
  106. package/DS1/2-core/styles/ds-card.css +34 -0
  107. package/DS1/2-core/styles/ds-composer.css +13 -0
  108. package/DS1/2-core/styles/ds-cycle.css +10 -0
  109. package/DS1/2-core/styles/ds-empty.css +18 -0
  110. package/DS1/2-core/styles/ds-gap.css +1 -0
  111. package/DS1/2-core/styles/ds-icon.css +1 -0
  112. package/DS1/2-core/styles/ds-input.css +59 -6
  113. package/DS1/2-core/styles/ds-notice.css +32 -0
  114. package/DS1/2-core/styles/ds-progress.css +25 -0
  115. package/DS1/2-core/styles/ds-select.css +2 -2
  116. package/DS1/2-core/styles/ds-split.css +2 -62
  117. package/DS1/2-core/styles/ds-stat.css +34 -0
  118. package/DS1/2-core/styles/ds-switch.css +16 -1
  119. package/DS1/2-core/styles/ds-text.css +43 -12
  120. package/DS1/2-core/styles/ds-toast.css +182 -0
  121. package/DS1/2-core/styles/ds-tooltip.css +1 -0
  122. package/DS1/3-unit/calendar-base.ts +263 -0
  123. package/DS1/3-unit/ds-accordion.ts +9 -1
  124. package/DS1/3-unit/ds-avatar-group.ts +1 -0
  125. package/DS1/3-unit/ds-calendar-large.ts +349 -0
  126. package/DS1/3-unit/ds-calendar.ts +344 -0
  127. package/DS1/3-unit/ds-carousel.ts +368 -0
  128. package/DS1/3-unit/ds-date-picker.ts +540 -0
  129. package/DS1/3-unit/ds-form.ts +45 -37
  130. package/DS1/3-unit/ds-list.ts +48 -1
  131. package/DS1/3-unit/ds-matrix.ts +318 -0
  132. package/DS1/3-unit/ds-menu.ts +8 -4
  133. package/DS1/3-unit/ds-row.ts +84 -1
  134. package/DS1/3-unit/ds-sidebar.ts +366 -0
  135. package/DS1/3-unit/ds-table.ts +75 -34
  136. package/DS1/3-unit/styles/ds-accordion.css +1 -0
  137. package/DS1/3-unit/styles/ds-avatar-group.css +2 -4
  138. package/DS1/3-unit/styles/ds-calendar-large.css +165 -0
  139. package/DS1/3-unit/styles/ds-calendar.css +238 -0
  140. package/DS1/3-unit/styles/ds-carousel.css +30 -0
  141. package/DS1/3-unit/styles/ds-date-picker.css +124 -0
  142. package/DS1/3-unit/styles/ds-list.css +1 -0
  143. package/DS1/3-unit/styles/ds-matrix.css +203 -0
  144. package/DS1/3-unit/styles/ds-menu.css +31 -6
  145. package/DS1/3-unit/styles/ds-row.css +84 -2
  146. package/DS1/3-unit/styles/ds-sidebar.css +134 -0
  147. package/DS1/3-unit/styles/ds-table.css +3 -74
  148. package/DS1/4-page/ds-dialog.ts +40 -4
  149. package/DS1/4-page/ds-document.ts +240 -0
  150. package/DS1/4-page/ds-footer.ts +165 -0
  151. package/DS1/4-page/ds-grid.ts +39 -59
  152. package/DS1/4-page/ds-header.ts +171 -0
  153. package/DS1/4-page/ds-page.ts +184 -0
  154. package/DS1/4-page/email.ts +2 -3
  155. package/DS1/4-page/styles/ds-container.css +1 -0
  156. package/DS1/4-page/styles/ds-document.css +18 -0
  157. package/DS1/4-page/styles/ds-footer.css +29 -0
  158. package/DS1/4-page/styles/ds-grid.css +31 -85
  159. package/DS1/4-page/styles/ds-header.css +57 -0
  160. package/DS1/4-page/styles/ds-page.css +214 -0
  161. package/DS1/components.ts +7 -1
  162. package/DS1/index.ts +24 -6
  163. package/DS1/react/avatar.ts +4 -5
  164. package/DS1/react/button-split.ts +29 -0
  165. package/DS1/react/button.ts +32 -13
  166. package/DS1/react/carousel.ts +76 -0
  167. package/DS1/react/dialog.ts +36 -5
  168. package/DS1/react/document.ts +14 -0
  169. package/DS1/react/empty.ts +32 -0
  170. package/DS1/react/footer.ts +17 -0
  171. package/DS1/react/header.ts +15 -0
  172. package/DS1/react/input.ts +28 -17
  173. package/DS1/react/message.ts +73 -0
  174. package/DS1/react/notice.ts +59 -0
  175. package/DS1/react/page.ts +13 -0
  176. package/DS1/react/progress.ts +99 -0
  177. package/DS1/react/sidebar.ts +71 -0
  178. package/DS1/react/stat.ts +73 -0
  179. package/DS1/react/toast.ts +82 -0
  180. package/DS1/x-icon/Tabler-LICENSE.md +27 -0
  181. package/DS1/x-icon/airtable.svg +5 -0
  182. package/DS1/x-icon/attach.svg +3 -0
  183. package/DS1/x-icon/audio.svg +3 -0
  184. package/DS1/x-icon/bag-alt.svg +3 -0
  185. package/DS1/x-icon/bank.svg +3 -0
  186. package/DS1/x-icon/banknote.svg +3 -0
  187. package/DS1/x-icon/bolt.svg +3 -0
  188. package/DS1/x-icon/book-alt.svg +3 -0
  189. package/DS1/x-icon/book.svg +4 -0
  190. package/DS1/x-icon/box.svg +3 -0
  191. package/DS1/x-icon/briefcase.svg +3 -0
  192. package/DS1/x-icon/building.svg +4 -0
  193. package/DS1/x-icon/car.svg +3 -0
  194. package/DS1/x-icon/card.svg +3 -0
  195. package/DS1/x-icon/cart.svg +3 -0
  196. package/DS1/x-icon/{ezo-android-screen-stats.svg → chevron-down.svg} +1 -1
  197. package/DS1/x-icon/{ezo-item-button-start.svg → chevron-left.svg} +1 -1
  198. package/DS1/x-icon/{ezo-android-screen-lists.svg → chevron-right.svg} +1 -1
  199. package/DS1/x-icon/{ezo-item-button-reopen.svg → chevron-up.svg} +1 -1
  200. package/DS1/x-icon/cloud.svg +3 -0
  201. package/DS1/x-icon/coffee.svg +3 -0
  202. package/DS1/x-icon/coins.svg +3 -0
  203. package/DS1/x-icon/cursor.svg +3 -0
  204. package/DS1/x-icon/curve.svg +7 -0
  205. package/DS1/x-icon/dislike.svg +4 -0
  206. package/DS1/x-icon/dot-bank.svg +3 -0
  207. package/DS1/x-icon/dot-banknote.svg +3 -0
  208. package/DS1/x-icon/dot-banknotes.svg +3 -0
  209. package/DS1/x-icon/dot-card.svg +3 -0
  210. package/DS1/x-icon/dot-coin.svg +3 -0
  211. package/DS1/x-icon/dot-coins.svg +3 -0
  212. package/DS1/x-icon/dot-receipt.svg +3 -0
  213. package/DS1/x-icon/dot-safe.svg +3 -0
  214. package/DS1/x-icon/dot-transfer.svg +3 -0
  215. package/DS1/x-icon/dot-wallet.svg +3 -0
  216. package/DS1/x-icon/download.svg +4 -0
  217. package/DS1/x-icon/drive.svg +5 -0
  218. package/DS1/x-icon/drop.svg +3 -0
  219. package/DS1/x-icon/dropbox.svg +3 -0
  220. package/DS1/x-icon/dumbbell.svg +3 -0
  221. package/DS1/x-icon/eye-off.svg +3 -0
  222. package/DS1/x-icon/eye.svg +3 -0
  223. package/DS1/x-icon/facebook.svg +3 -0
  224. package/DS1/x-icon/figma.svg +5 -0
  225. package/DS1/x-icon/flame.svg +3 -0
  226. package/DS1/x-icon/flip.svg +5 -0
  227. package/DS1/x-icon/food.svg +3 -0
  228. package/DS1/x-icon/fuel.svg +3 -0
  229. package/DS1/x-icon/game.svg +3 -0
  230. package/DS1/x-icon/gift.svg +3 -0
  231. package/DS1/x-icon/github.svg +3 -0
  232. package/DS1/x-icon/heart.svg +3 -0
  233. package/DS1/x-icon/history.svg +3 -0
  234. package/DS1/x-icon/home-alt.svg +3 -0
  235. package/DS1/x-icon/income.svg +3 -0
  236. package/DS1/x-icon/info.svg +5 -0
  237. package/DS1/x-icon/instagram.svg +5 -0
  238. package/DS1/x-icon/jpbank.svg +3 -0
  239. package/DS1/x-icon/key.svg +4 -0
  240. package/DS1/x-icon/keyboard.svg +3 -0
  241. package/DS1/x-icon/like.svg +4 -0
  242. package/DS1/x-icon/linkedin.svg +7 -0
  243. package/DS1/x-icon/loom.svg +6 -0
  244. package/DS1/x-icon/map.svg +4 -0
  245. package/DS1/x-icon/medical.svg +3 -0
  246. package/DS1/x-icon/minus.svg +3 -0
  247. package/DS1/x-icon/moon.svg +3 -0
  248. package/DS1/x-icon/move.svg +3 -0
  249. package/DS1/x-icon/music-alt.svg +3 -0
  250. package/DS1/x-icon/music.svg +5 -0
  251. package/DS1/x-icon/notion.svg +6 -0
  252. package/DS1/x-icon/offline.svg +3 -0
  253. package/DS1/x-icon/pause.svg +4 -0
  254. package/DS1/x-icon/paw.svg +3 -0
  255. package/DS1/x-icon/pdf.svg +3 -0
  256. package/DS1/x-icon/people.svg +5 -0
  257. package/DS1/x-icon/percent.svg +3 -0
  258. package/DS1/x-icon/phone.svg +3 -0
  259. package/DS1/x-icon/pill.svg +3 -0
  260. package/DS1/x-icon/plane.svg +3 -0
  261. package/DS1/x-icon/postal.svg +3 -0
  262. package/DS1/x-icon/present.svg +4 -0
  263. package/DS1/x-icon/reaction.svg +5 -0
  264. package/DS1/x-icon/receipt.svg +3 -0
  265. package/DS1/x-icon/refresh.svg +3 -0
  266. package/DS1/x-icon/refund.svg +3 -0
  267. package/DS1/x-icon/repeat.svg +3 -0
  268. package/DS1/x-icon/rotate.svg +4 -0
  269. package/DS1/x-icon/safe.svg +3 -0
  270. package/DS1/x-icon/school-alt.svg +3 -0
  271. package/DS1/x-icon/shield-alt.svg +3 -0
  272. package/DS1/x-icon/shield.svg +4 -0
  273. package/DS1/x-icon/shirt.svg +3 -0
  274. package/DS1/x-icon/shop.svg +3 -0
  275. package/DS1/x-icon/sign-in.svg +3 -0
  276. package/DS1/x-icon/sign-out.svg +3 -0
  277. package/DS1/x-icon/slack.svg +6 -0
  278. package/DS1/x-icon/sparkle.svg +3 -0
  279. package/DS1/x-icon/start.svg +4 -0
  280. package/DS1/x-icon/stop.svg +3 -0
  281. package/DS1/x-icon/sun.svg +3 -0
  282. package/DS1/x-icon/system.svg +4 -0
  283. package/DS1/x-icon/tag.svg +3 -0
  284. package/DS1/x-icon/ticket.svg +3 -0
  285. package/DS1/x-icon/title-struck.svg +4 -0
  286. package/DS1/x-icon/train.svg +3 -0
  287. package/DS1/x-icon/transfer.svg +3 -0
  288. package/DS1/x-icon/tv.svg +3 -0
  289. package/DS1/x-icon/upload.svg +4 -0
  290. package/DS1/x-icon/video.svg +4 -0
  291. package/DS1/x-icon/vimeo.svg +3 -0
  292. package/DS1/x-icon/wallet.svg +3 -0
  293. package/DS1/x-icon/wifi.svg +3 -0
  294. package/DS1/x-icon/window.svg +4 -0
  295. package/DS1/x-icon/wrench.svg +3 -0
  296. package/DS1/x-icon/x-brand.svg +4 -0
  297. package/DS1/x-icon/youtube.svg +4 -0
  298. package/README.md +3 -3
  299. package/dist/0-face/calendar.d.ts +75 -0
  300. package/dist/0-face/calendar.d.ts.map +1 -0
  301. package/dist/0-face/calendar.js +149 -0
  302. package/dist/0-face/carousel.d.ts +174 -0
  303. package/dist/0-face/carousel.d.ts.map +1 -0
  304. package/dist/0-face/carousel.js +583 -0
  305. package/dist/0-face/component-visibility.d.ts +7 -0
  306. package/dist/0-face/component-visibility.d.ts.map +1 -0
  307. package/dist/0-face/component-visibility.js +11 -0
  308. package/dist/0-face/copy-text.d.ts +11 -0
  309. package/dist/0-face/copy-text.d.ts.map +1 -0
  310. package/dist/0-face/copy-text.js +97 -0
  311. package/dist/0-face/device.d.ts +3 -7
  312. package/dist/0-face/device.d.ts.map +1 -1
  313. package/dist/0-face/device.js +7 -41
  314. package/dist/0-face/dialog-swipe.d.ts +49 -0
  315. package/dist/0-face/dialog-swipe.d.ts.map +1 -0
  316. package/dist/0-face/dialog-swipe.js +239 -0
  317. package/dist/0-face/dialogs.d.ts +33 -0
  318. package/dist/0-face/dialogs.d.ts.map +1 -0
  319. package/dist/0-face/dialogs.js +173 -0
  320. package/dist/0-face/drawer.d.ts +64 -0
  321. package/dist/0-face/drawer.d.ts.map +1 -0
  322. package/dist/0-face/drawer.js +256 -0
  323. package/dist/0-face/feedback-words.d.ts +21 -0
  324. package/dist/0-face/feedback-words.d.ts.map +1 -0
  325. package/dist/0-face/feedback-words.js +30 -0
  326. package/dist/0-face/feedback.d.ts +41 -0
  327. package/dist/0-face/feedback.d.ts.map +1 -0
  328. package/dist/0-face/feedback.js +35 -0
  329. package/dist/0-face/format.d.ts +166 -0
  330. package/dist/0-face/format.d.ts.map +1 -0
  331. package/dist/0-face/format.js +445 -0
  332. package/dist/0-face/generated/toast-assets.d.ts +11 -0
  333. package/dist/0-face/generated/toast-assets.d.ts.map +1 -0
  334. package/dist/0-face/generated/toast-assets.js +14 -0
  335. package/dist/0-face/grid-fit.js +1 -1
  336. package/dist/0-face/grid.d.ts.map +1 -1
  337. package/dist/0-face/grid.js +2 -1
  338. package/dist/0-face/header.d.ts +38 -0
  339. package/dist/0-face/header.d.ts.map +1 -0
  340. package/dist/0-face/header.js +80 -0
  341. package/dist/0-face/i18n.d.ts +32 -2
  342. package/dist/0-face/i18n.d.ts.map +1 -1
  343. package/dist/0-face/i18n.js +65 -19
  344. package/dist/0-face/keys.d.ts +104 -0
  345. package/dist/0-face/keys.d.ts.map +1 -0
  346. package/dist/0-face/keys.js +253 -0
  347. package/dist/0-face/languages.d.ts +2 -2
  348. package/dist/0-face/languages.js +3 -3
  349. package/dist/0-face/layout-inspector.js +6 -6
  350. package/dist/0-face/library-styles.d.ts +7 -0
  351. package/dist/0-face/library-styles.d.ts.map +1 -0
  352. package/dist/0-face/library-styles.js +29 -0
  353. package/dist/0-face/load-toaster.d.ts +8 -0
  354. package/dist/0-face/load-toaster.d.ts.map +1 -0
  355. package/dist/0-face/load-toaster.js +7 -0
  356. package/dist/0-face/preference-options.d.ts +34 -0
  357. package/dist/0-face/preference-options.d.ts.map +1 -0
  358. package/dist/0-face/preference-options.js +1 -0
  359. package/dist/0-face/preferences.d.ts +3 -12
  360. package/dist/0-face/preferences.d.ts.map +1 -1
  361. package/dist/0-face/pricing.d.ts +19 -9
  362. package/dist/0-face/pricing.d.ts.map +1 -1
  363. package/dist/0-face/pricing.js +81 -40
  364. package/dist/0-face/scaling.d.ts +71 -1
  365. package/dist/0-face/scaling.d.ts.map +1 -1
  366. package/dist/0-face/scaling.js +108 -3
  367. package/dist/0-face/shared-words.d.ts +9 -4
  368. package/dist/0-face/shared-words.d.ts.map +1 -1
  369. package/dist/0-face/sidebar.d.ts +69 -0
  370. package/dist/0-face/sidebar.d.ts.map +1 -0
  371. package/dist/0-face/sidebar.js +191 -0
  372. package/dist/0-face/theme-bootstrap.d.ts +1 -0
  373. package/dist/0-face/theme-bootstrap.d.ts.map +1 -0
  374. package/dist/0-face/theme-bootstrap.js +214 -0
  375. package/dist/0-face/theme.d.ts +32 -0
  376. package/dist/0-face/theme.d.ts.map +1 -1
  377. package/dist/0-face/theme.js +69 -43
  378. package/dist/0-face/toast-queue.d.ts +110 -0
  379. package/dist/0-face/toast-queue.d.ts.map +1 -0
  380. package/dist/0-face/toast-queue.js +98 -0
  381. package/dist/0-face/toaster.d.ts +27 -0
  382. package/dist/0-face/toaster.d.ts.map +1 -0
  383. package/dist/0-face/toaster.js +373 -0
  384. package/dist/0-face/tooltips.d.ts +24 -1
  385. package/dist/0-face/tooltips.d.ts.map +1 -1
  386. package/dist/0-face/tooltips.js +155 -16
  387. package/dist/0-face/translations/da.json +60 -1
  388. package/dist/0-face/translations/de.json +60 -1
  389. package/dist/0-face/translations/en.json +60 -1
  390. package/dist/0-face/translations/es.json +60 -1
  391. package/dist/0-face/translations/fi.json +60 -1
  392. package/dist/0-face/translations/fr.json +60 -1
  393. package/dist/0-face/translations/is.json +60 -1
  394. package/dist/0-face/translations/it.json +60 -1
  395. package/dist/0-face/translations/ja.json +60 -1
  396. package/dist/0-face/translations/ko.json +60 -1
  397. package/dist/0-face/translations/nb.json +60 -1
  398. package/dist/0-face/translations/pt-BR.json +60 -1
  399. package/dist/0-face/translations/pt.json +60 -1
  400. package/dist/0-face/translations/sv.json +60 -1
  401. package/dist/0-face/translations/zh.json +60 -1
  402. package/dist/0-face/translations-format.d.ts.map +1 -1
  403. package/dist/0-face/translations-format.js +3 -4
  404. package/dist/1-root/library-tokens.d.ts +31 -0
  405. package/dist/1-root/library-tokens.d.ts.map +1 -0
  406. package/dist/1-root/library-tokens.js +84 -0
  407. package/dist/1-root/measures.d.ts +52 -0
  408. package/dist/1-root/measures.d.ts.map +1 -0
  409. package/dist/1-root/measures.js +49 -0
  410. package/dist/1-root/palette.d.ts +5 -0
  411. package/dist/1-root/palette.d.ts.map +1 -1
  412. package/dist/1-root/palette.js +18 -0
  413. package/dist/2-core/button-split.d.ts +21 -0
  414. package/dist/2-core/button-split.d.ts.map +1 -0
  415. package/dist/2-core/button-split.js +48 -0
  416. package/dist/2-core/chart/grid-chart.d.ts +113 -0
  417. package/dist/2-core/chart/grid-chart.d.ts.map +1 -0
  418. package/dist/2-core/chart/grid-chart.js +466 -0
  419. package/dist/2-core/ds-avatar.d.ts +20 -3
  420. package/dist/2-core/ds-avatar.d.ts.map +1 -1
  421. package/dist/2-core/ds-avatar.js +19 -5
  422. package/dist/2-core/ds-badge.js +10 -13
  423. package/dist/2-core/ds-button.d.ts +76 -0
  424. package/dist/2-core/ds-button.d.ts.map +1 -1
  425. package/dist/2-core/ds-button.js +101 -26
  426. package/dist/2-core/ds-card.d.ts +76 -11
  427. package/dist/2-core/ds-card.d.ts.map +1 -1
  428. package/dist/2-core/ds-card.js +129 -105
  429. package/dist/2-core/ds-chart.d.ts +105 -0
  430. package/dist/2-core/ds-chart.d.ts.map +1 -0
  431. package/dist/2-core/ds-chart.js +390 -0
  432. package/dist/2-core/ds-composer.d.ts +7 -0
  433. package/dist/2-core/ds-composer.d.ts.map +1 -1
  434. package/dist/2-core/ds-composer.js +1 -1
  435. package/dist/2-core/ds-cycle.d.ts +36 -2
  436. package/dist/2-core/ds-cycle.d.ts.map +1 -1
  437. package/dist/2-core/ds-cycle.js +95 -18
  438. package/dist/2-core/ds-empty.d.ts +74 -0
  439. package/dist/2-core/ds-empty.d.ts.map +1 -0
  440. package/dist/2-core/ds-empty.js +96 -0
  441. package/dist/2-core/ds-icon.d.ts +6 -0
  442. package/dist/2-core/ds-icon.d.ts.map +1 -1
  443. package/dist/2-core/ds-icon.js +12 -2
  444. package/dist/2-core/ds-input.d.ts +39 -1
  445. package/dist/2-core/ds-input.d.ts.map +1 -1
  446. package/dist/2-core/ds-input.js +150 -6
  447. package/dist/2-core/ds-message.d.ts +154 -0
  448. package/dist/2-core/ds-message.d.ts.map +1 -0
  449. package/dist/2-core/ds-message.js +177 -0
  450. package/dist/2-core/ds-notice.d.ts +13 -0
  451. package/dist/2-core/ds-notice.d.ts.map +1 -0
  452. package/dist/2-core/ds-notice.js +11 -0
  453. package/dist/2-core/ds-progress.d.ts +200 -0
  454. package/dist/2-core/ds-progress.d.ts.map +1 -0
  455. package/dist/2-core/ds-progress.js +319 -0
  456. package/dist/2-core/ds-stat.d.ts +126 -0
  457. package/dist/2-core/ds-stat.d.ts.map +1 -0
  458. package/dist/2-core/ds-stat.js +137 -0
  459. package/dist/2-core/ds-switch.d.ts +1 -0
  460. package/dist/2-core/ds-switch.d.ts.map +1 -1
  461. package/dist/2-core/ds-switch.js +1 -0
  462. package/dist/2-core/ds-text.d.ts +15 -2
  463. package/dist/2-core/ds-text.d.ts.map +1 -1
  464. package/dist/2-core/ds-text.js +13 -0
  465. package/dist/2-core/ds-toast.d.ts +139 -0
  466. package/dist/2-core/ds-toast.d.ts.map +1 -0
  467. package/dist/2-core/ds-toast.js +329 -0
  468. package/dist/2-core/figures.d.ts +56 -0
  469. package/dist/2-core/figures.d.ts.map +1 -0
  470. package/dist/2-core/figures.js +70 -0
  471. package/dist/2-core/generated/ds-icon-map.d.ts +120 -65
  472. package/dist/2-core/generated/ds-icon-map.d.ts.map +1 -1
  473. package/dist/2-core/generated/ds-icon-map.js +238 -128
  474. package/dist/2-core/generated/icon-avatar.d.ts +2 -0
  475. package/dist/2-core/generated/icon-avatar.d.ts.map +1 -0
  476. package/dist/2-core/generated/icon-avatar.js +2 -0
  477. package/dist/2-core/generated/icons-extra.d.ts.map +1 -1
  478. package/dist/2-core/generated/icons-extra.js +120 -65
  479. package/dist/2-core/generated/icons-immediate.d.ts +1 -1
  480. package/dist/2-core/generated/icons-immediate.d.ts.map +1 -1
  481. package/dist/2-core/generated/icons-immediate.js +1 -1
  482. package/dist/3-unit/calendar-base.d.ts +149 -0
  483. package/dist/3-unit/calendar-base.d.ts.map +1 -0
  484. package/dist/3-unit/calendar-base.js +172 -0
  485. package/dist/3-unit/ds-accordion.d.ts +9 -0
  486. package/dist/3-unit/ds-accordion.d.ts.map +1 -1
  487. package/dist/3-unit/ds-accordion.js +7 -1
  488. package/dist/3-unit/ds-avatar-group.d.ts +1 -0
  489. package/dist/3-unit/ds-avatar-group.d.ts.map +1 -1
  490. package/dist/3-unit/ds-calendar-large.d.ts +138 -0
  491. package/dist/3-unit/ds-calendar-large.d.ts.map +1 -0
  492. package/dist/3-unit/ds-calendar-large.js +305 -0
  493. package/dist/3-unit/ds-calendar.d.ts +175 -0
  494. package/dist/3-unit/ds-calendar.d.ts.map +1 -0
  495. package/dist/3-unit/ds-calendar.js +303 -0
  496. package/dist/3-unit/ds-carousel.d.ts +182 -0
  497. package/dist/3-unit/ds-carousel.d.ts.map +1 -0
  498. package/dist/3-unit/ds-carousel.js +327 -0
  499. package/dist/3-unit/ds-date-picker.d.ts +203 -0
  500. package/dist/3-unit/ds-date-picker.d.ts.map +1 -0
  501. package/dist/3-unit/ds-date-picker.js +499 -0
  502. package/dist/3-unit/ds-form.d.ts.map +1 -1
  503. package/dist/3-unit/ds-form.js +38 -28
  504. package/dist/3-unit/ds-list.d.ts +12 -0
  505. package/dist/3-unit/ds-list.d.ts.map +1 -1
  506. package/dist/3-unit/ds-list.js +52 -1
  507. package/dist/3-unit/ds-matrix.d.ts +146 -0
  508. package/dist/3-unit/ds-matrix.d.ts.map +1 -0
  509. package/dist/3-unit/ds-matrix.js +248 -0
  510. package/dist/3-unit/ds-menu.d.ts +1 -1
  511. package/dist/3-unit/ds-menu.d.ts.map +1 -1
  512. package/dist/3-unit/ds-menu.js +7 -4
  513. package/dist/3-unit/ds-row.d.ts +66 -0
  514. package/dist/3-unit/ds-row.d.ts.map +1 -1
  515. package/dist/3-unit/ds-row.js +80 -1
  516. package/dist/3-unit/ds-sidebar.d.ts +149 -0
  517. package/dist/3-unit/ds-sidebar.d.ts.map +1 -0
  518. package/dist/3-unit/ds-sidebar.js +342 -0
  519. package/dist/3-unit/ds-table.d.ts +28 -10
  520. package/dist/3-unit/ds-table.d.ts.map +1 -1
  521. package/dist/3-unit/ds-table.js +53 -25
  522. package/dist/4-page/ds-dialog.d.ts +16 -1
  523. package/dist/4-page/ds-dialog.d.ts.map +1 -1
  524. package/dist/4-page/ds-dialog.js +39 -3
  525. package/dist/4-page/ds-document.d.ts +98 -0
  526. package/dist/4-page/ds-document.d.ts.map +1 -0
  527. package/dist/4-page/ds-document.js +213 -0
  528. package/dist/4-page/ds-footer.d.ts +100 -0
  529. package/dist/4-page/ds-footer.d.ts.map +1 -0
  530. package/dist/4-page/ds-footer.js +119 -0
  531. package/dist/4-page/ds-grid.d.ts +32 -12
  532. package/dist/4-page/ds-grid.d.ts.map +1 -1
  533. package/dist/4-page/ds-grid.js +30 -39
  534. package/dist/4-page/ds-header.d.ts +84 -0
  535. package/dist/4-page/ds-header.d.ts.map +1 -0
  536. package/dist/4-page/ds-header.js +143 -0
  537. package/dist/4-page/ds-page.d.ts +110 -0
  538. package/dist/4-page/ds-page.d.ts.map +1 -0
  539. package/dist/4-page/ds-page.js +155 -0
  540. package/dist/4-page/email.d.ts +2 -3
  541. package/dist/4-page/email.d.ts.map +1 -1
  542. package/dist/4-page/email.js +2 -3
  543. package/dist/components.d.ts +4 -1
  544. package/dist/components.d.ts.map +1 -1
  545. package/dist/components.js +4 -1
  546. package/dist/design-system-1.bundle.js +12322 -5523
  547. package/dist/design-system-1.bundle.js.map +1 -1
  548. package/dist/design-system-1.bundle.min.js +8771 -4115
  549. package/dist/design-system-1.bundle.min.js.map +1 -1
  550. package/dist/design-system-1.css +1 -1
  551. package/dist/feedback.js +541 -0
  552. package/dist/feedback.js.map +1 -0
  553. package/dist/{icons-extra-BoAACA4X.js → icons-extra-CiDDs7_-.js} +404 -312
  554. package/dist/icons-extra-CiDDs7_-.js.map +1 -0
  555. package/dist/{icons-extra-DlxTo_Y4.js → icons-extra-hauwCx07.js} +121 -66
  556. package/dist/icons-extra-hauwCx07.js.map +1 -0
  557. package/dist/index.d.ts +21 -6
  558. package/dist/index.d.ts.map +1 -1
  559. package/dist/index.js +21 -6
  560. package/dist/react/avatar.d.ts +5 -9
  561. package/dist/react/avatar.d.ts.map +1 -1
  562. package/dist/react/avatar.js +2 -2
  563. package/dist/react/button-split.d.ts +19 -0
  564. package/dist/react/button-split.d.ts.map +1 -0
  565. package/dist/react/{split.js → button-split.js} +12 -9
  566. package/dist/react/button.d.ts +18 -7
  567. package/dist/react/button.d.ts.map +1 -1
  568. package/dist/react/button.js +13 -4
  569. package/dist/react/carousel.d.ts +63 -0
  570. package/dist/react/carousel.d.ts.map +1 -0
  571. package/dist/react/carousel.js +47 -0
  572. package/dist/react/choice.d.ts +1 -1
  573. package/dist/react/context-menu.d.ts +337 -337
  574. package/dist/react/dialog.d.ts +684 -678
  575. package/dist/react/dialog.d.ts.map +1 -1
  576. package/dist/react/dialog.js +29 -3
  577. package/dist/react/document.d.ts +11 -0
  578. package/dist/react/document.d.ts.map +1 -0
  579. package/dist/react/document.js +10 -0
  580. package/dist/react/empty.d.ts +34 -0
  581. package/dist/react/empty.d.ts.map +1 -0
  582. package/dist/react/empty.js +8 -0
  583. package/dist/react/file-picker.d.ts +1 -1
  584. package/dist/react/footer.d.ts +13 -0
  585. package/dist/react/footer.d.ts.map +1 -0
  586. package/dist/react/footer.js +12 -0
  587. package/dist/react/header.d.ts +12 -0
  588. package/dist/react/header.d.ts.map +1 -0
  589. package/dist/react/header.js +11 -0
  590. package/dist/react/input.d.ts +31 -9
  591. package/dist/react/input.d.ts.map +1 -1
  592. package/dist/react/input.js +94 -94
  593. package/dist/react/message.d.ts +66 -0
  594. package/dist/react/message.d.ts.map +1 -0
  595. package/dist/react/message.js +37 -0
  596. package/dist/react/notice.d.ts +45 -0
  597. package/dist/react/notice.d.ts.map +1 -0
  598. package/dist/react/notice.js +34 -0
  599. package/dist/react/page.d.ts +10 -0
  600. package/dist/react/page.d.ts.map +1 -0
  601. package/dist/react/page.js +9 -0
  602. package/dist/react/progress.d.ts +107 -0
  603. package/dist/react/progress.d.ts.map +1 -0
  604. package/dist/react/progress.js +47 -0
  605. package/dist/react/sidebar.d.ts +54 -0
  606. package/dist/react/sidebar.d.ts.map +1 -0
  607. package/dist/react/sidebar.js +48 -0
  608. package/dist/react/stat.d.ts +78 -0
  609. package/dist/react/stat.d.ts.map +1 -0
  610. package/dist/react/stat.js +25 -0
  611. package/dist/react/toast.d.ts +37 -0
  612. package/dist/react/toast.d.ts.map +1 -0
  613. package/dist/react/toast.js +55 -0
  614. package/dist/shared-words-CyZYc_De.js +1818 -0
  615. package/dist/shared-words-CyZYc_De.js.map +1 -0
  616. package/dist/shared-words-DAVSET4Z.js +1800 -0
  617. package/dist/shared-words-DAVSET4Z.js.map +1 -0
  618. package/package.json +19 -6
  619. package/DS1/2-core/ds-banner.ts +0 -122
  620. package/DS1/2-core/ds-date.ts +0 -24
  621. package/DS1/2-core/ds-language.ts +0 -94
  622. package/DS1/2-core/ds-pagedots.ts +0 -52
  623. package/DS1/2-core/ds-split.ts +0 -122
  624. package/DS1/2-core/ds-textarea.ts +0 -136
  625. package/DS1/2-core/styles/ds-banner.css +0 -77
  626. package/DS1/2-core/styles/ds-date.css +0 -9
  627. package/DS1/2-core/styles/ds-language.css +0 -78
  628. package/DS1/2-core/styles/ds-pagedots.css +0 -31
  629. package/DS1/2-core/styles/ds-textarea.css +0 -27
  630. package/DS1/4-page/ds-layout.ts +0 -949
  631. package/DS1/4-page/styles/ds-layout.css +0 -246
  632. package/DS1/react/split.ts +0 -42
  633. package/DS1/x-icon/ezo-accordion-chevron.svg +0 -11
  634. package/DS1/x-icon/ezo-account-close.svg +0 -1
  635. package/DS1/x-icon/ezo-android-screen-archive.svg +0 -4
  636. package/DS1/x-icon/ezo-android-screen-calendar.svg +0 -6
  637. package/DS1/x-icon/ezo-android-screen-camera.svg +0 -5
  638. package/DS1/x-icon/ezo-android-screen-check.svg +0 -3
  639. package/DS1/x-icon/ezo-android-screen-compose.svg +0 -4
  640. package/DS1/x-icon/ezo-android-screen-globe.svg +0 -1
  641. package/DS1/x-icon/ezo-android-screen-shared.svg +0 -5
  642. package/DS1/x-icon/ezo-android-screen-store.svg +0 -4
  643. package/DS1/x-icon/ezo-android-screen-views.svg +0 -4
  644. package/DS1/x-icon/ezo-android-screen-work.svg +0 -3
  645. package/DS1/x-icon/ezo-arrow-cursor.svg +0 -8
  646. package/DS1/x-icon/ezo-block-accordion.svg +0 -1
  647. package/DS1/x-icon/ezo-block-divider.svg +0 -1
  648. package/DS1/x-icon/ezo-block-group.svg +0 -1
  649. package/DS1/x-icon/ezo-block-image.svg +0 -1
  650. package/DS1/x-icon/ezo-block-section.svg +0 -1
  651. package/DS1/x-icon/ezo-block-table.svg +0 -1
  652. package/DS1/x-icon/ezo-code.svg +0 -14
  653. package/DS1/x-icon/ezo-down.svg +0 -3
  654. package/DS1/x-icon/ezo-figma-premium-star.svg +0 -5
  655. package/DS1/x-icon/ezo-item-button-complete.svg +0 -4
  656. package/DS1/x-icon/ezo-item-button-header.svg +0 -3
  657. package/DS1/x-icon/ezo-item-button-open.svg +0 -3
  658. package/DS1/x-icon/ezo-item-button-star.svg +0 -3
  659. package/DS1/x-icon/ezo-item-button-unheader.svg +0 -7
  660. package/DS1/x-icon/ezo-item-button-unstar.svg +0 -5
  661. package/DS1/x-icon/ezo-item-star.svg +0 -5
  662. package/DS1/x-icon/ezo-left.svg +0 -3
  663. package/DS1/x-icon/ezo-logo.svg +0 -1
  664. package/DS1/x-icon/ezo-mic.svg +0 -8
  665. package/DS1/x-icon/ezo-move-column.svg +0 -14
  666. package/DS1/x-icon/ezo-move-row.svg +0 -18
  667. package/DS1/x-icon/ezo-navigation-check.svg +0 -1
  668. package/DS1/x-icon/ezo-note-back.svg +0 -5
  669. package/DS1/x-icon/ezo-note-menu-complete.svg +0 -11
  670. package/DS1/x-icon/ezo-note-menu-delete.svg +0 -4
  671. package/DS1/x-icon/ezo-note-menu-duplicate.svg +0 -8
  672. package/DS1/x-icon/ezo-note-menu-note.svg +0 -5
  673. package/DS1/x-icon/ezo-note-menu-page.svg +0 -3
  674. package/DS1/x-icon/ezo-note-menu-star.svg +0 -5
  675. package/DS1/x-icon/ezo-note-menu-start.svg +0 -6
  676. package/DS1/x-icon/ezo-note-menu-stop.svg +0 -6
  677. package/DS1/x-icon/ezo-note-more.svg +0 -7
  678. package/DS1/x-icon/ezo-note-star.svg +0 -5
  679. package/DS1/x-icon/ezo-pattern-call-to-action.svg +0 -1
  680. package/DS1/x-icon/ezo-play.svg +0 -5
  681. package/DS1/x-icon/ezo-premium-star.svg +0 -5
  682. package/DS1/x-icon/ezo-setting-1xdots.svg +0 -13
  683. package/DS1/x-icon/ezo-setting-1xgrid.svg +0 -10
  684. package/DS1/x-icon/ezo-setting-1xlines.svg +0 -7
  685. package/DS1/x-icon/ezo-setting-2xdots.svg +0 -8
  686. package/DS1/x-icon/ezo-setting-2xgrid.svg +0 -8
  687. package/DS1/x-icon/ezo-setting-2xlines.svg +0 -6
  688. package/DS1/x-icon/ezo-setting-blank.svg +0 -5
  689. package/DS1/x-icon/ezo-store-chevron.svg +0 -1
  690. package/DS1/x-icon/ezo-upgrade-close.svg +0 -5
  691. package/DS1/x-icon/product-sources.json +0 -2557
  692. package/dist/2-core/ds-banner.d.ts +0 -68
  693. package/dist/2-core/ds-banner.d.ts.map +0 -1
  694. package/dist/2-core/ds-banner.js +0 -98
  695. package/dist/2-core/ds-date.d.ts +0 -16
  696. package/dist/2-core/ds-date.d.ts.map +0 -1
  697. package/dist/2-core/ds-date.js +0 -15
  698. package/dist/2-core/ds-language.d.ts +0 -75
  699. package/dist/2-core/ds-language.d.ts.map +0 -1
  700. package/dist/2-core/ds-language.js +0 -74
  701. package/dist/2-core/ds-pagedots.d.ts +0 -32
  702. package/dist/2-core/ds-pagedots.d.ts.map +0 -1
  703. package/dist/2-core/ds-pagedots.js +0 -36
  704. package/dist/2-core/ds-split.d.ts +0 -75
  705. package/dist/2-core/ds-split.d.ts.map +0 -1
  706. package/dist/2-core/ds-split.js +0 -101
  707. package/dist/2-core/ds-textarea.d.ts +0 -46
  708. package/dist/2-core/ds-textarea.d.ts.map +0 -1
  709. package/dist/2-core/ds-textarea.js +0 -121
  710. package/dist/4-page/ds-layout.d.ts +0 -31
  711. package/dist/4-page/ds-layout.d.ts.map +0 -1
  712. package/dist/4-page/ds-layout.js +0 -930
  713. package/dist/icons-extra-BoAACA4X.js.map +0 -1
  714. package/dist/icons-extra-DlxTo_Y4.js.map +0 -1
  715. package/dist/react/split.d.ts +0 -15
  716. package/dist/react/split.d.ts.map +0 -1
  717. package/dist/shared-words-Cg6Phtx0.js +0 -915
  718. package/dist/shared-words-Cg6Phtx0.js.map +0 -1
  719. package/dist/shared-words-Ddz0yUEF.js +0 -933
  720. package/dist/shared-words-Ddz0yUEF.js.map +0 -1
  721. /package/DS1/x-icon/{ezo-password-visibility-see.svg → password-see.svg} +0 -0
  722. /package/DS1/x-icon/{ezo-password-visibility-unsee.svg → password-unsee.svg} +0 -0
@@ -0,0 +1,623 @@
1
+ /**
2
+ * Carousels without Lit: the behaviour of `.ds-carousel` (drawn by
3
+ * `1-root/carousel.css`) and its dots (`.ds-progress--dots`, from
4
+ * `progress.css`) on a page's own markup, and the pieces `ds-carousel` and
5
+ * `ds-progress` share with it. No framework and no imports.
6
+ *
7
+ * ```html
8
+ * <section class="ds-carousel" aria-label="Colours">
9
+ * <div class="ds-carousel__track">
10
+ * <figure>…</figure>
11
+ * <figure>…</figure>
12
+ * </div>
13
+ * <div class="ds-carousel__controls">
14
+ * <button class="ds-button ds-button--icon ds-carousel__previous" type="button">…</button>
15
+ * <div class="ds-progress ds-progress--dots"></div>
16
+ * <button class="ds-button ds-button--icon ds-carousel__next" type="button">…</button>
17
+ * </div>
18
+ * </section>
19
+ * <script type="module">
20
+ * import { startCarousels } from "/ds1/0-face/carousel.js";
21
+ * startCarousels();
22
+ * </script>
23
+ * ```
24
+ *
25
+ * `startCarousels()` starts every `.ds-carousel` on the page: it makes the
26
+ * block a region described as a carousel, each slide a group labelled "2 of
27
+ * 5" (unless the page labels it), fills `.ds-progress--dots` with a dot for each
28
+ * slide, keeps the dots and the buttons on the slide in view, and announces
29
+ * the current slide politely in a `.ds-carousel__status` it adds. Dots take
30
+ * the arrow keys, Home and End. Scrolling is instant when the reader asks for
31
+ * reduced motion. The block fires `change` (`detail: { index, previous }`)
32
+ * when a person moves to another slide.
33
+ *
34
+ * A strip of things of their own width (`data-slides="auto"`, several in
35
+ * view, each stopping at the strip's start) takes three more options, as data
36
+ * attributes on `.ds-carousel` (and attributes of the same names on
37
+ * `ds-carousel`):
38
+ *
39
+ * - `data-bleed`: `none` (the default) keeps the strip in its box; `end` runs
40
+ * it on to the window's end edge, the first slide still on the box's start;
41
+ * `both` runs it to both edges, slides passing out of the box at its start.
42
+ * - `data-loop`: the slides held three times over, the copies unseen by
43
+ * assistive technology and never focused, so the strip has no end. A
44
+ * looping carousel draws no dots.
45
+ * - `data-autoplay`: move on a slide at a time by itself every so many
46
+ * milliseconds (`data-autoplay="5000"`; empty is 5000). Held while the
47
+ * pointer, a finger or the keyboard is in the strip, while it is out of
48
+ * view or the page hidden, and never for a reader who asks for reduced
49
+ * motion. A pause button (`.ds-carousel__pause`) is always drawn with it
50
+ * (WCAG 2.2.2).
51
+ * - `data-snap="none"`: slide freely, without stopping at slides.
52
+ *
53
+ * The words read English, or the shared words in the page's language where
54
+ * the page loads the language module; `setCarouselWords()` gives others.
55
+ */
56
+
57
+ /** The words a carousel says, keyed by the shared words' English. */
58
+ export type CarouselWord = "Carousel" | "Slide" | "Slides" | "Slide {index}" | "{index} of {count}" | "Previous slide" | "Next slide" | "Pause" | "Play";
59
+
60
+ /** What a strip's drive can be told; every option is off unless given. */
61
+ export interface CarouselDriveOptions {
62
+ bleed?: "none" | "end" | "both";
63
+ loop?: boolean;
64
+ /** Milliseconds between steps; `0` or absent for none. */
65
+ autoplay?: number;
66
+ /** A copy was made: mark and change it before it is placed. */
67
+ onCopy?: (copy: HTMLElement) => void;
68
+ }
69
+
70
+ /** A running drive: the bleed's measures, the loop's copies and autoplay. */
71
+ export interface CarouselDrive {
72
+ /** Moves a slide on (`1`) or back (`-1`). */
73
+ step(direction: 1 | -1): void;
74
+ /** Holds or resumes autoplay, as the pause button does. */
75
+ pause(paused: boolean): void;
76
+ /** Whether autoplay is held by the pause button. */
77
+ readonly paused: boolean;
78
+ stop(): void;
79
+ }
80
+
81
+ /** How long an autoplaying carousel stands when no interval is given. */
82
+ export const CAROUSEL_AUTOPLAY_MS = 5000;
83
+
84
+ /** An autoplay interval from an attribute: empty or `true` is the default, a number of milliseconds otherwise, at least a second. */
85
+ export function autoplayInterval(value: string | number | boolean | null | undefined): number {
86
+ if (value === null || value === undefined || value === false || value === "false") return 0;
87
+ if (value === "" || value === true || value === "true") return CAROUSEL_AUTOPLAY_MS;
88
+ const milliseconds = Number(value);
89
+ return Number.isFinite(milliseconds) && milliseconds > 0 ? Math.max(1000, milliseconds) : 0;
90
+ }
91
+
92
+ /** Marks an element as a copy made for a loop. */
93
+ export const COPY = "data-ds-carousel-copy";
94
+ const isCopy = (element: Element) => element.hasAttribute(COPY);
95
+ /** Whether an attribute asks for a bleed. */
96
+ export const bleedOf = (value: string | undefined): CarouselDriveOptions["bleed"] => (value === "end" || value === "both" ? value : "none");
97
+ export type CarouselWords = Partial<Record<CarouselWord, string>> | ((word: CarouselWord, params: Record<string, string | number>) => string);
98
+
99
+ /** Where the language module leaves its `translate()`, shared with the feedback module. */
100
+ const TRANSLATOR = Symbol.for("design-system-1.translate");
101
+ let words: CarouselWords | null = null;
102
+
103
+ /** Give the carousel script words of the page's own, or `null` for the language module's (or English). */
104
+ export function setCarouselWords(next: CarouselWords | null): void {
105
+ words = next;
106
+ }
107
+
108
+ const fill = (text: string, params: Record<string, string | number>) =>
109
+ text.replace(/\{\{?(\w+)\}?\}/g, (whole, name: string) => (name in params ? String(params[name]) : whole));
110
+
111
+ /** A carousel word in the page's language, with its placeholders filled. */
112
+ export function carouselWord(word: CarouselWord, params: Record<string, string | number> = {}): string {
113
+ if (typeof words === "function") return words(word, params);
114
+ const own = words?.[word];
115
+ if (own !== undefined) return fill(own, params);
116
+ const translate = (globalThis as unknown as Record<symbol, unknown>)[TRANSLATOR];
117
+ return fill(typeof translate === "function" ? String(translate(word, params)) : word, params);
118
+ }
119
+
120
+ /** How a dot is drawn: before, at or after the current slide, or the end marker. */
121
+ export type DotState = "past" | "current" | "next" | "future" | "end";
122
+
123
+ /** The state of dot `index` of `count` when `current` is the slide in view. */
124
+ export function dotState(index: number, current: number, count: number, end = false): DotState {
125
+ if (index === current) return "current";
126
+ if (end && index === count - 1) return "end";
127
+ if (index < current) return "past";
128
+ return index === current + 1 ? "next" : "future";
129
+ }
130
+
131
+ /**
132
+ * The dot a key moves to from `index`, or `undefined` for a key dots leave
133
+ * alone. Left and right follow the reading direction.
134
+ */
135
+ export function dotForKey(key: string, index: number, count: number, rtl = false): number | undefined {
136
+ const forward = rtl ? "ArrowLeft" : "ArrowRight";
137
+ const back = rtl ? "ArrowRight" : "ArrowLeft";
138
+ if (key === forward) return Math.min(count - 1, index + 1);
139
+ if (key === back) return Math.max(0, index - 1);
140
+ if (key === "Home") return 0;
141
+ if (key === "End") return count - 1;
142
+ return undefined;
143
+ }
144
+
145
+ /** Whether the reader asks for reduced motion. */
146
+ export function prefersReducedMotion(): boolean {
147
+ return typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
148
+ }
149
+
150
+ const isRtl = (element: Element) => getComputedStyle(element).direction === "rtl";
151
+
152
+ /**
153
+ * Scrolls the track so `slide` stands at its start: smoothly, unless the
154
+ * reader asks for reduced motion. Says whether the track had to move.
155
+ */
156
+ export function scrollToSlide(track: HTMLElement, slide: HTMLElement, smooth = true): boolean {
157
+ const rtl = isRtl(track);
158
+ const box = track.getBoundingClientRect();
159
+ const rect = slide.getBoundingClientRect();
160
+ const reach = Math.max(0, track.scrollWidth - track.clientWidth);
161
+ const wanted = track.scrollLeft + (rtl ? rect.right - box.right : rect.left - box.left);
162
+ // Right to left, the track scrolls from 0 down to minus its reach.
163
+ const left = rtl ? Math.max(-reach, Math.min(0, wanted)) : Math.max(0, Math.min(reach, wanted));
164
+ if (Math.abs(left - track.scrollLeft) < 1) return false;
165
+ track.scrollTo({ left, behavior: smooth && !prefersReducedMotion() ? "smooth" : "instant" });
166
+ return true;
167
+ }
168
+
169
+ /**
170
+ * The slide in view: the one whose start is nearest the track's. At the far
171
+ * end, where the last slides cannot reach the start, the current slide stays
172
+ * while it is wholly in view, and the last slide is current otherwise.
173
+ */
174
+ export function nearestSlide(track: HTMLElement, slides: readonly HTMLElement[], current = 0): number {
175
+ if (!slides.length) return 0;
176
+ const rtl = isRtl(track);
177
+ const box = track.getBoundingClientRect();
178
+ const start = (rect: DOMRect) => (rtl ? box.right - rect.right : rect.left - box.left);
179
+ const reach = track.scrollWidth - track.clientWidth;
180
+ if (reach > 0 && Math.abs(track.scrollLeft) >= reach - 1) {
181
+ const rect = slides[current]?.getBoundingClientRect();
182
+ const inView = rect && start(rect) >= -1 && start(rect) + rect.width <= box.width + 1;
183
+ return inView ? current : slides.length - 1;
184
+ }
185
+ let nearest = 0;
186
+ let distance = Infinity;
187
+ slides.forEach((slide, index) => {
188
+ const away = Math.abs(start(slide.getBoundingClientRect()));
189
+ if (away < distance) { distance = away; nearest = index; }
190
+ });
191
+ return nearest;
192
+ }
193
+
194
+
195
+ /** Where a slide starts along the track, from the track's own start, in its scroll's terms. */
196
+ function startOf(track: HTMLElement, slide: HTMLElement): number {
197
+ const box = track.getBoundingClientRect();
198
+ const rect = slide.getBoundingClientRect();
199
+ return isRtl(track) ? track.scrollLeft + rect.right - box.right : track.scrollLeft + rect.left - box.left;
200
+ }
201
+
202
+ /**
203
+ * The room between an element and the window's edges, at its start and its
204
+ * end, for a strip that bleeds out to them. Measured against the document's
205
+ * width, so a scrollbar is never covered.
206
+ */
207
+ export function bleedRoom(element: HTMLElement): { before: number; after: number } {
208
+ const width = document.documentElement.clientWidth || window.innerWidth;
209
+ const rect = element.getBoundingClientRect();
210
+ const left = Math.max(0, rect.left);
211
+ const right = Math.max(0, width - rect.right);
212
+ return isRtl(element) ? { before: right, after: left } : { before: left, after: right };
213
+ }
214
+
215
+ /**
216
+ * Drives a strip: `block` carries the bleed's measures, `track` scrolls, and
217
+ * the slides (the children of `holder`, the track itself on a native page)
218
+ * are what it holds. The bleed's room is measured as the page's width
219
+ * changes; a loop holds the slides three times over, opened on the middle
220
+ * set and kept within it; autoplay steps a slide at a time while nobody is in
221
+ * the strip and it can be seen.
222
+ */
223
+ export function driveCarousel(block: HTMLElement, track: HTMLElement, holder: HTMLElement, options: CarouselDriveOptions = {}): CarouselDrive {
224
+ const stops: (() => void)[] = [];
225
+ const slides = () => [...holder.children].filter((child): child is HTMLElement => child instanceof HTMLElement && !child.hasAttribute("slot"));
226
+ const originals = () => slides().filter((slide) => !isCopy(slide));
227
+
228
+ const bleed = options.bleed ?? "none";
229
+ if (bleed !== "none") {
230
+ const measure = () => {
231
+ const { before, after } = bleedRoom(block);
232
+ block.style.setProperty("--ds-carousel-before", `${before}px`);
233
+ block.style.setProperty("--ds-carousel-after", `${after}px`);
234
+ };
235
+ measure();
236
+ const sized = typeof ResizeObserver === "function" ? new ResizeObserver(measure) : null;
237
+ sized?.observe(document.documentElement);
238
+ sized?.observe(block);
239
+ window.addEventListener("resize", measure);
240
+ stops.push(() => { sized?.disconnect(); window.removeEventListener("resize", measure); });
241
+ }
242
+
243
+ const count = originals().length;
244
+ const looping = !!options.loop && count > 1;
245
+ if (looping) {
246
+ const copies = () => originals().map((slide) => {
247
+ const copy = slide.cloneNode(true) as HTMLElement;
248
+ copy.setAttribute(COPY, "");
249
+ copy.setAttribute("aria-hidden", "true");
250
+ copy.inert = true;
251
+ copy.removeAttribute("id");
252
+ copy.querySelectorAll("[id]").forEach((node) => node.removeAttribute("id"));
253
+ options.onCopy?.(copy);
254
+ return copy;
255
+ });
256
+ const first = originals()[0];
257
+ const after = copies();
258
+ first.before(...copies());
259
+ holder.append(...after);
260
+ stops.push(() => slides().filter(isCopy).forEach((copy) => copy.remove()));
261
+ }
262
+ // A set's length: from a slide to the same slide in the next set.
263
+ const span = () => {
264
+ const all = slides();
265
+ return looping && all.length > count ? Math.abs(startOf(track, all[count]) - startOf(track, all[0])) : 0;
266
+ };
267
+ const direction = () => (isRtl(track) ? -1 : 1);
268
+ // Kept within the middle set: past either side, the strip moves a whole set at once, the same slides under the eye.
269
+ const within = () => {
270
+ const length = span();
271
+ if (!length) return;
272
+ const at = Math.abs(track.scrollLeft);
273
+ if (at < length * 0.5) track.scrollLeft += length * direction();
274
+ else if (at >= length * 1.5) track.scrollLeft -= length * direction();
275
+ };
276
+ if (looping) {
277
+ const place = () => {
278
+ if (!track.clientWidth) return false;
279
+ track.scrollLeft = span() * direction();
280
+ return true;
281
+ };
282
+ if (!place()) {
283
+ const sized = new ResizeObserver(() => { if (place()) sized.disconnect(); });
284
+ sized.observe(track);
285
+ stops.push(() => sized.disconnect());
286
+ }
287
+ track.addEventListener("scrollend", within);
288
+ stops.push(() => track.removeEventListener("scrollend", within));
289
+ }
290
+
291
+ /** The slide standing at the strip's start, or the nearest to it. */
292
+ const atStart = (): number => {
293
+ const all = slides();
294
+ const at = Math.abs(track.scrollLeft);
295
+ let nearest = 0;
296
+ let distance = Infinity;
297
+ all.forEach((slide, index) => {
298
+ const away = Math.abs(Math.abs(startOf(track, slide)) - at);
299
+ if (away < distance) { distance = away; nearest = index; }
300
+ });
301
+ return nearest;
302
+ };
303
+
304
+ const step = (towards: 1 | -1) => {
305
+ if (looping) within();
306
+ const all = slides();
307
+ const target = all[atStart() + towards];
308
+ if (target) scrollToSlide(track, target, true);
309
+ else if (!looping && towards === 1 && options.autoplay) scrollToSlide(track, all[0], true);
310
+ };
311
+
312
+ let paused = false;
313
+ const every = options.autoplay ?? 0;
314
+ if (every > 0 && !prefersReducedMotion()) {
315
+ let held = false;
316
+ let seen = typeof IntersectionObserver !== "function";
317
+ const hold = () => { held = true; };
318
+ const release = () => { held = false; };
319
+ const later = () => setTimeout(release, every);
320
+ const listeners: [string, EventListener, AddEventListenerOptions?][] = [
321
+ ["pointerenter", hold], ["pointerleave", release],
322
+ ["touchstart", hold, { passive: true }], ["touchend", later, { passive: true }],
323
+ ["focusin", hold], ["focusout", release],
324
+ ];
325
+ for (const [name, listener, options] of listeners) block.addEventListener(name, listener, options);
326
+ const watch = typeof IntersectionObserver === "function"
327
+ ? new IntersectionObserver(([entry]) => { seen = !!entry?.isIntersecting; }, { threshold: 0.3 })
328
+ : null;
329
+ watch?.observe(track);
330
+ const timer = setInterval(() => {
331
+ if (paused || held || !seen || document.hidden) return;
332
+ step(1);
333
+ }, every);
334
+ stops.push(() => {
335
+ clearInterval(timer);
336
+ watch?.disconnect();
337
+ for (const [name, listener] of listeners) block.removeEventListener(name, listener);
338
+ });
339
+ }
340
+
341
+ return {
342
+ step,
343
+ pause(next: boolean) { paused = next; },
344
+ get paused() { return paused; },
345
+ stop() { stops.splice(0).forEach((stop) => stop()); },
346
+ };
347
+ }
348
+
349
+ /** An icon button the script adds: the pause button of an autoplaying strip. */
350
+ function iconButton(className: string, icon: string): HTMLButtonElement {
351
+ const button = document.createElement("button");
352
+ button.type = "button";
353
+ button.className = `ds-button ds-button--icon ${className}`;
354
+ const mark = document.createElement("span");
355
+ mark.className = "ds-icon";
356
+ mark.setAttribute("aria-hidden", "true");
357
+ mark.dataset.icon = icon;
358
+ button.append(mark);
359
+ return button;
360
+ }
361
+
362
+ /** Points a native icon at its file in the icon folder beside the page's copy (`--ds-icon` from `data-icon`). */
363
+ function drawIcon(button: HTMLButtonElement, icon: string, base: string) {
364
+ const mark = button.querySelector<HTMLElement>(".ds-icon");
365
+ if (!mark) return;
366
+ mark.dataset.icon = icon;
367
+ if (base) mark.style.setProperty("--ds-icon", `url("${base}${icon}.svg")`);
368
+ }
369
+
370
+ /** What `startDots` is given: the number of dots, the current one and the end marker. */
371
+ export interface DotsOptions {
372
+ count: number;
373
+ current?: number;
374
+ /** Draw the last dot as an end marker. */
375
+ end?: boolean;
376
+ /** Called when a person picks a dot, by a click or a key. */
377
+ onSelect?: (index: number) => void;
378
+ }
379
+
380
+ /** A running set of native dots. */
381
+ export interface DotsHandle {
382
+ /** Draw `count` dots, `current` among them. */
383
+ set(count: number, current: number): void;
384
+ stop(): void;
385
+ }
386
+
387
+ /** Attributes the script wrote, so what the page wrote is left alone and the script's own follow the language. */
388
+ const written = new WeakMap<Element, Set<string>>();
389
+ function own(element: Element, name: string, value: string): void {
390
+ const mine = written.get(element) ?? new Set<string>();
391
+ if (element.hasAttribute(name) && !mine.has(name)) return;
392
+ mine.add(name);
393
+ written.set(element, mine);
394
+ if (element.getAttribute(name) !== value) element.setAttribute(name, value);
395
+ }
396
+ /** Whether the page names an element itself. */
397
+ const named = (element: Element) => element.hasAttribute("aria-labelledby") || (element.hasAttribute("aria-label") && !written.get(element)?.has("aria-label"));
398
+ /** Calls `relabel` whenever the language or its words change; returns the way to stop. */
399
+ function onLanguage(relabel: () => void): () => void {
400
+ if (typeof window === "undefined") return () => {};
401
+ for (const name of ["language-changed", "translations-loaded"]) window.addEventListener(name, relabel);
402
+ return () => { for (const name of ["language-changed", "translations-loaded"]) window.removeEventListener(name, relabel); };
403
+ }
404
+
405
+ /**
406
+ * Fills a `.ds-progress--dots` element with a button for each dot and keeps
407
+ * its states: a group labelled "Slides", each dot "Slide 2", the current one
408
+ * `aria-current` and the only one in the tab order, arrows, Home and End
409
+ * moving between them.
410
+ */
411
+ export function startDots(element: HTMLElement, options: DotsOptions): DotsHandle {
412
+ let count = Math.max(0, Math.floor(options.count));
413
+ let current = options.current ?? 0;
414
+ const draw = () => {
415
+ own(element, "role", "group");
416
+ if (!named(element)) own(element, "aria-label", carouselWord("Slides"));
417
+ const dots = [...element.querySelectorAll<HTMLButtonElement>(":scope > .ds-progress__dot")];
418
+ for (const extra of dots.splice(count)) extra.remove();
419
+ while (dots.length < count) {
420
+ const dot = document.createElement("button");
421
+ dot.type = "button";
422
+ dot.className = "ds-progress__dot";
423
+ element.append(dot);
424
+ dots.push(dot);
425
+ }
426
+ dots.forEach((dot, index) => {
427
+ const state = dotState(index, current, count, options.end);
428
+ dot.dataset.state = state;
429
+ if (!named(dot)) own(dot, "aria-label", carouselWord("Slide {index}", { index: index + 1 }));
430
+ if (state === "current") dot.setAttribute("aria-current", "true"); else dot.removeAttribute("aria-current");
431
+ dot.tabIndex = state === "current" ? 0 : -1;
432
+ });
433
+ };
434
+ const dotList = () => [...element.querySelectorAll<HTMLButtonElement>(":scope > .ds-progress__dot")];
435
+ const pick = (index: number, focus: boolean) => {
436
+ options.onSelect?.(index);
437
+ if (focus) dotList()[index]?.focus();
438
+ };
439
+ const click = (event: MouseEvent) => {
440
+ const index = dotList().indexOf((event.target as Element).closest?.(".ds-progress__dot") as HTMLButtonElement);
441
+ if (index >= 0) pick(index, false);
442
+ };
443
+ const keydown = (event: KeyboardEvent) => {
444
+ const dots = dotList();
445
+ const from = dots.indexOf(event.target as HTMLButtonElement);
446
+ if (from < 0) return;
447
+ const to = dotForKey(event.key, from, dots.length, isRtl(element));
448
+ if (to === undefined) return;
449
+ event.preventDefault();
450
+ pick(to, true);
451
+ };
452
+ element.addEventListener("click", click);
453
+ element.addEventListener("keydown", keydown);
454
+ const quiet = onLanguage(draw);
455
+ draw();
456
+ return {
457
+ set(nextCount, nextCurrent) { count = Math.max(0, Math.floor(nextCount)); current = nextCurrent; draw(); },
458
+ stop() { element.removeEventListener("click", click); element.removeEventListener("keydown", keydown); quiet(); },
459
+ };
460
+ }
461
+
462
+ /** A running native carousel. */
463
+ export interface CarouselHandle {
464
+ /** The slide in view. */
465
+ readonly current: number;
466
+ /** Go to a slide, as its dot does. */
467
+ goTo(index: number): void;
468
+ stop(): void;
469
+ }
470
+
471
+ /** Detail of a carousel's `change` event. */
472
+ export interface CarouselChangeDetail { index: number; previous: number }
473
+
474
+ const running = new WeakMap<HTMLElement, CarouselHandle>();
475
+
476
+ /** What `startCarousel` and `startCarousels` are told. */
477
+ export interface StartCarouselOptions {
478
+ /** Where the icons are, for the pause button the script adds (`/ds1/x-icon/`). */
479
+ icons?: string;
480
+ }
481
+
482
+ /** Starts one `.ds-carousel` block; starting it again returns the running one. */
483
+ export function startCarousel(element: HTMLElement, options: StartCarouselOptions = {}): CarouselHandle {
484
+ const existing = running.get(element);
485
+ if (existing) return existing;
486
+ const track = element.querySelector<HTMLElement>(".ds-carousel__track");
487
+ if (!track) throw new Error("A .ds-carousel needs a .ds-carousel__track");
488
+ // A strip's options: the bleed's room, a loop's copies and autoplay come from the drive.
489
+ const bleed = bleedOf(element.dataset.bleed);
490
+ const loop = element.dataset.loop !== undefined && element.dataset.loop !== "false";
491
+ const every = autoplayInterval(element.dataset.autoplay ?? null);
492
+ const drive = bleed !== "none" || loop || every > 0 ? driveCarousel(element, track, track, { bleed, loop, autoplay: every }) : undefined;
493
+ const previousButton = element.querySelector<HTMLButtonElement>(".ds-carousel__previous");
494
+ const nextButton = element.querySelector<HTMLButtonElement>(".ds-carousel__next");
495
+ let status = element.querySelector<HTMLElement>(".ds-carousel__status");
496
+ if (!status) {
497
+ status = document.createElement("span");
498
+ status.className = "ds-carousel__status";
499
+ element.append(status);
500
+ }
501
+ status.setAttribute("aria-live", "polite");
502
+ status.setAttribute("aria-atomic", "true");
503
+
504
+ const slides = () => [...track.children].filter((child): child is HTMLElement => child instanceof HTMLElement && !isCopy(child));
505
+ let current = 0;
506
+ let pending: number | undefined;
507
+ let settle: ReturnType<typeof setTimeout> | undefined;
508
+ let frame = 0;
509
+
510
+ /** The region, the slides and the buttons, named in the page's language unless the page names them. */
511
+ const label = () => {
512
+ own(element, "role", "region");
513
+ own(element, "aria-roledescription", carouselWord("Carousel"));
514
+ if (!named(element)) own(element, "aria-label", carouselWord("Carousel"));
515
+ const all = slides();
516
+ all.forEach((slide, index) => {
517
+ own(slide, "role", "group");
518
+ own(slide, "aria-roledescription", carouselWord("Slide"));
519
+ if (!named(slide)) own(slide, "aria-label", carouselWord("{index} of {count}", { index: index + 1, count: all.length }));
520
+ });
521
+ if (previousButton && !named(previousButton)) own(previousButton, "aria-label", carouselWord("Previous slide"));
522
+ if (nextButton && !named(nextButton)) own(nextButton, "aria-label", carouselWord("Next slide"));
523
+ };
524
+ // A looping strip has no place to point to, so it draws no dots.
525
+ const dotsElement = loop ? null : element.querySelector<HTMLElement>(".ds-progress--dots");
526
+ const dots = dotsElement ? startDots(dotsElement, { count: slides().length, end: dotsElement.hasAttribute("data-end"), onSelect: index => go(index, true) }) : undefined;
527
+
528
+ const show = (index: number, announce: boolean) => {
529
+ const count = slides().length;
530
+ const previous = current;
531
+ current = Math.max(0, Math.min(count - 1, index));
532
+ dots?.set(count, current);
533
+ if (previousButton) previousButton.disabled = !drive && current <= 0;
534
+ if (nextButton) nextButton.disabled = !drive && current >= count - 1;
535
+ if (announce && current !== previous) {
536
+ status!.textContent = carouselWord("{index} of {count}", { index: current + 1, count });
537
+ element.dispatchEvent(new CustomEvent<CarouselChangeDetail>("change", { bubbles: true, detail: { index: current, previous } }));
538
+ }
539
+ };
540
+ const go = (index: number, announce: boolean) => {
541
+ const all = slides();
542
+ const target = Math.max(0, Math.min(all.length - 1, index));
543
+ if (!all[target]) return;
544
+ if (scrollToSlide(track, all[target]!)) {
545
+ pending = target;
546
+ clearTimeout(settle);
547
+ settle = setTimeout(() => { pending = undefined; }, 600);
548
+ }
549
+ show(target, announce);
550
+ };
551
+ const scrolled = () => {
552
+ cancelAnimationFrame(frame);
553
+ if (loop) return;
554
+ frame = requestAnimationFrame(() => {
555
+ if (pending !== undefined) {
556
+ // A scroll asked for by a dot or a button: wait for it to stop before following the track again.
557
+ clearTimeout(settle);
558
+ settle = setTimeout(() => { pending = undefined; }, 150);
559
+ return;
560
+ }
561
+ show(nearestSlide(track, slides(), current), true);
562
+ });
563
+ };
564
+ const ended = () => { pending = undefined; };
565
+ const previous = () => (drive ? drive.step(-1) : go(current - 1, true));
566
+ const next = () => (drive ? drive.step(1) : go(current + 1, true));
567
+ // Autoplay always comes with its pause button, in the controls row the page wrote or one the script adds.
568
+ let pause: HTMLButtonElement | null = null;
569
+ const drawPause = () => {
570
+ if (!pause || !drive) return;
571
+ pause.setAttribute("aria-pressed", String(drive.paused));
572
+ pause.setAttribute("aria-label", carouselWord(drive.paused ? "Play" : "Pause"));
573
+ drawIcon(pause, drive.paused ? "play-alt" : "pause", options.icons ?? "");
574
+ };
575
+ if (drive && every > 0 && !prefersReducedMotion()) {
576
+ let controls = element.querySelector<HTMLElement>(":scope > .ds-carousel__controls");
577
+ if (!controls) {
578
+ controls = document.createElement("div");
579
+ controls.className = "ds-carousel__controls";
580
+ track.after(controls);
581
+ }
582
+ pause = controls.querySelector<HTMLButtonElement>(".ds-carousel__pause") ?? iconButton("ds-carousel__pause", "pause");
583
+ if (!pause.isConnected) controls.prepend(pause);
584
+ pause.addEventListener("click", () => { drive.pause(!drive.paused); drawPause(); });
585
+ drawPause();
586
+ }
587
+ const observer = typeof MutationObserver === "function" ? new MutationObserver(() => { label(); show(current, false); }) : undefined;
588
+
589
+ track.addEventListener("scroll", scrolled, { passive: true });
590
+ track.addEventListener("scrollend", ended);
591
+ previousButton?.addEventListener("click", previous);
592
+ nextButton?.addEventListener("click", next);
593
+ observer?.observe(track, { childList: true });
594
+ const quiet = onLanguage(() => { label(); drawPause(); });
595
+ label();
596
+ show(0, false);
597
+
598
+ const handle: CarouselHandle = {
599
+ get current() { return current; },
600
+ goTo: index => go(index, false),
601
+ stop() {
602
+ track.removeEventListener("scroll", scrolled);
603
+ track.removeEventListener("scrollend", ended);
604
+ previousButton?.removeEventListener("click", previous);
605
+ nextButton?.removeEventListener("click", next);
606
+ observer?.disconnect();
607
+ quiet();
608
+ dots?.stop();
609
+ drive?.stop();
610
+ cancelAnimationFrame(frame);
611
+ clearTimeout(settle);
612
+ running.delete(element);
613
+ },
614
+ };
615
+ running.set(element, handle);
616
+ return handle;
617
+ }
618
+
619
+ /** Starts every `.ds-carousel` inside `root` (the document by default); the returned function stops them. */
620
+ export function startCarousels(root: ParentNode = document, options: StartCarouselOptions = {}): () => void {
621
+ const handles = [...root.querySelectorAll<HTMLElement>(".ds-carousel")].map((element) => startCarousel(element, options));
622
+ return () => handles.forEach(handle => handle.stop());
623
+ }
@@ -0,0 +1,14 @@
1
+ /** Visibility is independent of architecture. Internal means built into an app,
2
+ * not secret: source and API comments remain available to implementers. */
3
+ export type ComponentVisibility = "public" | "internal";
4
+ export const COMPONENT_VISIBILITY: Readonly<Record<string, ComponentVisibility>> = {
5
+ "spacing-handle": "internal",
6
+ "loading": "internal",
7
+ "kbd": "internal",
8
+ };
9
+ export function componentVisibility(name: string): ComponentVisibility {
10
+ return COMPONENT_VISIBILITY[name.replace(/^ds-/, "")] ?? "public";
11
+ }
12
+ export function isPublicComponent(name: string): boolean {
13
+ return componentVisibility(name) === "public";
14
+ }