@telefonica/mistica 16.60.0 → 16.62.0-beta.1

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 (548) hide show
  1. package/css/mistica.css +1 -1
  2. package/dist/accordion.css-mistica.js +16 -16
  3. package/dist/align.css-mistica.js +2 -2
  4. package/dist/autocomplete.css-mistica.js +6 -6
  5. package/dist/avatar.css-mistica.js +3 -3
  6. package/dist/badge.css-mistica.js +7 -7
  7. package/dist/box.css-mistica.js +15 -15
  8. package/dist/boxed.css-mistica.js +31 -31
  9. package/dist/button-fixed-footer-layout.d.ts +2 -1
  10. package/dist/button-fixed-footer-layout.js +4 -3
  11. package/dist/button-group.css-mistica.js +10 -10
  12. package/dist/button-layout.css-mistica.js +21 -21
  13. package/dist/button.css-mistica.js +51 -51
  14. package/dist/callout.css-mistica.js +16 -16
  15. package/dist/card-internal.css-mistica.js +38 -38
  16. package/dist/carousel.css-mistica.js +18 -18
  17. package/dist/checkbox.css-mistica.js +21 -21
  18. package/dist/chip.css-mistica.js +30 -30
  19. package/dist/circle.css-mistica.js +2 -2
  20. package/dist/community/advanced-data-card.css-mistica.js +26 -26
  21. package/dist/community/blocks.css-mistica.js +3 -3
  22. package/dist/community/example-component.css-mistica.js +2 -2
  23. package/dist/counter.css-mistica.js +12 -12
  24. package/dist/cover-hero.css-mistica.js +16 -16
  25. package/dist/credit-card-number-field.css-mistica.js +6 -6
  26. package/dist/date-field.css-mistica.js +1 -1
  27. package/dist/date-time-picker.css-mistica.js +2 -2
  28. package/dist/dialog.css-mistica.js +15 -15
  29. package/dist/divider.css-mistica.js +5 -5
  30. package/dist/double-field.css-mistica.js +4 -4
  31. package/dist/drawer.css-mistica.js +15 -15
  32. package/dist/empty-state-card.css-mistica.js +4 -4
  33. package/dist/empty-state.css-mistica.js +14 -14
  34. package/dist/fade-in.css-mistica.js +1 -1
  35. package/dist/feedback.css-mistica.js +14 -14
  36. package/dist/file-upload.css-mistica.js +14 -14
  37. package/dist/fixed-footer-layout.css-mistica.js +12 -12
  38. package/dist/fixed-footer-layout.d.ts +6 -1
  39. package/dist/fixed-footer-layout.js +29 -28
  40. package/dist/form.css-mistica.js +2 -2
  41. package/dist/grid-layout.css-mistica.js +9 -9
  42. package/dist/grid.css-mistica.js +147 -147
  43. package/dist/header.css-mistica.js +5 -5
  44. package/dist/hero.css-mistica.js +11 -11
  45. package/dist/horizontal-scroll.css-mistica.js +3 -3
  46. package/dist/icon-button.css-mistica.js +66 -66
  47. package/dist/icons/icon-chevron.css-mistica.js +6 -6
  48. package/dist/icons/icon-error.css-mistica.js +3 -3
  49. package/dist/image.css-mistica.js +11 -11
  50. package/dist/image.js +8 -1
  51. package/dist/inline.css-mistica.js +16 -16
  52. package/dist/list.css-mistica.js +15 -15
  53. package/dist/loading-bar.css-mistica.js +5 -5
  54. package/dist/loading-screen.css-mistica.js +15 -15
  55. package/dist/logo.css-mistica.js +9 -9
  56. package/dist/menu.css-mistica.js +24 -24
  57. package/dist/mosaic.css-mistica.js +3 -3
  58. package/dist/navigation-bar.css-mistica.js +45 -45
  59. package/dist/navigation-breadcrumbs.css-mistica.js +5 -5
  60. package/dist/package-version.js +2 -2
  61. package/dist/pin-field.css-mistica.js +10 -10
  62. package/dist/popover.css-mistica.js +2 -2
  63. package/dist/progress-bar.css-mistica.js +12 -12
  64. package/dist/radio-button.css-mistica.js +33 -33
  65. package/dist/rating.css-mistica.js +12 -12
  66. package/dist/responsive-layout.css-mistica.js +20 -20
  67. package/dist/screen-reader-only.css-mistica.js +2 -2
  68. package/dist/select.css-mistica.js +29 -29
  69. package/dist/sheet-action-row.css-mistica.js +2 -2
  70. package/dist/sheet-common.css-mistica.js +16 -16
  71. package/dist/sheet-info.css-mistica.js +4 -4
  72. package/dist/skeletons.css-mistica.js +12 -12
  73. package/dist/skins/skin-contract.css-mistica.js +686 -686
  74. package/dist/skip-link.css-mistica.js +3 -3
  75. package/dist/slider.css-mistica.js +28 -28
  76. package/dist/snackbar.css-mistica.js +16 -16
  77. package/dist/spinner.css-mistica.js +5 -5
  78. package/dist/square.css-mistica.js +2 -2
  79. package/dist/stack.css-mistica.js +9 -9
  80. package/dist/stacking-group.css-mistica.js +2 -2
  81. package/dist/stepper.css-mistica.js +16 -16
  82. package/dist/switch-component.css-mistica.js +53 -53
  83. package/dist/table.css-mistica.js +24 -24
  84. package/dist/tabs.css-mistica.js +30 -30
  85. package/dist/tag.css-mistica.js +5 -5
  86. package/dist/text-field-base.css-mistica.js +30 -30
  87. package/dist/text-field-components.css-mistica.js +19 -19
  88. package/dist/text-link.css-mistica.js +10 -10
  89. package/dist/text.css-mistica.js +13 -13
  90. package/dist/theme-context.css-mistica.js +2 -2
  91. package/dist/timeline.css-mistica.js +18 -18
  92. package/dist/timer.css-mistica.js +13 -13
  93. package/dist/tooltip.css-mistica.js +12 -12
  94. package/dist/touchable.css-mistica.js +5 -5
  95. package/dist/utils/aspect-ratio-support.css-mistica.js +7 -7
  96. package/dist/video.css-mistica.js +2 -2
  97. package/dist/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +3 -3
  98. package/dist-es/accordion.css-mistica.js +7 -7
  99. package/dist-es/align.css-mistica.js +2 -2
  100. package/dist-es/autocomplete.css-mistica.js +2 -2
  101. package/dist-es/avatar.css-mistica.js +2 -2
  102. package/dist-es/badge.css-mistica.js +2 -2
  103. package/dist-es/box.css-mistica.js +15 -15
  104. package/dist-es/boxed.css-mistica.js +25 -25
  105. package/dist-es/button-fixed-footer-layout.js +12 -11
  106. package/dist-es/button-group.css-mistica.js +2 -2
  107. package/dist-es/button-layout.css-mistica.js +16 -16
  108. package/dist-es/button.css-mistica.js +38 -38
  109. package/dist-es/callout.css-mistica.js +12 -12
  110. package/dist-es/card-internal.css-mistica.js +20 -20
  111. package/dist-es/carousel.css-mistica.js +10 -10
  112. package/dist-es/checkbox.css-mistica.js +14 -14
  113. package/dist-es/chip.css-mistica.js +17 -17
  114. package/dist-es/circle.css-mistica.js +2 -2
  115. package/dist-es/community/advanced-data-card.css-mistica.js +7 -7
  116. package/dist-es/community/blocks.css-mistica.js +2 -2
  117. package/dist-es/community/example-component.css-mistica.js +2 -2
  118. package/dist-es/counter.css-mistica.js +2 -2
  119. package/dist-es/cover-hero.css-mistica.js +4 -4
  120. package/dist-es/credit-card-number-field.css-mistica.js +4 -4
  121. package/dist-es/date-field.css-mistica.js +1 -1
  122. package/dist-es/date-time-picker.css-mistica.js +2 -2
  123. package/dist-es/dialog.css-mistica.js +5 -5
  124. package/dist-es/divider.css-mistica.js +5 -5
  125. package/dist-es/double-field.css-mistica.js +4 -4
  126. package/dist-es/drawer.css-mistica.js +2 -2
  127. package/dist-es/empty-state-card.css-mistica.js +2 -2
  128. package/dist-es/empty-state.css-mistica.js +7 -7
  129. package/dist-es/fade-in.css-mistica.js +1 -1
  130. package/dist-es/feedback.css-mistica.js +2 -2
  131. package/dist-es/file-upload.css-mistica.js +8 -8
  132. package/dist-es/fixed-footer-layout.css-mistica.js +4 -4
  133. package/dist-es/fixed-footer-layout.js +57 -56
  134. package/dist-es/form.css-mistica.js +2 -2
  135. package/dist-es/grid-layout.css-mistica.js +4 -4
  136. package/dist-es/grid.css-mistica.js +127 -127
  137. package/dist-es/header.css-mistica.js +2 -2
  138. package/dist-es/hero.css-mistica.js +4 -4
  139. package/dist-es/horizontal-scroll.css-mistica.js +2 -2
  140. package/dist-es/icon-button.css-mistica.js +56 -56
  141. package/dist-es/icons/icon-chevron.css-mistica.js +4 -4
  142. package/dist-es/icons/icon-error.css-mistica.js +2 -2
  143. package/dist-es/image.css-mistica.js +4 -4
  144. package/dist-es/image.js +8 -1
  145. package/dist-es/inline.css-mistica.js +10 -10
  146. package/dist-es/list.css-mistica.js +2 -2
  147. package/dist-es/loading-bar.css-mistica.js +2 -2
  148. package/dist-es/loading-screen.css-mistica.js +5 -5
  149. package/dist-es/logo.css-mistica.js +7 -7
  150. package/dist-es/menu.css-mistica.js +15 -15
  151. package/dist-es/mosaic.css-mistica.js +2 -2
  152. package/dist-es/navigation-bar.css-mistica.js +20 -20
  153. package/dist-es/navigation-breadcrumbs.css-mistica.js +2 -2
  154. package/dist-es/package-version.js +2 -2
  155. package/dist-es/pin-field.css-mistica.js +2 -2
  156. package/dist-es/popover.css-mistica.js +2 -2
  157. package/dist-es/progress-bar.css-mistica.js +8 -8
  158. package/dist-es/radio-button.css-mistica.js +25 -25
  159. package/dist-es/rating.css-mistica.js +4 -4
  160. package/dist-es/responsive-layout.css-mistica.js +7 -7
  161. package/dist-es/screen-reader-only.css-mistica.js +2 -2
  162. package/dist-es/select.css-mistica.js +20 -20
  163. package/dist-es/sheet-action-row.css-mistica.js +2 -2
  164. package/dist-es/sheet-common.css-mistica.js +2 -2
  165. package/dist-es/sheet-info.css-mistica.js +2 -2
  166. package/dist-es/skeletons.css-mistica.js +8 -8
  167. package/dist-es/skins/skin-contract.css-mistica.js +686 -686
  168. package/dist-es/skip-link.css-mistica.js +2 -2
  169. package/dist-es/slider.css-mistica.js +20 -20
  170. package/dist-es/snackbar.css-mistica.js +5 -5
  171. package/dist-es/spinner.css-mistica.js +2 -2
  172. package/dist-es/square.css-mistica.js +2 -2
  173. package/dist-es/stack.css-mistica.js +7 -7
  174. package/dist-es/stacking-group.css-mistica.js +2 -2
  175. package/dist-es/stepper.css-mistica.js +4 -4
  176. package/dist-es/style.css +1 -1
  177. package/dist-es/switch-component.css-mistica.js +41 -41
  178. package/dist-es/table.css-mistica.js +11 -11
  179. package/dist-es/tabs.css-mistica.js +21 -21
  180. package/dist-es/tag.css-mistica.js +2 -2
  181. package/dist-es/text-field-base.css-mistica.js +17 -17
  182. package/dist-es/text-field-components.css-mistica.js +4 -4
  183. package/dist-es/text-link.css-mistica.js +9 -9
  184. package/dist-es/text.css-mistica.js +8 -8
  185. package/dist-es/theme-context.css-mistica.js +2 -2
  186. package/dist-es/timeline.css-mistica.js +11 -11
  187. package/dist-es/timer.css-mistica.js +7 -7
  188. package/dist-es/tooltip.css-mistica.js +3 -3
  189. package/dist-es/touchable.css-mistica.js +2 -2
  190. package/dist-es/utils/aspect-ratio-support.css-mistica.js +4 -4
  191. package/dist-es/video.css-mistica.js +2 -2
  192. package/dist-es/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +2 -2
  193. package/doc/components.md +19 -0
  194. package/doc/figma-mcp.md +136 -0
  195. package/doc/layout.md +20 -1
  196. package/doc/llms.md +18 -0
  197. package/doc/patterns.md +6 -17
  198. package/package.json +13 -1
  199. package/src/accordion.css.ts +121 -0
  200. package/src/accordion.tsx +366 -0
  201. package/src/align.css.ts +7 -0
  202. package/src/align.tsx +32 -0
  203. package/src/autocomplete.css.ts +62 -0
  204. package/src/autocomplete.tsx +239 -0
  205. package/src/avatar.css.ts +14 -0
  206. package/src/avatar.tsx +120 -0
  207. package/src/badge.css.ts +51 -0
  208. package/src/badge.tsx +79 -0
  209. package/src/box.css.ts +51 -0
  210. package/src/box.tsx +114 -0
  211. package/src/boxed.css.ts +132 -0
  212. package/src/boxed.tsx +153 -0
  213. package/src/button-fixed-footer-layout.tsx +65 -0
  214. package/src/button-group.css.ts +75 -0
  215. package/src/button-group.tsx +91 -0
  216. package/src/button-layout.css.ts +162 -0
  217. package/src/button-layout.tsx +91 -0
  218. package/src/button.css.ts +758 -0
  219. package/src/button.tsx +632 -0
  220. package/src/callout.css.ts +50 -0
  221. package/src/callout.tsx +147 -0
  222. package/src/card-cover.tsx +242 -0
  223. package/src/card-data.tsx +152 -0
  224. package/src/card-internal.css.ts +271 -0
  225. package/src/card-internal.tsx +1724 -0
  226. package/src/card-media.tsx +157 -0
  227. package/src/card-naked.tsx +63 -0
  228. package/src/carousel.css.ts +522 -0
  229. package/src/carousel.tsx +1300 -0
  230. package/src/checkbox.css.ts +94 -0
  231. package/src/checkbox.tsx +192 -0
  232. package/src/chip.css.ts +204 -0
  233. package/src/chip.tsx +191 -0
  234. package/src/circle.css.ts +14 -0
  235. package/src/circle.tsx +52 -0
  236. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-actions-button-and-link-footer-image-false-1-snap.png +0 -0
  237. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-actions-button-and-link-footer-image-true-1-snap.png +0 -0
  238. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-actions-button-footer-image-false-1-snap.png +0 -0
  239. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-actions-button-footer-image-true-1-snap.png +0 -0
  240. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-actions-link-footer-image-false-1-snap.png +0 -0
  241. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-actions-link-footer-image-true-1-snap.png +0 -0
  242. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-actions-none-footer-image-false-1-snap.png +0 -0
  243. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-actions-none-footer-image-true-1-snap.png +0 -0
  244. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-extras-0-1-snap.png +0 -0
  245. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-extras-1-1-snap.png +0 -0
  246. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-extras-3-1-snap.png +0 -0
  247. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-extras-3-no-divider-1-snap.png +0 -0
  248. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-inside-carousel-1-snap.png +0 -0
  249. package/src/community/__screenshot_tests__/__image_snapshots__/advanced-data-card-screenshot-test-tsx-advanced-data-card-without-stacking-group-with-top-actions-and-too-long-title-1-snap.png +0 -0
  250. package/src/community/__screenshot_tests__/__image_snapshots__/blocks-screenshot-test-tsx-blocks-highlighted-value-block-1-snap.png +0 -0
  251. package/src/community/__screenshot_tests__/__image_snapshots__/blocks-screenshot-test-tsx-blocks-information-block-1-snap.png +0 -0
  252. package/src/community/__screenshot_tests__/__image_snapshots__/blocks-screenshot-test-tsx-blocks-progress-block-1-snap.png +0 -0
  253. package/src/community/__screenshot_tests__/__image_snapshots__/blocks-screenshot-test-tsx-blocks-progress-block-2-snap.png +0 -0
  254. package/src/community/__screenshot_tests__/__image_snapshots__/blocks-screenshot-test-tsx-blocks-row-block-1-snap.png +0 -0
  255. package/src/community/__screenshot_tests__/__image_snapshots__/blocks-screenshot-test-tsx-blocks-simple-block-1-snap.png +0 -0
  256. package/src/community/__screenshot_tests__/__image_snapshots__/blocks-screenshot-test-tsx-blocks-value-block-1-snap.png +0 -0
  257. package/src/community/__screenshot_tests__/advanced-data-card-screenshot-test.tsx +84 -0
  258. package/src/community/__screenshot_tests__/blocks-screenshot-test.tsx +72 -0
  259. package/src/community/__stories__/advanced-data-card-carousel-story.tsx +66 -0
  260. package/src/community/__stories__/advanced-data-card-story.tsx +158 -0
  261. package/src/community/__stories__/blocks-story.tsx +272 -0
  262. package/src/community/__stories__/example-component-story.tsx +15 -0
  263. package/src/community/__stories__/index-story.tsx +154 -0
  264. package/src/community/__type_tests__/advanced-data-card-type-test.tsx +40 -0
  265. package/src/community/advanced-data-card.css.ts +271 -0
  266. package/src/community/advanced-data-card.tsx +431 -0
  267. package/src/community/blocks.css.ts +12 -0
  268. package/src/community/blocks.tsx +290 -0
  269. package/src/community/example-component.css.ts +7 -0
  270. package/src/community/example-component.tsx +17 -0
  271. package/src/community/index.tsx +10 -0
  272. package/src/counter.css.ts +150 -0
  273. package/src/counter.tsx +215 -0
  274. package/src/cover-hero-media.tsx +39 -0
  275. package/src/cover-hero.css.ts +133 -0
  276. package/src/cover-hero.tsx +262 -0
  277. package/src/credit-card-expiration-field.tsx +187 -0
  278. package/src/credit-card-fields.tsx +56 -0
  279. package/src/credit-card-number-field.css.ts +47 -0
  280. package/src/credit-card-number-field.tsx +245 -0
  281. package/src/cvv-field.tsx +169 -0
  282. package/src/date-field.css.ts +14 -0
  283. package/src/date-field.tsx +130 -0
  284. package/src/date-time-field.tsx +141 -0
  285. package/src/date-time-picker.css.ts +126 -0
  286. package/src/date-time-picker.tsx +188 -0
  287. package/src/decimal-field.tsx +160 -0
  288. package/src/desktop-container-type-context.tsx +15 -0
  289. package/src/dialog-context.tsx +81 -0
  290. package/src/dialog.css.ts +155 -0
  291. package/src/dialog.tsx +423 -0
  292. package/src/divider.css.ts +10 -0
  293. package/src/divider.tsx +11 -0
  294. package/src/double-field.css.ts +33 -0
  295. package/src/double-field.tsx +71 -0
  296. package/src/drawer.css.ts +123 -0
  297. package/src/drawer.tsx +304 -0
  298. package/src/email-field.tsx +76 -0
  299. package/src/empty-state-card.css.ts +40 -0
  300. package/src/empty-state-card.tsx +92 -0
  301. package/src/empty-state.css.ts +119 -0
  302. package/src/empty-state.tsx +141 -0
  303. package/src/fade-in.css.ts +12 -0
  304. package/src/fade-in.tsx +40 -0
  305. package/src/feedback.css.ts +119 -0
  306. package/src/feedback.tsx +432 -0
  307. package/src/file-upload.css.ts +156 -0
  308. package/src/file-upload.tsx +612 -0
  309. package/src/fixed-footer-layout.css.ts +96 -0
  310. package/src/fixed-footer-layout.tsx +227 -0
  311. package/src/fixed-to-top.tsx +21 -0
  312. package/src/focus-trap.tsx +17 -0
  313. package/src/form-context.tsx +198 -0
  314. package/src/form.css.ts +5 -0
  315. package/src/form.tsx +287 -0
  316. package/src/grid-layout.css.ts +68 -0
  317. package/src/grid-layout.tsx +201 -0
  318. package/src/grid.css.ts +203 -0
  319. package/src/grid.tsx +241 -0
  320. package/src/header.css.ts +30 -0
  321. package/src/header.tsx +319 -0
  322. package/src/hero.css.ts +71 -0
  323. package/src/hero.tsx +318 -0
  324. package/src/hooks.tsx +313 -0
  325. package/src/horizontal-scroll.css.ts +43 -0
  326. package/src/horizontal-scroll.tsx +18 -0
  327. package/src/iban-field.tsx +218 -0
  328. package/src/icon-button.css.ts +561 -0
  329. package/src/icon-button.tsx +221 -0
  330. package/src/icons/__stories__/mistica-icons-story.tsx +192 -0
  331. package/src/icons/icon-amex.tsx +40 -0
  332. package/src/icons/icon-chevron.css.ts +23 -0
  333. package/src/icons/icon-chevron.tsx +150 -0
  334. package/src/icons/icon-cvv-amex.tsx +31 -0
  335. package/src/icons/icon-cvv-visa-mc.tsx +31 -0
  336. package/src/icons/icon-error.css.ts +27 -0
  337. package/src/icons/icon-error.tsx +207 -0
  338. package/src/icons/icon-info.tsx +86 -0
  339. package/src/icons/icon-mastercard.tsx +36 -0
  340. package/src/icons/icon-success-vivo-new.tsx +51 -0
  341. package/src/icons/icon-success-vivo.tsx +36 -0
  342. package/src/icons/icon-success.tsx +211 -0
  343. package/src/icons/icon-visa.tsx +32 -0
  344. package/src/image.css.ts +48 -0
  345. package/src/image.tsx +352 -0
  346. package/src/index.tsx +2466 -0
  347. package/src/inline.css.ts +131 -0
  348. package/src/inline.tsx +135 -0
  349. package/src/integer-field.tsx +93 -0
  350. package/src/list.css.ts +281 -0
  351. package/src/list.tsx +963 -0
  352. package/src/loading-bar.css.ts +69 -0
  353. package/src/loading-bar.tsx +25 -0
  354. package/src/loading-screen.css.ts +114 -0
  355. package/src/loading-screen.tsx +376 -0
  356. package/src/logo-blau-shell.tsx +30 -0
  357. package/src/logo-blau.tsx +60 -0
  358. package/src/logo-common.tsx +29 -0
  359. package/src/logo-esimflag-shell.tsx +30 -0
  360. package/src/logo-esimflag.tsx +56 -0
  361. package/src/logo-movistar-new-shell.tsx +30 -0
  362. package/src/logo-movistar-new.tsx +85 -0
  363. package/src/logo-movistar-shell.tsx +30 -0
  364. package/src/logo-movistar.tsx +63 -0
  365. package/src/logo-o2-new-shell.tsx +26 -0
  366. package/src/logo-o2-new.tsx +27 -0
  367. package/src/logo-o2-shell.tsx +26 -0
  368. package/src/logo-o2.tsx +27 -0
  369. package/src/logo-telefonica-shell.tsx +30 -0
  370. package/src/logo-telefonica.tsx +95 -0
  371. package/src/logo-tu-shell.tsx +26 -0
  372. package/src/logo-tu.tsx +28 -0
  373. package/src/logo-vivo-shell.tsx +30 -0
  374. package/src/logo-vivo.tsx +53 -0
  375. package/src/logo.css.ts +33 -0
  376. package/src/logo.tsx +313 -0
  377. package/src/master-detail-layout.tsx +28 -0
  378. package/src/maybe-dismissable.css.ts +37 -0
  379. package/src/maybe-dismissable.tsx +58 -0
  380. package/src/media-queries.css.ts +67 -0
  381. package/src/menu.css.ts +132 -0
  382. package/src/menu.tsx +468 -0
  383. package/src/meter.tsx +516 -0
  384. package/src/modal-context-provider.tsx +45 -0
  385. package/src/month-field.tsx +124 -0
  386. package/src/mosaic.css.ts +73 -0
  387. package/src/mosaic.tsx +205 -0
  388. package/src/navigation-bar.css.ts +558 -0
  389. package/src/navigation-bar.tsx +1637 -0
  390. package/src/navigation-breadcrumbs.css.ts +22 -0
  391. package/src/navigation-breadcrumbs.tsx +69 -0
  392. package/src/negative-box.tsx +15 -0
  393. package/src/nestable-context.tsx +139 -0
  394. package/src/overlay.tsx +86 -0
  395. package/src/overscroll-color-context.tsx +141 -0
  396. package/src/package-version.tsx +2 -0
  397. package/src/password-field.tsx +126 -0
  398. package/src/phone-number-field-lite.tsx +265 -0
  399. package/src/phone-number-field.tsx +171 -0
  400. package/src/pin-field.css.ts +90 -0
  401. package/src/pin-field.tsx +346 -0
  402. package/src/placeholder.tsx +41 -0
  403. package/src/popover.css.ts +8 -0
  404. package/src/popover.tsx +85 -0
  405. package/src/portal.tsx +43 -0
  406. package/src/progress-bar.css.ts +61 -0
  407. package/src/progress-bar.tsx +174 -0
  408. package/src/radio-button.css.ts +174 -0
  409. package/src/radio-button.tsx +322 -0
  410. package/src/rating.css.ts +128 -0
  411. package/src/rating.tsx +351 -0
  412. package/src/responsive-layout.css.ts +162 -0
  413. package/src/responsive-layout.tsx +106 -0
  414. package/src/screen-reader-only.css.ts +27 -0
  415. package/src/screen-reader-only.tsx +33 -0
  416. package/src/screen-size-context-provider.tsx +96 -0
  417. package/src/screen-size-context.tsx +23 -0
  418. package/src/search-field.tsx +126 -0
  419. package/src/select.css.ts +226 -0
  420. package/src/select.tsx +513 -0
  421. package/src/sheet-action-row.css.ts +33 -0
  422. package/src/sheet-actions-list.tsx +113 -0
  423. package/src/sheet-actions.tsx +95 -0
  424. package/src/sheet-common.css.ts +254 -0
  425. package/src/sheet-common.tsx +402 -0
  426. package/src/sheet-info.css.ts +19 -0
  427. package/src/sheet-info.tsx +127 -0
  428. package/src/sheet-native.tsx +189 -0
  429. package/src/sheet-radio-list.tsx +118 -0
  430. package/src/sheet-root.tsx +127 -0
  431. package/src/sheet-types.tsx +94 -0
  432. package/src/sheet-web.tsx +140 -0
  433. package/src/skeleton-base.tsx +38 -0
  434. package/src/skeletons.css.ts +56 -0
  435. package/src/skeletons.tsx +133 -0
  436. package/src/skins/blau.tsx +724 -0
  437. package/src/skins/constants.tsx +10 -0
  438. package/src/skins/defaults.tsx +104 -0
  439. package/src/skins/esimflag.tsx +728 -0
  440. package/src/skins/movistar-new.tsx +735 -0
  441. package/src/skins/movistar.tsx +740 -0
  442. package/src/skins/o2-new.tsx +731 -0
  443. package/src/skins/o2.tsx +727 -0
  444. package/src/skins/skin-contract.css.ts +380 -0
  445. package/src/skins/telefonica.tsx +768 -0
  446. package/src/skins/tu.tsx +741 -0
  447. package/src/skins/types/colors.tsx +286 -0
  448. package/src/skins/types/index.tsx +153 -0
  449. package/src/skins/utils.tsx +66 -0
  450. package/src/skins/vivo-new.tsx +745 -0
  451. package/src/skins/vivo.tsx +720 -0
  452. package/src/skip-link.css.ts +34 -0
  453. package/src/skip-link.tsx +52 -0
  454. package/src/slider.css.ts +181 -0
  455. package/src/slider.tsx +384 -0
  456. package/src/snackbar-context.tsx +98 -0
  457. package/src/snackbar-native.ts +37 -0
  458. package/src/snackbar.css.ts +176 -0
  459. package/src/snackbar.tsx +258 -0
  460. package/src/spinner.css.ts +66 -0
  461. package/src/spinner.tsx +136 -0
  462. package/src/sprinkles.css.ts +83 -0
  463. package/src/square.css.ts +15 -0
  464. package/src/square.tsx +55 -0
  465. package/src/stack.css.ts +44 -0
  466. package/src/stack.tsx +79 -0
  467. package/src/stacking-group.css.ts +15 -0
  468. package/src/stacking-group.tsx +82 -0
  469. package/src/stepper.css.ts +233 -0
  470. package/src/stepper.tsx +156 -0
  471. package/src/switch-component.css.ts +181 -0
  472. package/src/switch-component.tsx +187 -0
  473. package/src/tab-focus.tsx +68 -0
  474. package/src/table-actions-header.tsx +21 -0
  475. package/src/table-cell-text.tsx +35 -0
  476. package/src/table.css.ts +297 -0
  477. package/src/table.tsx +398 -0
  478. package/src/tabs.css.ts +212 -0
  479. package/src/tabs.tsx +263 -0
  480. package/src/tag.css.ts +42 -0
  481. package/src/tag.tsx +161 -0
  482. package/src/test-utils/environment/setup-ssr.tsx +10 -0
  483. package/src/test-utils/fail-test-on-console-error.tsx +22 -0
  484. package/src/test-utils/index.tsx +341 -0
  485. package/src/test-utils/setup-ssr-test-env.tsx +13 -0
  486. package/src/test-utils/ssr.tsx +197 -0
  487. package/src/text-field-base.css.ts +416 -0
  488. package/src/text-field-base.tsx +628 -0
  489. package/src/text-field-components.css.ts +165 -0
  490. package/src/text-field-components.tsx +230 -0
  491. package/src/text-field.tsx +118 -0
  492. package/src/text-link.css.ts +83 -0
  493. package/src/text-link.tsx +85 -0
  494. package/src/text-tokens.tsx +708 -0
  495. package/src/text.css.ts +60 -0
  496. package/src/text.tsx +516 -0
  497. package/src/theme-context-provider.tsx +370 -0
  498. package/src/theme-context.css.ts +3 -0
  499. package/src/theme-context.tsx +8 -0
  500. package/src/theme-variant-context.tsx +51 -0
  501. package/src/theme.tsx +184 -0
  502. package/src/time-field.tsx +99 -0
  503. package/src/timeline.css.ts +135 -0
  504. package/src/timeline.tsx +250 -0
  505. package/src/timer.css.ts +99 -0
  506. package/src/timer.tsx +420 -0
  507. package/src/title.tsx +119 -0
  508. package/src/tooltip-context-provider.tsx +57 -0
  509. package/src/tooltip.css.ts +106 -0
  510. package/src/tooltip.tsx +649 -0
  511. package/src/touchable.css.ts +56 -0
  512. package/src/touchable.tsx +355 -0
  513. package/src/types/font-face.d.ts +47 -0
  514. package/src/types/libs.d.ts +3 -0
  515. package/src/utils/__tests__/analytics-test.tsx +35 -0
  516. package/src/utils/__tests__/browser-test.tsx +28 -0
  517. package/src/utils/__tests__/dom-test.tsx +23 -0
  518. package/src/utils/__tests__/helpers-test.tsx +166 -0
  519. package/src/utils/analytics.tsx +28 -0
  520. package/src/utils/animation.tsx +201 -0
  521. package/src/utils/aspect-ratio-support.css.ts +28 -0
  522. package/src/utils/aspect-ratio-support.tsx +141 -0
  523. package/src/utils/browser.tsx +9 -0
  524. package/src/utils/color.tsx +46 -0
  525. package/src/utils/common.tsx +27 -0
  526. package/src/utils/credit-card.tsx +46 -0
  527. package/src/utils/css.tsx +25 -0
  528. package/src/utils/document-visibility.tsx +52 -0
  529. package/src/utils/dom.tsx +155 -0
  530. package/src/utils/environment.tsx +6 -0
  531. package/src/utils/headings.tsx +18 -0
  532. package/src/utils/helpers.tsx +182 -0
  533. package/src/utils/keys.tsx +8 -0
  534. package/src/utils/locale.tsx +27 -0
  535. package/src/utils/platform.tsx +94 -0
  536. package/src/utils/region-code.tsx +1 -0
  537. package/src/utils/renders-element.tsx +6 -0
  538. package/src/utils/time.tsx +22 -0
  539. package/src/utils/types.tsx +19 -0
  540. package/src/utils/utility-types.tsx +8 -0
  541. package/src/video.css.ts +11 -0
  542. package/src/video.tsx +355 -0
  543. package/src/vivinho-loading-animation/in-lottie.json +402 -0
  544. package/src/vivinho-loading-animation/index.tsx +90 -0
  545. package/src/vivinho-loading-animation/out-lottie.json +575 -0
  546. package/src/vivinho-loading-animation/pulse-lottie.json +551 -0
  547. package/src/vivinho-loading-animation/vivinho-loading-animation.css.ts +15 -0
  548. package/src/vivinho-loading-animation/wave-lottie.json +2829 -0
package/doc/layout.md CHANGED
@@ -79,7 +79,8 @@ a horizontal `Stack`, and it covers the most common row-layout use cases you mig
79
79
  It supports:
80
80
 
81
81
  - horizontal distribution via `space={number}` or `space="between" | "around" | "evenly"`
82
- - vertical alignment of children via `alignItems="flex-start" | "flex-end" | "center" | "stretch" | "baseline"`
82
+ - vertical alignment of children via
83
+ `alignItems="flex-start" | "flex-end" | "center" | "stretch" | "baseline"`
83
84
  - wrapping via `wrap` and row spacing via `verticalSpace`
84
85
 
85
86
  :information_source: Check `Inline` in
@@ -139,6 +140,24 @@ Distribute items evenly. Items have equal space around them
139
140
 
140
141
  <img src="./images/layout/inline-evenly.svg" />
141
142
 
143
+ ### nesting
144
+
145
+ Nest `Inline` components to compose richer rows. A common pattern groups a leading icon and label on the left
146
+ with a value on the right via `space="between"`:
147
+
148
+ ```tsx
149
+ <Inline space="between" alignItems="center">
150
+ <Inline space={8} alignItems="center">
151
+ <IconTruckRegular size={24} color={skinVars.colors.neutralHigh} />
152
+ <Text2 regular>Envío:</Text2>
153
+ </Inline>
154
+ <Text2 regular>Mañana, gratis</Text2>
155
+ </Inline>
156
+ ```
157
+
158
+ The outer `Inline` distributes the two groups to opposite ends; the inner `Inline` keeps the icon tightly
159
+ grouped with its label at a fixed gap.
160
+
142
161
  ## Align
143
162
 
144
163
  Positions its children within a container using CSS grid alignment. Useful for centering content or placing it
package/doc/llms.md CHANGED
@@ -15,6 +15,17 @@ This file is the main entry point. All docs live at:
15
15
  If you cannot find a documentation file in `node_modules`, fetch the equivalent file from the GitHub
16
16
  repository at `https://github.com/Telefonica/mistica-web/blob/master/doc/<filename>`.
17
17
 
18
+ ## Source code
19
+
20
+ Source is available at `node_modules/@telefonica/mistica/src/` (fallback:
21
+ `https://github.com/Telefonica/mistica-web/tree/master/src`). Use `src/index.tsx` to map imports to files.
22
+
23
+ Read source only when you need to understand internal behavior that docs and types don't cover — for example
24
+ debugging layout/CSS issues (`*.css.ts` files), understanding event handling, or authoring a custom skin (read
25
+ a real skin in `src/skins/` to see canonical token patterns). Normally you shouldn't read source for
26
+ greenfield UI work — the docs already cover that, and reading source tends to pull toward low-level APIs when
27
+ a documented composite component would be simpler.
28
+
18
29
  ## Critical Rules
19
30
 
20
31
  1. **NEVER hardcode colors in app/component UI code.** Always use `skinVars.colors.*` design tokens from
@@ -43,6 +54,11 @@ repository at `https://github.com/Telefonica/mistica-web/blob/master/doc/<filena
43
54
  ```tsx
44
55
  <style>{`body { background-color: ${skinVars.colors.background}; }`}</style>
45
56
  ```
57
+ 11. **Re-apply these rules during debugging, reviewing, and fixing — not just while writing new code.**
58
+ TypeScript errors, visual mismatches, and "I just need this to work" pressure are not exceptions. If you
59
+ are about to add `style={{...}}` to a `<div>`, a hex literal, a manual `font-size`, a `margin: auto` /
60
+ `justify-content: center` workaround, or any other escape hatch inside Mistica code, stop and find the
61
+ primitive first — the rule you need is already above.
46
62
 
47
63
  ## Install
48
64
 
@@ -313,6 +329,7 @@ After reading the minimum set, read any further files that apply to your specifi
313
329
  | **Testing (read if you have to implement tests)** | `doc/testing.md` |
314
330
  | **Migrating from older versions** | `doc/migration-guide.md` |
315
331
  | **Optimizing bundle size with lottie** | `doc/lottie.md` |
332
+ | **Implementing a Figma design via Figma MCP** | `doc/figma-mcp.md` |
316
333
 
317
334
  ## Docs reference
318
335
 
@@ -336,3 +353,4 @@ After reading the minimum set, read any further files that apply to your specifi
336
353
  - [Testing](./testing.md): NODE_ENV, unit tests, acceptance tests, isRunningAcceptanceTest
337
354
  - [Lottie](./lottie.md): optimizing bundle size with lottie-web light build
338
355
  - [Migration guide](./migration-guide.md): cards ecosystem migration (v16), v12 to v13 migration
356
+ - [Figma MCP](./figma-mcp.md): mandatory translation rules when implementing from Figma MCP output.
package/doc/patterns.md CHANGED
@@ -2,19 +2,8 @@
2
2
 
3
3
  ## Critical rules
4
4
 
5
- 1. **NEVER hardcode colors in app/component UI code.** Always use `skinVars.colors.*` from
6
- `@telefonica/mistica`. For skins and theme-level customization, see [theme-config.md](./theme-config.md).
7
- 2. **NEVER use raw `<div>` for layout.** Use `Box`, `Stack`, `Inline`, `ResponsiveLayout`, `GridLayout`,
8
- `Grid`.
9
- 3. **NEVER set font sizes manually.** Use text components (`Text1`-`Text10`, `Title1`-`Title4`). If those
10
- don't cover your necessities you can set custom sizes with `Text` component.
11
- 4. **NEVER set border radius manually.** Use `skinVars.borderRadii.*` or components that handle it (`Boxed`,
12
- cards, etc.). For theme-level visual customization without a dedicated component prop, use a custom skin.
13
- 5. **Always wrap your app** with `ThemeContextProvider` and import `@telefonica/mistica/css/mistica.css`.
14
- 6. **Always namespace React hooks**: `React.useState`, `React.useEffect`, `React.useRef`, etc.
15
- 7. **Add `'use client';`** directive to client components when using Next.js app router.
16
- 8. **Set `font-family` and `body` background color.** See [llms.md](./llms.md) rules 9–10 and
17
- [fonts.md](./fonts.md) for the per-skin font table, `@font-face` setup, and the `GlobalStyles` pattern.
5
+ See [Critical Rules in `llms.md`](./llms.md#critical-rules) the single source of truth. These rules apply
6
+ throughout this document.
18
7
 
19
8
  ## Page layout composition
20
9
 
@@ -501,10 +490,10 @@ return (
501
490
  <ResponsiveLayout>
502
491
  <Stack space={24}>
503
492
  <Stepper currentIndex={currentStep} steps={['Personal', 'Address', 'Payment', 'Confirm']} />
504
- {currentStep === 0 && <PersonalInfoForm />}
505
- {currentStep === 1 && <AddressForm />}
506
- {currentStep === 2 && <PaymentForm />}
507
- {currentStep === 3 && <ConfirmationScreen />}
493
+ {currentStep === 0 && <PersonalInfoForm />}
494
+ {currentStep === 1 && <AddressForm />}
495
+ {currentStep === 2 && <PaymentForm />}
496
+ {currentStep === 3 && <ConfirmationScreen />}
508
497
  </Stack>
509
498
  </ResponsiveLayout>
510
499
  </Stack>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telefonica/mistica",
3
- "version": "16.60.0",
3
+ "version": "16.62.0-beta.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,6 +14,18 @@
14
14
  "dist-es/**",
15
15
  "css/**",
16
16
  "doc/**",
17
+ "src/**",
18
+ "!src/generated/**",
19
+ "!src/**/__tests__/**",
20
+ "!src/**/__acceptance_tests__/**",
21
+ "!src/**/__screenshot_tests__/**",
22
+ "!src/**/__type_tests__/**",
23
+ "!src/**/__stories__/**",
24
+ "!src/**/__private_stories__/**",
25
+ "!src/**/*-test.ts",
26
+ "!src/**/*-test.tsx",
27
+ "!src/**/*-story.ts",
28
+ "!src/**/*-story.tsx",
17
29
  "community.d.ts",
18
30
  "community.js"
19
31
  ],
@@ -0,0 +1,121 @@
1
+ import {style} from '@vanilla-extract/css';
2
+ import * as mq from './media-queries.css';
3
+ import {vars} from './skins/skin-contract.css';
4
+ import {sprinkles} from './sprinkles.css';
5
+
6
+ export const itemContent = sprinkles({
7
+ width: '100%',
8
+ border: 'none',
9
+ background: 'transparent',
10
+ display: 'block',
11
+ height: '100%',
12
+ padding: 0,
13
+ });
14
+
15
+ export const boxed = style({});
16
+
17
+ const boxedTouchableBorderRadiusStyles = {
18
+ [`${boxed} &:active`]: {
19
+ // needed because we can't use overflow: hidden on the boxed container for the focus ring to be visible
20
+ borderRadius: `calc(${vars.borderRadii.container} - 1px)`,
21
+ },
22
+ [`${boxed} &:hover`]: {
23
+ // needed because we can't use overflow: hidden on the boxed container for the focus ring to be visible
24
+ borderRadius: `calc(${vars.borderRadii.container} - 1px)`,
25
+ },
26
+ [`${boxed} &[aria-expanded="true"]`]: {
27
+ borderBottomLeftRadius: 0,
28
+ borderBottomRightRadius: 0,
29
+ },
30
+ };
31
+
32
+ export const touchableBackground = style({
33
+ transition: 'background-color 0.1s ease-in-out',
34
+ ':active': {
35
+ background: vars.colors.backgroundContainerPressed,
36
+ },
37
+ '@media': {
38
+ [mq.supportsHover]: {
39
+ ':hover': {
40
+ background: vars.colors.backgroundContainerHover,
41
+ },
42
+ ':active': {
43
+ background: vars.colors.backgroundContainerPressed,
44
+ },
45
+ },
46
+ [mq.touchableOnly]: {
47
+ transition: 'none',
48
+ },
49
+ },
50
+ selectors: boxedTouchableBorderRadiusStyles,
51
+ });
52
+
53
+ export const touchableBackgroundOverBrand = style({
54
+ transition: 'background-color 0.1s ease-in-out',
55
+ ':active': {
56
+ background: vars.colors.backgroundContainerBrandPressed,
57
+ },
58
+ '@media': {
59
+ [mq.supportsHover]: {
60
+ ':hover': {
61
+ background: vars.colors.backgroundContainerBrandHover,
62
+ },
63
+ ':active': {
64
+ background: vars.colors.backgroundContainerBrandPressed,
65
+ },
66
+ },
67
+ [mq.touchableOnly]: {
68
+ transition: 'none',
69
+ },
70
+ },
71
+ selectors: boxedTouchableBorderRadiusStyles,
72
+ });
73
+
74
+ export const rightContentContainer = style({
75
+ height: '100%',
76
+ });
77
+
78
+ export const chevronContainer = style({
79
+ height: '100%',
80
+ display: 'flex',
81
+ alignItems: 'center',
82
+ });
83
+
84
+ export const panelContainer = style({
85
+ display: 'grid',
86
+ });
87
+
88
+ export const panelTransitionClasses = {
89
+ enter: style({
90
+ gridTemplateRows: '0fr',
91
+ }),
92
+ enterActive: style({
93
+ gridTemplateRows: '1fr',
94
+ transition: 'grid-template-rows 0.4s',
95
+ '@media': {
96
+ ['(prefers-reduced-motion)']: {
97
+ transition: 'none',
98
+ },
99
+ },
100
+ }),
101
+ exit: style({
102
+ gridTemplateRows: '1fr',
103
+ }),
104
+ exitActive: style({
105
+ gridTemplateRows: '0fr',
106
+ transition: 'grid-template-rows 0.4s',
107
+ '@media': {
108
+ ['(prefers-reduced-motion)']: {
109
+ transition: 'none',
110
+ },
111
+ },
112
+ }),
113
+ };
114
+
115
+ export const panel = style({
116
+ overflow: 'hidden',
117
+ });
118
+
119
+ export const accordionItem = sprinkles({
120
+ width: '100%',
121
+ });
@@ -0,0 +1,366 @@
1
+ 'use client';
2
+ import * as React from 'react';
3
+ import {Content as HeaderContent} from './list';
4
+ import IconChevron from './icons/icon-chevron';
5
+ import Box from './box';
6
+ import * as styles from './accordion.css';
7
+ import Stack from './stack';
8
+ import {BaseTouchable} from './touchable';
9
+ import classNames from 'classnames';
10
+ import {vars as skinVars} from './skins/skin-contract.css';
11
+ import {getPrefixedDataAttributes} from './utils/dom';
12
+ import Divider from './divider';
13
+ import {InternalBoxed} from './boxed';
14
+ import {useThemeVariant} from './theme-variant-context';
15
+ import {CSSTransition} from 'react-transition-group';
16
+ import {isRunningAcceptanceTest} from './utils/platform';
17
+ import Inline from './inline';
18
+
19
+ import type {ExclusifyUnion} from './utils/utility-types';
20
+ import type {DataAttributes, TrackingEvent} from './utils/types';
21
+ import type {TouchableElement} from './touchable';
22
+
23
+ const ACCORDION_TRANSITION_DURATION_IN_MS = 400;
24
+
25
+ type AccordionContextType = {
26
+ index: ReadonlyArray<number>;
27
+ toggle: (item: number) => void;
28
+ };
29
+
30
+ const AccordionContext = React.createContext<AccordionContextType>({
31
+ index: [],
32
+ toggle: () => {},
33
+ });
34
+
35
+ const useAccordionContext = (): AccordionContextType => React.useContext(AccordionContext);
36
+
37
+ interface AccordionItemContentProps {
38
+ children?: void;
39
+ title: string;
40
+ titleAs?: string;
41
+ subtitle?: string;
42
+ asset?: React.ReactNode;
43
+ content: React.ReactNode;
44
+ dataAttributes?: DataAttributes;
45
+ trackingEvent?: TrackingEvent | ReadonlyArray<TrackingEvent>;
46
+ role?: string;
47
+ detail?: string;
48
+ right?: React.ReactNode;
49
+ 'aria-label'?: string;
50
+ 'aria-labelledby'?: string;
51
+ }
52
+
53
+ const useAccordionState = ({
54
+ value,
55
+ defaultValue,
56
+ onChange,
57
+ singleOpen,
58
+ }: {
59
+ value?: number | ReadonlyArray<number>;
60
+ defaultValue?: number | ReadonlyArray<number>;
61
+ onChange?: (item: number, value: boolean) => void;
62
+ singleOpen?: boolean;
63
+ }): [ReadonlyArray<number>, (value: number) => void] => {
64
+ const isControlledByParent = value !== undefined;
65
+
66
+ const getValueAsList = (value?: number | ReadonlyArray<number>) => {
67
+ return value === undefined ? [] : typeof value === 'number' ? [value] : value;
68
+ };
69
+
70
+ const [index, setIndex] = React.useState<ReadonlyArray<number>>(getValueAsList(defaultValue));
71
+
72
+ React.useEffect(() => {
73
+ if (index.length > 1 && singleOpen) {
74
+ const newIndex = [...index];
75
+ newIndex.splice(1);
76
+ setIndex(newIndex);
77
+ }
78
+ }, [singleOpen, index]);
79
+
80
+ const updateIndexOnToggle = (item: number, index?: ReadonlyArray<number>) => {
81
+ if (!index) {
82
+ return [item];
83
+ }
84
+
85
+ const valueIndex = index.indexOf(item);
86
+ let newIndex = [...index];
87
+ if (valueIndex === -1) {
88
+ if (singleOpen) {
89
+ newIndex = [item];
90
+ } else {
91
+ newIndex.push(item);
92
+ }
93
+ } else {
94
+ newIndex.splice(valueIndex, 1);
95
+ }
96
+
97
+ return newIndex;
98
+ };
99
+
100
+ const toggle = (item: number) => {
101
+ if (!isControlledByParent) {
102
+ setIndex(updateIndexOnToggle(item, index));
103
+ }
104
+ if (onChange) {
105
+ const currentItemValue = (isControlledByParent ? getValueAsList(value) : index).includes(item);
106
+ onChange(item, !currentItemValue);
107
+ }
108
+ };
109
+
110
+ if (isControlledByParent) {
111
+ return [getValueAsList(value), toggle];
112
+ }
113
+
114
+ return [index, toggle];
115
+ };
116
+
117
+ const getAccordionItemIndex = (element: Element | null) => {
118
+ const accordionAncestor = element?.closest('[data-accordion]');
119
+ if (!accordionAncestor) return undefined;
120
+
121
+ return Array.from(accordionAncestor.querySelectorAll('[data-accordion-item]'))
122
+ .filter((e) => e.closest('[data-accordion]') === accordionAncestor)
123
+ .findIndex((e) => e === element);
124
+ };
125
+
126
+ const getAssetText = (asset: React.ReactNode): string => {
127
+ if (!React.isValidElement(asset)) return '';
128
+
129
+ const props = asset.props as {alt?: unknown; 'aria-label'?: unknown};
130
+
131
+ if (typeof props.alt === 'string' && props.alt.trim()) {
132
+ return props.alt.trim();
133
+ }
134
+
135
+ if (typeof props['aria-label'] === 'string' && props['aria-label'].trim()) {
136
+ return props['aria-label'].trim();
137
+ }
138
+
139
+ return '';
140
+ };
141
+
142
+ const AccordionItemContent = React.forwardRef<TouchableElement, AccordionItemContentProps>(
143
+ (
144
+ {
145
+ content,
146
+ dataAttributes,
147
+ trackingEvent,
148
+ right,
149
+ 'aria-label': ariaLabel,
150
+ 'aria-labelledby': ariaLabelledby,
151
+ ...props
152
+ },
153
+ ref
154
+ ) => {
155
+ const panelContainerRef = React.useRef<HTMLDivElement | null>(null);
156
+ const itemRef = React.useRef<HTMLDivElement | null>(null);
157
+ const {index, toggle} = useAccordionContext();
158
+ const variant = useThemeVariant();
159
+ const labelId = React.useId();
160
+ const panelId = React.useId();
161
+
162
+ const assetText = getAssetText(props.asset);
163
+
164
+ const computedAriaLabel = ariaLabel ?? [props.title, assetText].filter(Boolean).join(' ');
165
+
166
+ const [itemIndex, setItemIndex] = React.useState<number>();
167
+ const isOpen = itemIndex !== undefined && index?.includes(itemIndex);
168
+
169
+ React.useEffect(() => {
170
+ setItemIndex(getAccordionItemIndex(itemRef.current));
171
+ }, []);
172
+
173
+ const iconColor = {
174
+ default: isOpen ? skinVars.colors.chevronIndicator : skinVars.colors.chevronIndicator,
175
+ alternative: isOpen ? skinVars.colors.chevronIndicator : skinVars.colors.chevronIndicator,
176
+ brand: skinVars.colors.textSecondaryBrand,
177
+ media: skinVars.colors.textSecondaryBrand,
178
+ negative: skinVars.colors.textSecondaryNegative,
179
+ }[variant];
180
+
181
+ return (
182
+ <div ref={itemRef} {...getPrefixedDataAttributes({...dataAttributes, 'accordion-item': true})}>
183
+ <BaseTouchable
184
+ ref={ref}
185
+ className={classNames(
186
+ styles.itemContent,
187
+ variant === 'brand' || variant === 'media' || variant === 'negative'
188
+ ? styles.touchableBackgroundOverBrand
189
+ : styles.touchableBackground
190
+ )}
191
+ onPress={() => {
192
+ if (itemIndex !== undefined) toggle(itemIndex);
193
+ }}
194
+ trackingEvent={trackingEvent}
195
+ aria-expanded={isOpen}
196
+ aria-controls={panelId}
197
+ aria-label={computedAriaLabel}
198
+ aria-labelledby={ariaLabelledby}
199
+ >
200
+ <Box paddingX={16}>
201
+ <HeaderContent
202
+ labelId={labelId}
203
+ {...props}
204
+ right={({centerY}) => (
205
+ <Inline
206
+ space={4}
207
+ alignItems={centerY ? 'center' : undefined}
208
+ className={styles.rightContentContainer}
209
+ >
210
+ {right}
211
+ <div className={styles.chevronContainer}>
212
+ <IconChevron
213
+ size={20}
214
+ transitionDuration={ACCORDION_TRANSITION_DURATION_IN_MS}
215
+ direction={isOpen ? 'up' : 'down'}
216
+ color={iconColor}
217
+ />
218
+ </div>
219
+ </Inline>
220
+ )}
221
+ />
222
+ </Box>
223
+ </BaseTouchable>
224
+ <CSSTransition
225
+ in={isOpen}
226
+ timeout={isRunningAcceptanceTest() ? 0 : ACCORDION_TRANSITION_DURATION_IN_MS}
227
+ nodeRef={panelContainerRef}
228
+ classNames={styles.panelTransitionClasses}
229
+ mountOnEnter
230
+ unmountOnExit
231
+ >
232
+ <div className={styles.panelContainer} ref={panelContainerRef}>
233
+ <div className={styles.panel} role="region" aria-labelledby={labelId} id={panelId}>
234
+ <Box paddingX={16} paddingBottom={16}>
235
+ {content}
236
+ </Box>
237
+ </div>
238
+ </div>
239
+ </CSSTransition>
240
+ </div>
241
+ );
242
+ }
243
+ );
244
+
245
+ export const AccordionItem = React.forwardRef<TouchableElement, AccordionItemContentProps>(
246
+ ({dataAttributes, role, ...props}, ref) => (
247
+ <div role={role} className={styles.accordionItem}>
248
+ <AccordionItemContent
249
+ {...props}
250
+ ref={ref}
251
+ dataAttributes={{'component-name': 'AccordionItem', ...dataAttributes}}
252
+ />
253
+ </div>
254
+ )
255
+ );
256
+
257
+ type AccordionBaseProps = {
258
+ children: React.ReactNode;
259
+ dataAttributes?: DataAttributes;
260
+ onChange?: (index: number, value: boolean) => void;
261
+ role?: string;
262
+ };
263
+
264
+ type SingleOpenProps = {
265
+ singleOpen: true;
266
+ index?: number;
267
+ defaultIndex?: number;
268
+ };
269
+
270
+ type MultipleOpenProps = {
271
+ singleOpen?: false;
272
+ index?: number | ReadonlyArray<number>;
273
+ defaultIndex?: number | ReadonlyArray<number>;
274
+ };
275
+
276
+ type AccordionProps = AccordionBaseProps & ExclusifyUnion<SingleOpenProps | MultipleOpenProps>;
277
+
278
+ export const Accordion = ({
279
+ children,
280
+ dataAttributes,
281
+ index,
282
+ defaultIndex,
283
+ onChange,
284
+ singleOpen,
285
+ role,
286
+ }: AccordionProps): JSX.Element => {
287
+ const [indexList, toggle] = useAccordionState({
288
+ value: index,
289
+ defaultValue: defaultIndex,
290
+ onChange,
291
+ singleOpen,
292
+ });
293
+ const childrenContent = React.Children.toArray(children).filter(Boolean);
294
+ const lastIndex = childrenContent.length - 1;
295
+
296
+ return (
297
+ <AccordionContext.Provider value={{index: indexList, toggle}}>
298
+ <div
299
+ role={role}
300
+ {...getPrefixedDataAttributes({...dataAttributes, accordion: true}, 'Accordion')}
301
+ >
302
+ {childrenContent.map((child, index) => (
303
+ <React.Fragment key={index}>
304
+ {child}
305
+ {index < lastIndex && (
306
+ <Box paddingX={16}>
307
+ <Divider />
308
+ </Box>
309
+ )}
310
+ </React.Fragment>
311
+ ))}
312
+ </div>
313
+ </AccordionContext.Provider>
314
+ );
315
+ };
316
+
317
+ interface BoxedAccordionItemProps extends AccordionItemContentProps {
318
+ /**
319
+ * @deprecated Use `variant="brand"` instead.
320
+ */
321
+ isInverse?: boolean;
322
+ variant?: 'default' | 'brand';
323
+ }
324
+
325
+ export const BoxedAccordionItem = React.forwardRef<HTMLDivElement, BoxedAccordionItemProps>(
326
+ ({dataAttributes, isInverse, variant, ...props}, ref) => (
327
+ <InternalBoxed
328
+ overflow="visible"
329
+ className={styles.boxed}
330
+ variant={variant ?? (isInverse ? 'brand' : 'default')}
331
+ ref={ref}
332
+ dataAttributes={{'component-name': 'BoxedAccordionItem', ...dataAttributes}}
333
+ >
334
+ <AccordionItemContent {...props} />
335
+ </InternalBoxed>
336
+ )
337
+ );
338
+
339
+ export const BoxedAccordion = ({
340
+ children,
341
+ dataAttributes,
342
+ index,
343
+ defaultIndex,
344
+ onChange,
345
+ singleOpen,
346
+ role,
347
+ }: AccordionProps): JSX.Element => {
348
+ const [indexList, toggle] = useAccordionState({
349
+ value: index,
350
+ defaultValue: defaultIndex,
351
+ onChange,
352
+ singleOpen,
353
+ });
354
+
355
+ return (
356
+ <AccordionContext.Provider value={{index: indexList, toggle}}>
357
+ <Stack
358
+ space={16}
359
+ role={role}
360
+ dataAttributes={{'component-name': 'BoxedAccordion', accordion: true, ...dataAttributes}}
361
+ >
362
+ {children}
363
+ </Stack>
364
+ </AccordionContext.Provider>
365
+ );
366
+ };
@@ -0,0 +1,7 @@
1
+ import {style} from '@vanilla-extract/css';
2
+
3
+ export const container = style({
4
+ display: 'grid',
5
+ width: '100%',
6
+ height: '100%',
7
+ });
package/src/align.tsx ADDED
@@ -0,0 +1,32 @@
1
+ import * as React from 'react';
2
+ import {getPrefixedDataAttributes} from './utils/dom';
3
+ import * as styles from './align.css';
4
+
5
+ import type {DataAttributes} from './utils/types';
6
+
7
+ type Props = {
8
+ x?: 'start' | 'center' | 'end';
9
+ y?: 'start' | 'center' | 'end';
10
+ width?: number | string;
11
+ height?: number | string;
12
+ children?: React.ReactNode;
13
+ dataAttributes?: DataAttributes;
14
+ };
15
+
16
+ const Align = ({x = 'start', y = 'start', width, height, children, dataAttributes}: Props): JSX.Element => {
17
+ return (
18
+ <div
19
+ {...getPrefixedDataAttributes(dataAttributes, 'Align')}
20
+ className={styles.container}
21
+ style={{
22
+ placeItems: `${y} ${x}`,
23
+ ...(width !== undefined ? {width} : {}),
24
+ ...(height !== undefined ? {height} : {}),
25
+ }}
26
+ >
27
+ {children}
28
+ </div>
29
+ );
30
+ };
31
+
32
+ export default Align;