@telefonica/mistica 17.3.0 → 17.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (609) hide show
  1. package/css/blau.css +29 -16
  2. package/css/esimflag.css +40 -18
  3. package/css/mistica-common.css +5 -0
  4. package/css/mistica.css +1 -1
  5. package/css/movistar.css +34 -18
  6. package/css/o2.css +31 -18
  7. package/css/telefonica.css +43 -18
  8. package/css/vivo-evolution.css +71 -20
  9. package/css/vivo.css +31 -18
  10. package/dist/accordion.css-mistica.js +10 -10
  11. package/dist/align.css-mistica.js +1 -1
  12. package/dist/autocomplete.css-mistica.js +4 -4
  13. package/dist/avatar.css-mistica.js +1 -1
  14. package/dist/badge.css-mistica.js +1 -1
  15. package/dist/box.css-mistica.js +13 -13
  16. package/dist/boxed.css-mistica.js +24 -24
  17. package/dist/boxed.d.ts +9 -0
  18. package/dist/boxed.js +18 -15
  19. package/dist/button-group.css-mistica.js +1 -1
  20. package/dist/button-layout.css-mistica.js +19 -19
  21. package/dist/button.css-mistica.js +51 -51
  22. package/dist/callout.css-mistica.js +13 -13
  23. package/dist/card-internal.css-mistica.js +22 -22
  24. package/dist/carousel.css-mistica.js +30 -30
  25. package/dist/checkbox.css-mistica.js +15 -15
  26. package/dist/chip.css-mistica.js +18 -18
  27. package/dist/circle.css-mistica.js +2 -2
  28. package/dist/community/advanced-data-card.css-mistica.js +19 -19
  29. package/dist/community/ai-card.css-mistica.js +11 -11
  30. package/dist/community/blocks.css-mistica.js +1 -1
  31. package/dist/community/cyber/example-component.css-mistica.js +1 -1
  32. package/dist/community/example-component.css-mistica.js +1 -1
  33. package/dist/community/skins/cyber-skin.js +19 -17
  34. package/dist/counter.css-mistica.js +6 -6
  35. package/dist/cover-hero.css-mistica.js +7 -7
  36. package/dist/credit-card-number-field.css-mistica.js +3 -3
  37. package/dist/date-field.css-mistica.js +1 -1
  38. package/dist/date-time-picker.css-mistica.js +1 -1
  39. package/dist/dialog.css-mistica.js +10 -10
  40. package/dist/divider.css-mistica.js +5 -5
  41. package/dist/double-field.css-mistica.js +2 -2
  42. package/dist/drawer.css-mistica.js +4 -4
  43. package/dist/empty-state-card.css-mistica.js +1 -1
  44. package/dist/empty-state.css-mistica.js +8 -8
  45. package/dist/fade-in.css-mistica.js +1 -1
  46. package/dist/fade-out.css-mistica.js +11 -0
  47. package/dist/fade-out.css.d.ts +1 -0
  48. package/dist/fade-out.d.ts +11 -0
  49. package/dist/fade-out.js +88 -0
  50. package/dist/feedback.css-mistica.js +5 -5
  51. package/dist/file-upload.css-mistica.js +10 -10
  52. package/dist/fixed-footer-layout.css-mistica.js +6 -6
  53. package/dist/form.css-mistica.js +1 -1
  54. package/dist/generated/mistica-icons/icon-antenna-filled.js +40 -12
  55. package/dist/generated/mistica-icons/icon-antenna-light.js +37 -17
  56. package/dist/generated/mistica-icons/icon-antenna-regular.js +42 -14
  57. package/dist/generated/mistica-icons/icon-arrow-up-down-filled.js +26 -16
  58. package/dist/generated/mistica-icons/icon-arrow-up-down-light.js +22 -12
  59. package/dist/generated/mistica-icons/icon-arrow-up-down-regular.js +30 -20
  60. package/dist/generated/mistica-icons/icon-arrows-left-and-right-filled.js +26 -16
  61. package/dist/generated/mistica-icons/icon-arrows-left-and-right-light.js +24 -14
  62. package/dist/generated/mistica-icons/icon-arrows-left-and-right-regular.js +26 -16
  63. package/dist/generated/mistica-icons/icon-authentication-success-filled.js +31 -11
  64. package/dist/generated/mistica-icons/icon-authentication-success-light.js +33 -17
  65. package/dist/generated/mistica-icons/icon-authentication-success-regular.js +29 -13
  66. package/dist/generated/mistica-icons/icon-blog-filled.js +36 -16
  67. package/dist/generated/mistica-icons/icon-blog-light.js +34 -14
  68. package/dist/generated/mistica-icons/icon-blog-regular.js +32 -16
  69. package/dist/generated/mistica-icons/icon-book-filled.js +19 -9
  70. package/dist/generated/mistica-icons/icon-book-light.js +25 -15
  71. package/dist/generated/mistica-icons/icon-book-regular.js +16 -6
  72. package/dist/generated/mistica-icons/icon-box-filled.js +35 -19
  73. package/dist/generated/mistica-icons/icon-box-light.js +28 -18
  74. package/dist/generated/mistica-icons/icon-box-regular.js +26 -16
  75. package/dist/generated/mistica-icons/icon-box-star-filled.js +37 -17
  76. package/dist/generated/mistica-icons/icon-box-star-light.js +22 -6
  77. package/dist/generated/mistica-icons/icon-box-star-regular.js +30 -14
  78. package/dist/generated/mistica-icons/icon-briefcase-filled.js +28 -12
  79. package/dist/generated/mistica-icons/icon-briefcase-light.js +21 -11
  80. package/dist/generated/mistica-icons/icon-briefcase-regular.js +29 -19
  81. package/dist/generated/mistica-icons/icon-calendar-event-filled.js +23 -12
  82. package/dist/generated/mistica-icons/icon-calendar-event-light.js +28 -11
  83. package/dist/generated/mistica-icons/icon-calendar-event-regular.js +30 -13
  84. package/dist/generated/mistica-icons/icon-calendar-filled.js +32 -22
  85. package/dist/generated/mistica-icons/icon-calendar-light.js +39 -23
  86. package/dist/generated/mistica-icons/icon-calendar-month-filled.js +23 -12
  87. package/dist/generated/mistica-icons/icon-calendar-month-light.js +30 -13
  88. package/dist/generated/mistica-icons/icon-calendar-month-regular.js +30 -13
  89. package/dist/generated/mistica-icons/icon-calendar-regular.js +33 -17
  90. package/dist/generated/mistica-icons/icon-car-filled.js +25 -9
  91. package/dist/generated/mistica-icons/icon-car-light.js +24 -14
  92. package/dist/generated/mistica-icons/icon-car-regular.js +24 -14
  93. package/dist/generated/mistica-icons/icon-care-briefcase-filled.js +23 -12
  94. package/dist/generated/mistica-icons/icon-care-briefcase-light.js +25 -14
  95. package/dist/generated/mistica-icons/icon-care-briefcase-regular.js +18 -8
  96. package/dist/generated/mistica-icons/icon-care-filled.js +25 -15
  97. package/dist/generated/mistica-icons/icon-care-home-filled.js +24 -13
  98. package/dist/generated/mistica-icons/icon-care-home-light.js +24 -13
  99. package/dist/generated/mistica-icons/icon-care-home-regular.js +26 -16
  100. package/dist/generated/mistica-icons/icon-care-laptop-filled.js +22 -11
  101. package/dist/generated/mistica-icons/icon-care-laptop-light.js +24 -13
  102. package/dist/generated/mistica-icons/icon-care-laptop-regular.js +28 -18
  103. package/dist/generated/mistica-icons/icon-care-light.js +22 -12
  104. package/dist/generated/mistica-icons/icon-care-mobile-filled.js +22 -11
  105. package/dist/generated/mistica-icons/icon-care-mobile-light.js +29 -12
  106. package/dist/generated/mistica-icons/icon-care-mobile-regular.js +33 -17
  107. package/dist/generated/mistica-icons/icon-care-regular.js +23 -13
  108. package/dist/generated/mistica-icons/icon-care-shield-filled.js +24 -14
  109. package/dist/generated/mistica-icons/icon-care-shield-light.js +23 -13
  110. package/dist/generated/mistica-icons/icon-care-shield-regular.js +26 -16
  111. package/dist/generated/mistica-icons/icon-change-plan-filled.js +36 -16
  112. package/dist/generated/mistica-icons/icon-change-plan-light.js +38 -18
  113. package/dist/generated/mistica-icons/icon-change-plan-regular.js +30 -14
  114. package/dist/generated/mistica-icons/icon-chip-device-filled.js +32 -16
  115. package/dist/generated/mistica-icons/icon-chip-device-light.js +33 -17
  116. package/dist/generated/mistica-icons/icon-chip-device-regular.js +36 -20
  117. package/dist/generated/mistica-icons/icon-chip-sim-card-filled.js +25 -15
  118. package/dist/generated/mistica-icons/icon-chip-sim-card-light.js +36 -20
  119. package/dist/generated/mistica-icons/icon-chip-sim-card-regular.js +42 -26
  120. package/dist/generated/mistica-icons/icon-credit-card-filled.js +20 -10
  121. package/dist/generated/mistica-icons/icon-credit-card-light.js +18 -8
  122. package/dist/generated/mistica-icons/icon-credit-card-regular.js +23 -13
  123. package/dist/generated/mistica-icons/icon-document-information-filled.d.ts +3 -0
  124. package/dist/generated/mistica-icons/icon-document-information-light.d.ts +3 -0
  125. package/dist/generated/mistica-icons/icon-document-information-regular.d.ts +3 -0
  126. package/dist/generated/mistica-icons/icon-document-other-filled.js +25 -9
  127. package/dist/generated/mistica-icons/icon-document-other-light.js +33 -17
  128. package/dist/generated/mistica-icons/icon-document-other-regular.js +25 -9
  129. package/dist/generated/mistica-icons/icon-dollar-symbol-circle-filled.js +25 -15
  130. package/dist/generated/mistica-icons/icon-dollar-symbol-circle-light.js +30 -14
  131. package/dist/generated/mistica-icons/icon-dollar-symbol-circle-regular.js +29 -13
  132. package/dist/generated/mistica-icons/icon-error-filled.js +33 -17
  133. package/dist/generated/mistica-icons/icon-error-light.js +29 -13
  134. package/dist/generated/mistica-icons/icon-error-regular.js +32 -16
  135. package/dist/generated/mistica-icons/icon-esim-filled.js +33 -17
  136. package/dist/generated/mistica-icons/icon-esim-light.js +43 -23
  137. package/dist/generated/mistica-icons/icon-esim-regular.js +29 -9
  138. package/dist/generated/mistica-icons/icon-eye-filled.js +18 -8
  139. package/dist/generated/mistica-icons/icon-eye-light.js +31 -15
  140. package/dist/generated/mistica-icons/icon-eye-regular.js +29 -13
  141. package/dist/generated/mistica-icons/icon-file-ok-filled.js +30 -14
  142. package/dist/generated/mistica-icons/icon-file-ok-light.js +29 -13
  143. package/dist/generated/mistica-icons/icon-file-ok-regular.js +31 -15
  144. package/dist/generated/mistica-icons/icon-fingerprint-filled.js +36 -15
  145. package/dist/generated/mistica-icons/icon-fingerprint-light.js +35 -14
  146. package/dist/generated/mistica-icons/icon-fingerprint-regular.js +29 -9
  147. package/dist/generated/mistica-icons/icon-home-filled.js +17 -7
  148. package/dist/generated/mistica-icons/icon-home-light.js +21 -11
  149. package/dist/generated/mistica-icons/icon-home-regular.js +29 -19
  150. package/dist/generated/mistica-icons/icon-home-wifi-filled.js +39 -19
  151. package/dist/generated/mistica-icons/icon-home-wifi-light.js +30 -14
  152. package/dist/generated/mistica-icons/icon-home-wifi-regular.js +37 -17
  153. package/dist/generated/mistica-icons/icon-id-card-filled.js +32 -16
  154. package/dist/generated/mistica-icons/icon-id-card-light.js +27 -11
  155. package/dist/generated/mistica-icons/icon-id-card-regular.js +31 -15
  156. package/dist/generated/mistica-icons/icon-information-user-filled.js +32 -12
  157. package/dist/generated/mistica-icons/icon-information-user-light.js +37 -21
  158. package/dist/generated/mistica-icons/icon-information-user-regular.js +44 -28
  159. package/dist/generated/mistica-icons/icon-internet-filled.js +18 -8
  160. package/dist/generated/mistica-icons/icon-internet-light.js +21 -11
  161. package/dist/generated/mistica-icons/icon-internet-regular.js +19 -9
  162. package/dist/generated/mistica-icons/icon-internet-roaming-filled.d.ts +3 -0
  163. package/dist/generated/mistica-icons/icon-internet-roaming-light.d.ts +3 -0
  164. package/dist/generated/mistica-icons/icon-internet-roaming-regular.d.ts +3 -0
  165. package/dist/generated/mistica-icons/icon-key-filled.js +21 -11
  166. package/dist/generated/mistica-icons/icon-key-light.js +31 -15
  167. package/dist/generated/mistica-icons/icon-key-regular.js +32 -16
  168. package/dist/generated/mistica-icons/icon-list-filled.js +23 -12
  169. package/dist/generated/mistica-icons/icon-list-light.js +31 -15
  170. package/dist/generated/mistica-icons/icon-list-regular.js +34 -18
  171. package/dist/generated/mistica-icons/icon-location-filled.js +25 -15
  172. package/dist/generated/mistica-icons/icon-location-light.js +30 -14
  173. package/dist/generated/mistica-icons/icon-location-regular.js +30 -14
  174. package/dist/generated/mistica-icons/icon-lock-closed-filled.js +25 -15
  175. package/dist/generated/mistica-icons/icon-lock-closed-light.js +31 -15
  176. package/dist/generated/mistica-icons/icon-lock-closed-regular.js +35 -19
  177. package/dist/generated/mistica-icons/icon-message-filled.js +23 -12
  178. package/dist/generated/mistica-icons/icon-message-light.js +28 -11
  179. package/dist/generated/mistica-icons/icon-message-regular.js +27 -10
  180. package/dist/generated/mistica-icons/icon-mobile-device-filled.js +25 -15
  181. package/dist/generated/mistica-icons/icon-mobile-device-light.js +26 -10
  182. package/dist/generated/mistica-icons/icon-mobile-device-regular.js +32 -16
  183. package/dist/generated/mistica-icons/icon-mobile-information-filled.d.ts +3 -0
  184. package/dist/generated/mistica-icons/icon-mobile-information-light.d.ts +3 -0
  185. package/dist/generated/mistica-icons/icon-mobile-information-regular.d.ts +3 -0
  186. package/dist/generated/mistica-icons/icon-panel-collapse-regular.js +165 -0
  187. package/dist/generated/mistica-icons/icon-panel-expand-regular.js +159 -0
  188. package/dist/generated/mistica-icons/icons-keywords.js +57 -0
  189. package/dist/grid-layout.css-mistica.js +3 -3
  190. package/dist/grid.css-mistica.js +120 -120
  191. package/dist/header.css-mistica.js +1 -1
  192. package/dist/header.d.ts +3 -1
  193. package/dist/header.js +81 -73
  194. package/dist/hero.css-mistica.js +4 -4
  195. package/dist/horizontal-scroll.css-mistica.js +1 -1
  196. package/dist/icon-button.css-mistica.js +53 -53
  197. package/dist/icons/icon-chevron.css-mistica.js +2 -2
  198. package/dist/icons/icon-error.css-mistica.js +1 -1
  199. package/dist/image.css-mistica.js +6 -6
  200. package/dist/index.d.ts +6 -0
  201. package/dist/index.js +14 -1
  202. package/dist/inline.css-mistica.js +11 -11
  203. package/dist/list.css-mistica.js +40 -28
  204. package/dist/list.css.d.ts +2 -0
  205. package/dist/list.d.ts +3 -1
  206. package/dist/list.js +176 -165
  207. package/dist/loading-bar.css-mistica.js +1 -1
  208. package/dist/loading-screen.css-mistica.js +12 -12
  209. package/dist/logo.css-mistica.js +5 -5
  210. package/dist/menu.css-mistica.js +13 -13
  211. package/dist/mobile-navigation-menu.d.ts +26 -0
  212. package/dist/mobile-navigation-menu.js +145 -0
  213. package/dist/mosaic.css-mistica.js +1 -1
  214. package/dist/navigation-bar.css-mistica.js +31 -97
  215. package/dist/navigation-bar.css.d.ts +0 -24
  216. package/dist/navigation-bar.d.ts +3 -38
  217. package/dist/navigation-bar.js +399 -586
  218. package/dist/navigation-breadcrumbs.css-mistica.js +1 -1
  219. package/dist/navigation-shared.css-mistica.js +79 -0
  220. package/dist/navigation-shared.css.d.ts +26 -0
  221. package/dist/navigation-shared.d.ts +66 -0
  222. package/dist/navigation-shared.js +264 -0
  223. package/dist/package-version.js +1 -1
  224. package/dist/pagination.css-mistica.js +22 -22
  225. package/dist/pin-field.css-mistica.js +4 -4
  226. package/dist/popover.css-mistica.js +1 -1
  227. package/dist/portal.d.ts +1 -1
  228. package/dist/progress-bar.css-mistica.js +7 -7
  229. package/dist/radio-button.css-mistica.js +27 -27
  230. package/dist/rating.css-mistica.js +4 -4
  231. package/dist/responsive-layout.css-mistica.js +6 -6
  232. package/dist/screen-reader-only.css-mistica.js +1 -1
  233. package/dist/select.css-mistica.js +21 -21
  234. package/dist/sheet-action-row.css-mistica.js +1 -1
  235. package/dist/sheet-common.css-mistica.js +7 -7
  236. package/dist/sheet-info.css-mistica.js +1 -1
  237. package/dist/sidenav-bar-context.d.ts +25 -0
  238. package/dist/sidenav-bar-context.js +72 -0
  239. package/dist/sidenav-bar-data.d.ts +15 -0
  240. package/dist/sidenav-bar-data.js +38 -0
  241. package/dist/sidenav-bar-first-level-item.d.ts +42 -0
  242. package/dist/sidenav-bar-first-level-item.js +174 -0
  243. package/dist/sidenav-bar-keyboard.d.ts +13 -0
  244. package/dist/sidenav-bar-keyboard.js +314 -0
  245. package/dist/sidenav-bar-layout.css-mistica.js +28 -0
  246. package/dist/sidenav-bar-layout.css.d.ts +5 -0
  247. package/dist/sidenav-bar-layout.d.ts +22 -0
  248. package/dist/sidenav-bar-layout.js +103 -0
  249. package/dist/sidenav-bar-mobile.d.ts +24 -0
  250. package/dist/sidenav-bar-mobile.js +332 -0
  251. package/dist/sidenav-bar-motion.d.ts +32 -0
  252. package/dist/sidenav-bar-motion.js +84 -0
  253. package/dist/sidenav-bar-panel.d.ts +31 -0
  254. package/dist/sidenav-bar-panel.js +208 -0
  255. package/dist/sidenav-bar-row.d.ts +82 -0
  256. package/dist/sidenav-bar-row.js +230 -0
  257. package/dist/sidenav-bar-second-level-item.d.ts +43 -0
  258. package/dist/sidenav-bar-second-level-item.js +89 -0
  259. package/dist/sidenav-bar-section.d.ts +23 -0
  260. package/dist/sidenav-bar-section.js +167 -0
  261. package/dist/sidenav-bar-types.d.ts +192 -0
  262. package/dist/sidenav-bar-types.js +11 -0
  263. package/dist/sidenav-bar.css-mistica.js +325 -0
  264. package/dist/sidenav-bar.css.d.ts +93 -0
  265. package/dist/sidenav-bar.d.ts +102 -0
  266. package/dist/sidenav-bar.js +492 -0
  267. package/dist/skeletons.css-mistica.js +8 -8
  268. package/dist/skins/blau.js +23 -8
  269. package/dist/skins/defaults.js +11 -0
  270. package/dist/skins/esimflag.js +24 -9
  271. package/dist/skins/movistar.js +24 -9
  272. package/dist/skins/o2.js +24 -9
  273. package/dist/skins/skin-contract.css-mistica.js +740 -731
  274. package/dist/skins/skin-contract.css.d.ts +9 -0
  275. package/dist/skins/telefonica.js +24 -9
  276. package/dist/skins/types/colors.d.ts +2 -0
  277. package/dist/skins/types/index.d.ts +1 -0
  278. package/dist/skins/vivo-evolution.js +25 -10
  279. package/dist/skins/vivo.js +24 -9
  280. package/dist/skip-link.css-mistica.js +2 -2
  281. package/dist/slider.css-mistica.js +24 -24
  282. package/dist/snackbar.css-mistica.js +14 -14
  283. package/dist/spinner.css-mistica.js +1 -1
  284. package/dist/square.css-mistica.js +1 -1
  285. package/dist/stack.css-mistica.js +5 -5
  286. package/dist/stacking-group.css-mistica.js +1 -1
  287. package/dist/stepper.css-mistica.js +9 -9
  288. package/dist/switch-component.css-mistica.js +48 -42
  289. package/dist/switch-component.css.d.ts +2 -0
  290. package/dist/switch-component.js +18 -18
  291. package/dist/table.css-mistica.js +9 -9
  292. package/dist/tabs.css-mistica.js +22 -22
  293. package/dist/tag.css-mistica.js +3 -3
  294. package/dist/text-field-base.css-mistica.js +20 -20
  295. package/dist/text-field-components.css-mistica.js +10 -10
  296. package/dist/text-link.css-mistica.js +6 -6
  297. package/dist/text-tokens.d.ts +6 -0
  298. package/dist/text-tokens.js +157 -133
  299. package/dist/text.css-mistica.js +6 -6
  300. package/dist/timeline.css-mistica.js +11 -11
  301. package/dist/timer.css-mistica.js +6 -6
  302. package/dist/tooltip.css-mistica.js +2 -2
  303. package/dist/touchable.css-mistica.js +4 -4
  304. package/dist/utils/aspect-ratio-support.css-mistica.js +2 -2
  305. package/dist/video.css-mistica.js +1 -1
  306. package/dist/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +1 -1
  307. package/dist-es/accordion.css-mistica.js +7 -7
  308. package/dist-es/align.css-mistica.js +1 -1
  309. package/dist-es/autocomplete.css-mistica.js +2 -2
  310. package/dist-es/avatar.css-mistica.js +1 -1
  311. package/dist-es/badge.css-mistica.js +1 -1
  312. package/dist-es/box.css-mistica.js +13 -13
  313. package/dist-es/boxed.css-mistica.js +23 -23
  314. package/dist-es/boxed.js +25 -25
  315. package/dist-es/button-group.css-mistica.js +1 -1
  316. package/dist-es/button-layout.css-mistica.js +16 -16
  317. package/dist-es/button.css-mistica.js +38 -38
  318. package/dist-es/callout.css-mistica.js +12 -12
  319. package/dist-es/card-internal.css-mistica.js +17 -17
  320. package/dist-es/carousel.css-mistica.js +10 -10
  321. package/dist-es/checkbox.css-mistica.js +13 -13
  322. package/dist-es/chip.css-mistica.js +17 -17
  323. package/dist-es/circle.css-mistica.js +2 -2
  324. package/dist-es/community/advanced-data-card.css-mistica.js +7 -7
  325. package/dist-es/community/ai-card.css-mistica.js +4 -4
  326. package/dist-es/community/blocks.css-mistica.js +1 -1
  327. package/dist-es/community/cyber/example-component.css-mistica.js +1 -1
  328. package/dist-es/community/example-component.css-mistica.js +1 -1
  329. package/dist-es/community/skins/cyber-skin.js +19 -17
  330. package/dist-es/counter.css-mistica.js +2 -2
  331. package/dist-es/cover-hero.css-mistica.js +4 -4
  332. package/dist-es/credit-card-number-field.css-mistica.js +3 -3
  333. package/dist-es/date-field.css-mistica.js +1 -1
  334. package/dist-es/date-time-picker.css-mistica.js +1 -1
  335. package/dist-es/dialog.css-mistica.js +5 -5
  336. package/dist-es/divider.css-mistica.js +5 -5
  337. package/dist-es/double-field.css-mistica.js +2 -2
  338. package/dist-es/drawer.css-mistica.js +2 -2
  339. package/dist-es/empty-state-card.css-mistica.js +1 -1
  340. package/dist-es/empty-state.css-mistica.js +7 -7
  341. package/dist-es/fade-in.css-mistica.js +1 -1
  342. package/dist-es/fade-out.css-mistica.js +2 -0
  343. package/dist-es/fade-out.js +79 -0
  344. package/dist-es/feedback.css-mistica.js +2 -2
  345. package/dist-es/file-upload.css-mistica.js +8 -8
  346. package/dist-es/fixed-footer-layout.css-mistica.js +3 -3
  347. package/dist-es/form.css-mistica.js +1 -1
  348. package/dist-es/generated/mistica-icons/icon-antenna-filled.js +50 -22
  349. package/dist-es/generated/mistica-icons/icon-antenna-light.js +47 -27
  350. package/dist-es/generated/mistica-icons/icon-antenna-regular.js +52 -24
  351. package/dist-es/generated/mistica-icons/icon-arrow-up-down-filled.js +29 -19
  352. package/dist-es/generated/mistica-icons/icon-arrow-up-down-light.js +26 -16
  353. package/dist-es/generated/mistica-icons/icon-arrow-up-down-regular.js +34 -24
  354. package/dist-es/generated/mistica-icons/icon-arrows-left-and-right-filled.js +30 -20
  355. package/dist-es/generated/mistica-icons/icon-arrows-left-and-right-light.js +32 -22
  356. package/dist-es/generated/mistica-icons/icon-arrows-left-and-right-regular.js +34 -24
  357. package/dist-es/generated/mistica-icons/icon-authentication-success-filled.js +42 -22
  358. package/dist-es/generated/mistica-icons/icon-authentication-success-light.js +44 -28
  359. package/dist-es/generated/mistica-icons/icon-authentication-success-regular.js +42 -26
  360. package/dist-es/generated/mistica-icons/icon-blog-filled.js +44 -24
  361. package/dist-es/generated/mistica-icons/icon-blog-light.js +45 -25
  362. package/dist-es/generated/mistica-icons/icon-blog-regular.js +45 -29
  363. package/dist-es/generated/mistica-icons/icon-book-filled.js +23 -13
  364. package/dist-es/generated/mistica-icons/icon-book-light.js +33 -23
  365. package/dist-es/generated/mistica-icons/icon-book-regular.js +22 -12
  366. package/dist-es/generated/mistica-icons/icon-box-filled.js +38 -22
  367. package/dist-es/generated/mistica-icons/icon-box-light.js +38 -28
  368. package/dist-es/generated/mistica-icons/icon-box-regular.js +37 -27
  369. package/dist-es/generated/mistica-icons/icon-box-star-filled.js +49 -29
  370. package/dist-es/generated/mistica-icons/icon-box-star-light.js +29 -13
  371. package/dist-es/generated/mistica-icons/icon-box-star-regular.js +33 -17
  372. package/dist-es/generated/mistica-icons/icon-briefcase-filled.js +32 -16
  373. package/dist-es/generated/mistica-icons/icon-briefcase-light.js +24 -14
  374. package/dist-es/generated/mistica-icons/icon-briefcase-regular.js +32 -22
  375. package/dist-es/generated/mistica-icons/icon-calendar-event-filled.js +28 -17
  376. package/dist-es/generated/mistica-icons/icon-calendar-event-light.js +34 -17
  377. package/dist-es/generated/mistica-icons/icon-calendar-event-regular.js +36 -19
  378. package/dist-es/generated/mistica-icons/icon-calendar-filled.js +42 -32
  379. package/dist-es/generated/mistica-icons/icon-calendar-light.js +45 -29
  380. package/dist-es/generated/mistica-icons/icon-calendar-month-filled.js +31 -20
  381. package/dist-es/generated/mistica-icons/icon-calendar-month-light.js +38 -21
  382. package/dist-es/generated/mistica-icons/icon-calendar-month-regular.js +38 -21
  383. package/dist-es/generated/mistica-icons/icon-calendar-regular.js +45 -29
  384. package/dist-es/generated/mistica-icons/icon-car-filled.js +26 -10
  385. package/dist-es/generated/mistica-icons/icon-car-light.js +33 -23
  386. package/dist-es/generated/mistica-icons/icon-car-regular.js +29 -19
  387. package/dist-es/generated/mistica-icons/icon-care-briefcase-filled.js +30 -19
  388. package/dist-es/generated/mistica-icons/icon-care-briefcase-light.js +28 -17
  389. package/dist-es/generated/mistica-icons/icon-care-briefcase-regular.js +24 -14
  390. package/dist-es/generated/mistica-icons/icon-care-filled.js +29 -19
  391. package/dist-es/generated/mistica-icons/icon-care-home-filled.js +32 -21
  392. package/dist-es/generated/mistica-icons/icon-care-home-light.js +31 -20
  393. package/dist-es/generated/mistica-icons/icon-care-home-regular.js +40 -30
  394. package/dist-es/generated/mistica-icons/icon-care-laptop-filled.js +29 -18
  395. package/dist-es/generated/mistica-icons/icon-care-laptop-light.js +31 -20
  396. package/dist-es/generated/mistica-icons/icon-care-laptop-regular.js +33 -23
  397. package/dist-es/generated/mistica-icons/icon-care-light.js +24 -14
  398. package/dist-es/generated/mistica-icons/icon-care-mobile-filled.js +30 -19
  399. package/dist-es/generated/mistica-icons/icon-care-mobile-light.js +35 -18
  400. package/dist-es/generated/mistica-icons/icon-care-mobile-regular.js +50 -34
  401. package/dist-es/generated/mistica-icons/icon-care-regular.js +38 -28
  402. package/dist-es/generated/mistica-icons/icon-care-shield-filled.js +33 -23
  403. package/dist-es/generated/mistica-icons/icon-care-shield-light.js +27 -17
  404. package/dist-es/generated/mistica-icons/icon-care-shield-regular.js +33 -23
  405. package/dist-es/generated/mistica-icons/icon-change-plan-filled.js +41 -21
  406. package/dist-es/generated/mistica-icons/icon-change-plan-light.js +42 -22
  407. package/dist-es/generated/mistica-icons/icon-change-plan-regular.js +35 -19
  408. package/dist-es/generated/mistica-icons/icon-chip-device-filled.js +37 -21
  409. package/dist-es/generated/mistica-icons/icon-chip-device-light.js +46 -30
  410. package/dist-es/generated/mistica-icons/icon-chip-device-regular.js +48 -32
  411. package/dist-es/generated/mistica-icons/icon-chip-sim-card-filled.js +26 -16
  412. package/dist-es/generated/mistica-icons/icon-chip-sim-card-light.js +43 -27
  413. package/dist-es/generated/mistica-icons/icon-chip-sim-card-regular.js +59 -43
  414. package/dist-es/generated/mistica-icons/icon-credit-card-filled.js +24 -14
  415. package/dist-es/generated/mistica-icons/icon-credit-card-light.js +19 -9
  416. package/dist-es/generated/mistica-icons/icon-credit-card-regular.js +26 -16
  417. package/dist-es/generated/mistica-icons/icon-document-other-filled.js +31 -15
  418. package/dist-es/generated/mistica-icons/icon-document-other-light.js +42 -26
  419. package/dist-es/generated/mistica-icons/icon-document-other-regular.js +32 -16
  420. package/dist-es/generated/mistica-icons/icon-dollar-symbol-circle-filled.js +28 -18
  421. package/dist-es/generated/mistica-icons/icon-dollar-symbol-circle-light.js +41 -25
  422. package/dist-es/generated/mistica-icons/icon-dollar-symbol-circle-regular.js +42 -26
  423. package/dist-es/generated/mistica-icons/icon-error-filled.js +44 -28
  424. package/dist-es/generated/mistica-icons/icon-error-light.js +37 -21
  425. package/dist-es/generated/mistica-icons/icon-error-regular.js +40 -24
  426. package/dist-es/generated/mistica-icons/icon-esim-filled.js +48 -32
  427. package/dist-es/generated/mistica-icons/icon-esim-light.js +58 -38
  428. package/dist-es/generated/mistica-icons/icon-esim-regular.js +35 -15
  429. package/dist-es/generated/mistica-icons/icon-eye-filled.js +24 -14
  430. package/dist-es/generated/mistica-icons/icon-eye-light.js +43 -27
  431. package/dist-es/generated/mistica-icons/icon-eye-regular.js +33 -17
  432. package/dist-es/generated/mistica-icons/icon-file-ok-filled.js +41 -25
  433. package/dist-es/generated/mistica-icons/icon-file-ok-light.js +37 -21
  434. package/dist-es/generated/mistica-icons/icon-file-ok-regular.js +41 -25
  435. package/dist-es/generated/mistica-icons/icon-fingerprint-filled.js +45 -24
  436. package/dist-es/generated/mistica-icons/icon-fingerprint-light.js +39 -18
  437. package/dist-es/generated/mistica-icons/icon-fingerprint-regular.js +32 -12
  438. package/dist-es/generated/mistica-icons/icon-home-filled.js +19 -9
  439. package/dist-es/generated/mistica-icons/icon-home-light.js +24 -14
  440. package/dist-es/generated/mistica-icons/icon-home-regular.js +30 -20
  441. package/dist-es/generated/mistica-icons/icon-home-wifi-filled.js +51 -31
  442. package/dist-es/generated/mistica-icons/icon-home-wifi-light.js +36 -20
  443. package/dist-es/generated/mistica-icons/icon-home-wifi-regular.js +51 -31
  444. package/dist-es/generated/mistica-icons/icon-id-card-filled.js +40 -24
  445. package/dist-es/generated/mistica-icons/icon-id-card-light.js +38 -22
  446. package/dist-es/generated/mistica-icons/icon-id-card-regular.js +42 -26
  447. package/dist-es/generated/mistica-icons/icon-information-user-filled.js +36 -16
  448. package/dist-es/generated/mistica-icons/icon-information-user-light.js +51 -35
  449. package/dist-es/generated/mistica-icons/icon-information-user-regular.js +58 -42
  450. package/dist-es/generated/mistica-icons/icon-internet-filled.js +22 -12
  451. package/dist-es/generated/mistica-icons/icon-internet-light.js +25 -15
  452. package/dist-es/generated/mistica-icons/icon-internet-regular.js +22 -12
  453. package/dist-es/generated/mistica-icons/icon-key-filled.js +23 -13
  454. package/dist-es/generated/mistica-icons/icon-key-light.js +40 -24
  455. package/dist-es/generated/mistica-icons/icon-key-regular.js +40 -24
  456. package/dist-es/generated/mistica-icons/icon-list-filled.js +29 -18
  457. package/dist-es/generated/mistica-icons/icon-list-light.js +38 -22
  458. package/dist-es/generated/mistica-icons/icon-list-regular.js +42 -26
  459. package/dist-es/generated/mistica-icons/icon-location-filled.js +29 -19
  460. package/dist-es/generated/mistica-icons/icon-location-light.js +37 -21
  461. package/dist-es/generated/mistica-icons/icon-location-regular.js +37 -21
  462. package/dist-es/generated/mistica-icons/icon-lock-closed-filled.js +28 -18
  463. package/dist-es/generated/mistica-icons/icon-lock-closed-light.js +35 -19
  464. package/dist-es/generated/mistica-icons/icon-lock-closed-regular.js +40 -24
  465. package/dist-es/generated/mistica-icons/icon-message-filled.js +29 -18
  466. package/dist-es/generated/mistica-icons/icon-message-light.js +36 -19
  467. package/dist-es/generated/mistica-icons/icon-message-regular.js +35 -18
  468. package/dist-es/generated/mistica-icons/icon-mobile-device-filled.js +30 -20
  469. package/dist-es/generated/mistica-icons/icon-mobile-device-light.js +34 -18
  470. package/dist-es/generated/mistica-icons/icon-mobile-device-regular.js +37 -21
  471. package/dist-es/generated/mistica-icons/icon-panel-collapse-regular.js +115 -0
  472. package/dist-es/generated/mistica-icons/icon-panel-expand-regular.js +109 -0
  473. package/dist-es/generated/mistica-icons/icons-keywords.js +57 -0
  474. package/dist-es/grid-layout.css-mistica.js +3 -3
  475. package/dist-es/grid.css-mistica.js +120 -120
  476. package/dist-es/header.css-mistica.js +1 -1
  477. package/dist-es/header.js +113 -105
  478. package/dist-es/hero.css-mistica.js +3 -3
  479. package/dist-es/horizontal-scroll.css-mistica.js +1 -1
  480. package/dist-es/icon-button.css-mistica.js +53 -53
  481. package/dist-es/icons/icon-chevron.css-mistica.js +2 -2
  482. package/dist-es/icons/icon-error.css-mistica.js +1 -1
  483. package/dist-es/image.css-mistica.js +4 -4
  484. package/dist-es/index.js +2349 -2345
  485. package/dist-es/inline.css-mistica.js +11 -11
  486. package/dist-es/list.css-mistica.js +8 -2
  487. package/dist-es/list.js +275 -264
  488. package/dist-es/loading-bar.css-mistica.js +1 -1
  489. package/dist-es/loading-screen.css-mistica.js +5 -5
  490. package/dist-es/logo.css-mistica.js +5 -5
  491. package/dist-es/menu.css-mistica.js +13 -13
  492. package/dist-es/mobile-navigation-menu.js +90 -0
  493. package/dist-es/mosaic.css-mistica.js +1 -1
  494. package/dist-es/navigation-bar.css-mistica.js +11 -20
  495. package/dist-es/navigation-bar.js +469 -656
  496. package/dist-es/navigation-breadcrumbs.css-mistica.js +1 -1
  497. package/dist-es/navigation-shared.css-mistica.js +11 -0
  498. package/dist-es/navigation-shared.js +192 -0
  499. package/dist-es/package-version.js +1 -1
  500. package/dist-es/pagination.css-mistica.js +19 -19
  501. package/dist-es/pin-field.css-mistica.js +2 -2
  502. package/dist-es/popover.css-mistica.js +1 -1
  503. package/dist-es/progress-bar.css-mistica.js +7 -7
  504. package/dist-es/radio-button.css-mistica.js +22 -22
  505. package/dist-es/rating.css-mistica.js +3 -3
  506. package/dist-es/responsive-layout.css-mistica.js +6 -6
  507. package/dist-es/screen-reader-only.css-mistica.js +1 -1
  508. package/dist-es/select.css-mistica.js +18 -18
  509. package/dist-es/sheet-action-row.css-mistica.js +1 -1
  510. package/dist-es/sheet-common.css-mistica.js +2 -2
  511. package/dist-es/sheet-info.css-mistica.js +1 -1
  512. package/dist-es/sidenav-bar-context.js +14 -0
  513. package/dist-es/sidenav-bar-data.js +12 -0
  514. package/dist-es/sidenav-bar-first-level-item.js +124 -0
  515. package/dist-es/sidenav-bar-keyboard.js +253 -0
  516. package/dist-es/sidenav-bar-layout.css-mistica.js +2 -0
  517. package/dist-es/sidenav-bar-layout.js +86 -0
  518. package/dist-es/sidenav-bar-mobile.js +277 -0
  519. package/dist-es/sidenav-bar-motion.js +26 -0
  520. package/dist-es/sidenav-bar-panel.js +146 -0
  521. package/dist-es/sidenav-bar-row.js +208 -0
  522. package/dist-es/sidenav-bar-second-level-item.js +72 -0
  523. package/dist-es/sidenav-bar-section.js +112 -0
  524. package/dist-es/sidenav-bar-types.js +2 -0
  525. package/dist-es/sidenav-bar.css-mistica.js +74 -0
  526. package/dist-es/sidenav-bar.js +429 -0
  527. package/dist-es/skeletons.css-mistica.js +7 -7
  528. package/dist-es/skins/blau.js +23 -8
  529. package/dist-es/skins/defaults.js +11 -0
  530. package/dist-es/skins/esimflag.js +24 -9
  531. package/dist-es/skins/movistar.js +24 -9
  532. package/dist-es/skins/o2.js +24 -9
  533. package/dist-es/skins/skin-contract.css-mistica.js +740 -731
  534. package/dist-es/skins/telefonica.js +24 -9
  535. package/dist-es/skins/vivo-evolution.js +25 -10
  536. package/dist-es/skins/vivo.js +24 -9
  537. package/dist-es/skip-link.css-mistica.js +2 -2
  538. package/dist-es/slider.css-mistica.js +20 -20
  539. package/dist-es/snackbar.css-mistica.js +5 -5
  540. package/dist-es/spinner.css-mistica.js +1 -1
  541. package/dist-es/square.css-mistica.js +1 -1
  542. package/dist-es/stack.css-mistica.js +5 -5
  543. package/dist-es/stacking-group.css-mistica.js +1 -1
  544. package/dist-es/stepper.css-mistica.js +3 -3
  545. package/dist-es/style.css +1 -1
  546. package/dist-es/switch-component.css-mistica.js +37 -37
  547. package/dist-es/switch-component.js +26 -26
  548. package/dist-es/table.css-mistica.js +9 -9
  549. package/dist-es/tabs.css-mistica.js +19 -19
  550. package/dist-es/tag.css-mistica.js +2 -2
  551. package/dist-es/text-field-base.css-mistica.js +17 -17
  552. package/dist-es/text-field-components.css-mistica.js +4 -4
  553. package/dist-es/text-link.css-mistica.js +6 -6
  554. package/dist-es/text-tokens.js +82 -67
  555. package/dist-es/text.css-mistica.js +6 -6
  556. package/dist-es/timeline.css-mistica.js +10 -10
  557. package/dist-es/timer.css-mistica.js +6 -6
  558. package/dist-es/tooltip.css-mistica.js +2 -2
  559. package/dist-es/touchable.css-mistica.js +2 -2
  560. package/dist-es/utils/aspect-ratio-support.css-mistica.js +2 -2
  561. package/dist-es/video.css-mistica.js +1 -1
  562. package/dist-es/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +1 -1
  563. package/package.json +2 -1
  564. package/src/boxed.css.ts +1 -0
  565. package/src/boxed.tsx +18 -5
  566. package/src/callout.css.ts +4 -2
  567. package/src/community/skins/cyber-skin.tsx +19 -16
  568. package/src/fade-out.css.ts +12 -0
  569. package/src/fade-out.tsx +50 -0
  570. package/src/header.tsx +39 -17
  571. package/src/index.tsx +15 -0
  572. package/src/list.css.ts +36 -1
  573. package/src/list.tsx +370 -344
  574. package/src/mobile-navigation-menu.tsx +168 -0
  575. package/src/navigation-bar.css.ts +2 -267
  576. package/src/navigation-bar.tsx +77 -370
  577. package/src/navigation-shared.css.ts +289 -0
  578. package/src/navigation-shared.tsx +262 -0
  579. package/src/package-version.tsx +1 -1
  580. package/src/portal.tsx +1 -1
  581. package/src/sidenav-bar-context.tsx +41 -0
  582. package/src/sidenav-bar-data.ts +49 -0
  583. package/src/sidenav-bar-first-level-item.tsx +203 -0
  584. package/src/sidenav-bar-keyboard.tsx +393 -0
  585. package/src/sidenav-bar-layout.css.ts +89 -0
  586. package/src/sidenav-bar-layout.tsx +61 -0
  587. package/src/sidenav-bar-mobile.tsx +302 -0
  588. package/src/sidenav-bar-motion.tsx +70 -0
  589. package/src/sidenav-bar-panel.tsx +269 -0
  590. package/src/sidenav-bar-row.tsx +272 -0
  591. package/src/sidenav-bar-second-level-item.tsx +99 -0
  592. package/src/sidenav-bar-section.tsx +98 -0
  593. package/src/sidenav-bar-types.ts +224 -0
  594. package/src/sidenav-bar.css.ts +1018 -0
  595. package/src/sidenav-bar.tsx +821 -0
  596. package/src/skins/blau.tsx +17 -8
  597. package/src/skins/defaults.tsx +5 -0
  598. package/src/skins/esimflag.tsx +18 -9
  599. package/src/skins/movistar.tsx +18 -9
  600. package/src/skins/o2.tsx +18 -9
  601. package/src/skins/skin-contract.css.ts +3 -0
  602. package/src/skins/telefonica.tsx +18 -9
  603. package/src/skins/types/colors.tsx +2 -0
  604. package/src/skins/types/index.tsx +1 -0
  605. package/src/skins/vivo-evolution.tsx +19 -10
  606. package/src/skins/vivo.tsx +18 -9
  607. package/src/switch-component.css.ts +20 -0
  608. package/src/switch-component.tsx +9 -1
  609. package/src/text-tokens.tsx +24 -0
@@ -0,0 +1,1018 @@
1
+ import {createVar, globalStyle, style, styleVariants} from '@vanilla-extract/css';
2
+ import {sprinkles} from './sprinkles.css';
3
+ import {vars as skinVars} from './skins/skin-contract.css';
4
+
5
+ import type {NonDeprecatedVariant} from './theme-variant-context';
6
+
7
+ export const DEFAULT_WIDTH = 240;
8
+ export const COLLAPSED_WIDTH = 72;
9
+ const BOXED_INSET = 8;
10
+ // Left padding of a second-level row. It adds to the 8px left margin of the row (which clears the selected
11
+ // indicator on the rail), so the content of a second-level row lands 24px from the rail, as the Figma spec asks
12
+ // (16 + 8). The full 24 here would count the 8px margin twice.
13
+ const SECOND_LEVEL_INDENT = 16;
14
+ export const LOGO_SIZE = 32;
15
+ // Horizontal inset of the items rail on each side of a section (see `sectionContent`). The selected
16
+ // indicator of an item sits on that inset, at the left edge of the rail.
17
+ const RAIL_INSET = 10;
18
+ // Margin of the row of an item, on each side of the items rail. On the left it is measured from the left
19
+ // edge of the selected indicator, which is 2px wide, so the row keeps a gap of 6px from that indicator.
20
+ // The expanded sidenav and the collapsed rail share this number: the row of an item stands in the same
21
+ // place in both states, 18px from each edge of the sidenav.
22
+ const ITEM_ROW_INSET = 8;
23
+ const ITEM_ROW_GAP = 8;
24
+ const ITEM_ROW_HEIGHT = 44;
25
+ // Vertical padding of a row. A label that wraps keeps this room above and below its text, and a label of
26
+ // one line keeps the row at `ITEM_ROW_HEIGHT`: `Text2` measures 24px on the skin that gives it the most
27
+ // room, and 24 plus the two paddings is exactly that height.
28
+ const ITEM_ROW_PADDING_Y = 10;
29
+ const SECTION_TITLE_INSET = 24;
30
+ // Horizontal inset of the floating dialog panel. The row of each item adds `ITEM_ROW_INSET` on top of it,
31
+ // so the content of a child item lands at `SECTION_TITLE_INSET` from the edge of the panel.
32
+ const DIALOG_PANEL_INSET = 8;
33
+ const DIALOG_PANEL_PADDING_Y = 16;
34
+ // Vertical space that every entry of the first level of the body (a section or a stand-alone item) owns
35
+ // above and below itself. Two neighbours therefore stand twice this apart, and the first and the last
36
+ // entries keep it towards the header and the footer.
37
+ const ENTRY_SPACE_Y = 8;
38
+ // Vertical space between a section divider and the items that it faces. The outward side of the divider
39
+ // owns nothing: the entries around it already stand `ENTRY_SPACE_Y` apart on each side.
40
+ const SECTION_DIVIDER_MARGIN_Y = 16;
41
+ const SECTION_DIVIDER_MARGIN_X = 8;
42
+ const HEADER_SCROLL_SPACER_HEIGHT = 24;
43
+ const SLOT_INSET_X = 24;
44
+ // The collapsed rail draws both slots on the rail of the items, so they take `RAIL_INSET` there. The
45
+ // expanded inset would leave a slot only 24px of the 72px rail.
46
+ const COLLAPSED_SLOT_INSET_X = RAIL_INSET;
47
+ // Vertical insets of the footer slot, which are not equal to each other: the Figma anatomy frame of the
48
+ // footer region gives its slot 8px above and 32px below.
49
+ const FOOTER_PADDING_TOP = 8;
50
+ const FOOTER_PADDING_BOTTOM = 32;
51
+ const FOCUS_RING_ROOM = 4;
52
+
53
+ export const sidenavWidthVar = createVar();
54
+ // The second column always takes the `width` of the expanded sidenav, so it needs its own variable: the
55
+ // variable above carries the width of the collapsed rail while the sidenav is collapsed.
56
+ export const sidenavPanelWidthVar = createVar();
57
+
58
+ // Animation ------------------------------------------------------------------
59
+
60
+ export const COLLAPSE_DURATION_MS = 350;
61
+ export const CONTENT_DURATION_MS = 400;
62
+
63
+ const COLLAPSE_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';
64
+ const CONTENT_EASING = 'ease';
65
+
66
+ // `SidenavBar` fills both durations on its root element, and every rule below reads them from there.
67
+ // An acceptance run receives 0ms, so a test that presses a control and reads the result at once never
68
+ // catches a frame of the movement.
69
+ export const collapseDurationVar = createVar();
70
+ export const contentDurationVar = createVar();
71
+
72
+ // Every animated rule of this file carries this block: the spec asks for an instant change when the
73
+ // user turns motion down in the operating system.
74
+ const reducedMotion = {
75
+ '@media': {
76
+ ['(prefers-reduced-motion)']: {
77
+ transition: 'none',
78
+ },
79
+ },
80
+ } as const;
81
+
82
+ // Tokens ----------------------------------------------------------------------
83
+
84
+ // The spec paints the header, the body and the footer of every variant with an existing background token,
85
+ // one member per variant. A boxed sidenav paints the same colours as a full-height one, with one exception:
86
+ // the negative boxed header (see `headerNegativeBoxedBackground`).
87
+ const regionBackgroundColor: Record<NonDeprecatedVariant, string> = {
88
+ default: skinVars.colors.background,
89
+ brand: skinVars.colors.navigationBarBackground,
90
+ alternative: skinVars.colors.backgroundAlternative,
91
+ negative: skinVars.colors.backgroundNegative,
92
+ media: skinVars.colors.backgroundNegative,
93
+ };
94
+
95
+ // The negative variant is the only one whose boxed header takes a different token: the spec gives it
96
+ // `backgroundContainerNegative`, while its body and footer keep `backgroundNegative`. The header cannot be
97
+ // transparent, because the content scrolls underneath it while it is fixed.
98
+ export const headerNegativeBoxedBackground = style({
99
+ backgroundColor: skinVars.colors.backgroundContainerNegative,
100
+ });
101
+
102
+ // Every divider of the sidenav (the right divider, the two overscroll dividers, the section dividers and the
103
+ // separator of the double panel column) takes the same token for a given variant.
104
+ const dividerColor: Record<NonDeprecatedVariant, string> = {
105
+ default: skinVars.colors.divider,
106
+ brand: skinVars.colors.dividerBrand,
107
+ alternative: skinVars.colors.divider,
108
+ negative: skinVars.colors.dividerNegative,
109
+ media: skinVars.colors.dividerNegative,
110
+ };
111
+
112
+ const sectionTitleColor: Record<NonDeprecatedVariant, string> = {
113
+ default: skinVars.colors.textSecondary,
114
+ brand: skinVars.colors.textSecondaryBrand,
115
+ alternative: skinVars.colors.textSecondary,
116
+ negative: skinVars.colors.textSecondaryNegative,
117
+ media: skinVars.colors.textSecondaryNegative,
118
+ };
119
+
120
+ type ItemColors = {
121
+ label: string;
122
+ asset: string;
123
+ chevron: string;
124
+ indicator: string;
125
+ hover: string;
126
+ pressed: string;
127
+ selected: string;
128
+ selectedHover: string;
129
+ selectedPressed: string;
130
+ };
131
+
132
+ // The resting background of an item is transparent in every variant, so the region behind it shows through.
133
+ const itemColors: Record<NonDeprecatedVariant, ItemColors> = {
134
+ default: {
135
+ label: skinVars.colors.textPrimary,
136
+ asset: 'currentColor',
137
+ chevron: skinVars.colors.chevronIndicator,
138
+ indicator: skinVars.colors.controlActivated,
139
+ hover: skinVars.colors.backgroundContainerHover,
140
+ pressed: skinVars.colors.backgroundContainerPressed,
141
+ selected: skinVars.colors.backgroundSelected,
142
+ selectedHover: skinVars.colors.backgroundSelectedHover,
143
+ selectedPressed: skinVars.colors.backgroundSelectedPressed,
144
+ },
145
+ brand: {
146
+ label: skinVars.colors.textPrimaryBrand,
147
+ asset: 'currentColor',
148
+ chevron: skinVars.colors.neutralHighBrand,
149
+ indicator: skinVars.colors.controlActivatedBrand,
150
+ hover: skinVars.colors.backgroundContainerBrandHover,
151
+ pressed: skinVars.colors.backgroundContainerBrandPressed,
152
+ selected: skinVars.colors.backgroundSelectedBrand,
153
+ selectedHover: skinVars.colors.backgroundSelectedBrandHover,
154
+ selectedPressed: skinVars.colors.backgroundSelectedBrandPressed,
155
+ },
156
+ alternative: {
157
+ label: skinVars.colors.textPrimary,
158
+ asset: 'currentColor',
159
+ chevron: skinVars.colors.chevronIndicator,
160
+ indicator: skinVars.colors.controlActivated,
161
+ hover: skinVars.colors.backgroundContainerHover,
162
+ pressed: skinVars.colors.backgroundContainerPressed,
163
+ selected: skinVars.colors.backgroundSelected,
164
+ selectedHover: skinVars.colors.backgroundSelectedHover,
165
+ selectedPressed: skinVars.colors.backgroundSelectedPressed,
166
+ },
167
+ negative: {
168
+ label: skinVars.colors.textPrimaryNegative,
169
+ asset: 'currentColor',
170
+ chevron: skinVars.colors.neutralHighNegative,
171
+ indicator: skinVars.colors.controlActivatedNegative,
172
+ hover: skinVars.colors.backgroundContainerHover,
173
+ pressed: skinVars.colors.backgroundContainerPressed,
174
+ selected: skinVars.colors.backgroundSelectedNegative,
175
+ selectedHover: skinVars.colors.backgroundSelectedNegativeHover,
176
+ selectedPressed: skinVars.colors.backgroundSelectedNegativePressed,
177
+ },
178
+ media: {
179
+ label: skinVars.colors.textPrimaryNegative,
180
+ asset: 'currentColor',
181
+ chevron: skinVars.colors.neutralHighNegative,
182
+ indicator: skinVars.colors.controlActivatedNegative,
183
+ hover: skinVars.colors.backgroundContainerHover,
184
+ pressed: skinVars.colors.backgroundContainerPressed,
185
+ selected: skinVars.colors.backgroundSelected,
186
+ selectedHover: skinVars.colors.backgroundSelectedHover,
187
+ selectedPressed: skinVars.colors.backgroundSelectedPressed,
188
+ },
189
+ };
190
+
191
+ // The container is a row of columns: the main column, and the double panel column when it is open. Its
192
+ // width is intrinsic, so an open panel widens the sidenav and pushes the main content of the layout.
193
+ // It paints no background of its own: each region owns its token, and the body of the default variant
194
+ // is transparent, so the page shows through it.
195
+ // The three heights below replace the plain `100%` that a rail of `SidenavLayout` would need on its own.
196
+ // A percentage height resolves to `auto` under a parent that takes the height of its content, and the
197
+ // sidenav then shrinks to the height of its items, which is what a consumer sees when it renders the bar
198
+ // outside of the layout. A percentage `min-height` reads as `0` under that same parent, and a percentage
199
+ // `max-height` reads as `none`, so the two of them pin the sidenav to the height of its parent wherever
200
+ // that height exists, and they leave the height of the viewport wherever it does not.
201
+ export const container = style([
202
+ sprinkles({
203
+ display: 'flex',
204
+ flexDirection: 'row',
205
+ }),
206
+ {
207
+ position: 'relative',
208
+ boxSizing: 'border-box',
209
+ // The width belongs to the columns, so the root takes the width that they ask for. A block-level
210
+ // box otherwise fills the width of its parent, and the edge of a boxed sidenav, which the root
211
+ // paints, then stood far to the right of the items of a narrower `width`. A flex item resolves
212
+ // its width the same way, so a rail of `SidenavLayout` measured the columns already.
213
+ width: 'fit-content',
214
+ height: '100vh',
215
+ minHeight: '100%',
216
+ maxHeight: '100%',
217
+ overflow: 'hidden',
218
+ },
219
+ ]);
220
+
221
+ // The column that carries the header, the body, and the footer regions.
222
+ // `sidenavWidthVar` carries the width of the expanded sidenav or the width of the collapsed rail, so the
223
+ // transition below runs whenever the user toggles the sidenav.
224
+ export const mainColumn = style([
225
+ sprinkles({
226
+ display: 'flex',
227
+ flexDirection: 'column',
228
+ }),
229
+ {
230
+ position: 'relative',
231
+ boxSizing: 'border-box',
232
+ height: '100%',
233
+ width: sidenavWidthVar,
234
+ flexShrink: 0,
235
+ minWidth: 0,
236
+ transition: `width ${collapseDurationVar} ${COLLAPSE_EASING}`,
237
+ ...reducedMotion,
238
+ },
239
+ ]);
240
+
241
+ // A vertical divider paints over the last pixel column of the box that owns it, as an absolutely
242
+ // positioned overlay. A real border grows the intrinsic width of the container instead, so the whole
243
+ // sidenav (and the content next to it) shifted by 1px when the consumer toggled the divider. With the
244
+ // overlay, `width` is a total width, dividers included, for both columns, and no child moves. An
245
+ // outline is not an option either: the container has `overflow: hidden`, which clips it.
246
+ const verticalDividerOverlay = {
247
+ content: '',
248
+ position: 'absolute',
249
+ top: 0,
250
+ right: 0,
251
+ bottom: 0,
252
+ width: 1,
253
+ pointerEvents: 'none',
254
+ // Above the sticky scroll dividers of the body, above the header, and above the edge of a boxed
255
+ // sidenav (see `boxedBorder`), so this line reaches the top and the bottom of the box.
256
+ zIndex: 4,
257
+ } as const;
258
+
259
+ export const withRightDivider = styleVariants(dividerColor, (color) => ({
260
+ '::after': {...verticalDividerOverlay, backgroundColor: color},
261
+ }));
262
+
263
+ // The header, the body and the footer share one background per variant, so the three bands of the sidenav
264
+ // stay uniform, and a boxed sidenav paints the same colours as a full-height one.
265
+ export const regionBackground = styleVariants(regionBackgroundColor, (color) => ({
266
+ backgroundColor: color,
267
+ }));
268
+
269
+ // While the rail moves, every column of the sidenav stops answering the pointer: the row that the user
270
+ // aims at is travelling, and a floating panel opened here would measure an edge that has not arrived yet.
271
+ // The rule lands on the columns, and not on the container, so the container still takes the press: a press
272
+ // that fell through to the page behind would read as a press outside of the bar, and it would close the
273
+ // second column.
274
+ export const columnsWhileMoving = style({});
275
+
276
+ globalStyle(`${columnsWhileMoving} > *`, {
277
+ pointerEvents: 'none',
278
+ });
279
+
280
+ // The margins of the box belong to the height, so a boxed sidenav and a full-height one take the same
281
+ // room. The three heights follow the rule of `container` above.
282
+ export const boxed = style({
283
+ margin: BOXED_INSET,
284
+ height: `calc(100vh - ${BOXED_INSET * 2}px)`,
285
+ minHeight: `calc(100% - ${BOXED_INSET * 2}px)`,
286
+ maxHeight: `calc(100% - ${BOXED_INSET * 2}px)`,
287
+ borderRadius: skinVars.borderRadii.popup,
288
+ });
289
+
290
+ // The edge of the box is an overlay, not a real border. A real border takes 1px of the container on
291
+ // each side, and `overflow: hidden` clips every child to the padding box, so the separator of the
292
+ // double panel could not reach the top and the bottom edge of the box: it stopped one pixel short of
293
+ // them, and that pixel reads as a gap wherever the border token matches the background of the sidenav,
294
+ // which every dark mode does. The overlay keeps the border out of the intrinsic size too, so a boxed
295
+ // sidenav of `width` pixels measures exactly that width. An outline is not an option: `overflow:
296
+ // hidden` clips a negatively-offset outline.
297
+ // `shouldShowBoxedBorder` decides when this class applies: the border only reads over a default or an
298
+ // alternative page, and a skin can switch it off.
299
+ // todo https://github.com/Telefonica/mistica-design/issues/2827 review Boxed border rendering logic
300
+ export const boxedBorder = style({
301
+ '::before': {
302
+ content: '',
303
+ position: 'absolute',
304
+ inset: 0,
305
+ boxSizing: 'border-box',
306
+ border: `1px solid ${skinVars.colors.border}`,
307
+ // The container owns the radius (see `boxed`), and the edge follows it.
308
+ borderRadius: 'inherit',
309
+ pointerEvents: 'none',
310
+ // Above the background of both columns, the sticky scroll dividers of the body and the header,
311
+ // and below the vertical dividers, which cross it (see `verticalDividerOverlay`).
312
+ zIndex: 3,
313
+ },
314
+ });
315
+
316
+ // Header region ---------------------------------------------------------------
317
+
318
+ // The 24px inset above the logo belongs to the header, so the header band reaches the top edge of the
319
+ // sidenav in every variant.
320
+ // The 32px gap separates the collapse action from the header slot, and the collapsed rail keeps it: the
321
+ // spec gives one value for both states.
322
+ export const headerBase = style({
323
+ display: 'flex',
324
+ flexDirection: 'column',
325
+ alignItems: 'center',
326
+ gap: 24,
327
+ flexShrink: 0,
328
+ paddingTop: 24,
329
+ // Above the background of the body and above the painted scroll spacer, which follow it. Without a
330
+ // header slot, the collapse control ends the header, and its focus ring draws a few pixels below it,
331
+ // over the body: the body background, or the band of the spacer while the user scrolls, would
332
+ // otherwise cover that part of the ring. Below the boxed edge (zIndex 3) and the vertical dividers
333
+ // (zIndex 4).
334
+ position: 'relative',
335
+ zIndex: 2,
336
+ });
337
+
338
+ // The logo and the collapse control stack, both 32px tall. Their left edge is placed with
339
+ // explicit padding rather than by centering, so that it stays at 20px in both states
340
+ // regardless of the right divider border and of whether the consumer loads css/reset.css.
341
+ export const headerControls = style({
342
+ boxSizing: 'border-box',
343
+ display: 'flex',
344
+ flexDirection: 'column',
345
+ alignItems: 'flex-start',
346
+ gap: 8,
347
+ width: '100%',
348
+ paddingLeft: 20,
349
+ paddingRight: 24,
350
+ });
351
+
352
+ // The collapsed rail keeps the same left padding, and it keeps `flex-start` too. Centring the controls
353
+ // gives the same result at rest, because the rail leaves the logo exactly its 32px, but it moves them
354
+ // while the rail moves: a centre travels with the box that holds it, and a left edge does not.
355
+ export const headerControlsCollapsed = style({
356
+ paddingRight: 20,
357
+ });
358
+
359
+ // The default isotype is a square as wide as its height in both states. The collapsed rail still clamps
360
+ // the width, because a logo of the consumer, or the function form of the prop, can be wider than the rail.
361
+ // The spec fades the label of the header 50ms after the rail starts to move. Our default header carries no
362
+ // label, because the default logo is the isotype in both states, so what this rule gives is the smooth
363
+ // clamp of the width, and a smooth fade for a consumer that drives the opacity of its own logo.
364
+ export const logo = style({
365
+ display: 'flex',
366
+ alignItems: 'center',
367
+ flexShrink: 0,
368
+ // The spot grows with a logo of the consumer that is taller than the default isotype. The minimum
369
+ // keeps the 32px band of the spec, so the header rhythm does not change with the default logo.
370
+ height: 'auto',
371
+ minHeight: LOGO_SIZE,
372
+ // The clamp below is a `max-width`, and not a `width`, so that it interpolates: `auto` has no value to
373
+ // animate from.
374
+ maxWidth: '100%',
375
+ // A logo of the consumer that is larger than this box is clipped, so it never paints over the
376
+ // controls of the header or past the edge of the collapsed rail.
377
+ overflow: 'hidden',
378
+ transition: `max-width ${collapseDurationVar} ${COLLAPSE_EASING}, opacity ${collapseDurationVar} ${COLLAPSE_EASING} 50ms`,
379
+ ...reducedMotion,
380
+ });
381
+
382
+ // The child keeps its own width while the clamp narrows the box. A flex item shrinks to its minimum
383
+ // otherwise, and a text inside it then re-wraps letter by letter, which makes the spot grow with every
384
+ // line. This way the edge of the box cuts the child, which stands still (see `itemLabelFrozenWidth`).
385
+ globalStyle(`${logo} > *`, {
386
+ flexShrink: 0,
387
+ });
388
+
389
+ // The svg of the default logo draws a few pixels taller than the size that it receives, and the amount
390
+ // depends on the skin. The default spot holds the 32px of the spec, so the header keeps its rhythm in
391
+ // every skin.
392
+ export const logoDefault = style({
393
+ height: LOGO_SIZE,
394
+ });
395
+
396
+ export const logoCollapsed = style({
397
+ maxWidth: LOGO_SIZE,
398
+ });
399
+
400
+ // The slot follows the same rule as the logo above. It never rests at opacity 0, because the collapsed
401
+ // rail keeps the slot: the fade serves a consumer that drives the opacity of its own header content.
402
+ // The padding travels with the rail, so the slot never snaps to its collapsed inset while the rail moves.
403
+ export const headerSlot = style({
404
+ boxSizing: 'border-box',
405
+ width: '100%',
406
+ minWidth: 0,
407
+ paddingLeft: SLOT_INSET_X,
408
+ paddingRight: SLOT_INSET_X,
409
+ transition: `opacity ${collapseDurationVar} ${COLLAPSE_EASING} 50ms, padding ${collapseDurationVar} ${COLLAPSE_EASING}`,
410
+ ...reducedMotion,
411
+ });
412
+
413
+ export const headerSlotCollapsed = style({
414
+ paddingLeft: COLLAPSED_SLOT_INSET_X,
415
+ paddingRight: COLLAPSED_SLOT_INSET_X,
416
+ });
417
+
418
+ // Body region -----------------------------------------------------------------
419
+
420
+ // The body scrolls up and down, never sideways. The rule below is not the default: a box that scrolls on
421
+ // one axis takes `auto` on the other one as well, and the title of a section, which keeps the width of its
422
+ // text while the sidenav moves, would then give the collapsed rail a horizontal scrollbar.
423
+ export const bodyBase = style({
424
+ flex: 1,
425
+ minHeight: 0,
426
+ overflowX: 'hidden',
427
+ overflowY: 'auto',
428
+ display: 'flex',
429
+ flexDirection: 'column',
430
+ position: 'relative',
431
+ // When the keyboard moves the focus to a row outside of the view, the browser scrolls that row just
432
+ // to the edge of the scrollport. At the top, that edge sits under the painted spacer, which would
433
+ // cover the top of the focus ring. The scroll padding makes the browser leave the spacer and the
434
+ // ring their room. `FOCUS_RING_ROOM` is the room of the ring alone, top and bottom.
435
+ scrollPaddingTop: HEADER_SCROLL_SPACER_HEIGHT + FOCUS_RING_ROOM,
436
+ scrollPaddingBottom: FOCUS_RING_ROOM,
437
+ });
438
+
439
+ // The inset between the header and the first row lives inside the scrollport, as this sticky
440
+ // spacer, and not as a padding of the header or of the body. A padding of the header sits outside the
441
+ // scrollport, and the seam clips the focus ring of the first row; a padding of the body sits inside it,
442
+ // and the rows stay visible under the header while the user scrolls. The spacer gives both behaviours:
443
+ // transparent at rest, it leaves the ring its room, and while the content scrolls it paints the
444
+ // background of the body over the rows that pass beneath, with the divider on its bottom edge. It is
445
+ // always in the flow, so nothing jumps on the scroll threshold: only its paint changes.
446
+ // The flex places the line of the spacer on its outer edge: the last child lands on the bottom edge of
447
+ // the header spacer, and the first child on the top edge of the footer spacer. An absolutely positioned
448
+ // line is not an option: it does not anchor to the sticky box reliably, and it lands at the bottom of
449
+ // the scroll content instead.
450
+ const scrollSpacerBase = {
451
+ flexShrink: 0,
452
+ position: 'sticky',
453
+ zIndex: 1,
454
+ pointerEvents: 'none',
455
+ display: 'flex',
456
+ flexDirection: 'column',
457
+ } as const;
458
+
459
+ export const headerScrollSpacer = style({
460
+ ...scrollSpacerBase,
461
+ height: HEADER_SCROLL_SPACER_HEIGHT,
462
+ top: 0,
463
+ justifyContent: 'flex-end',
464
+ });
465
+
466
+ // The mirror of `headerScrollSpacer` for a fixed footer, which sits outside of the scrollport like the
467
+ // header does. The band covers the rows that pass beneath it toward the footer. It is shorter than the
468
+ // header spacer, because it carries the top inset of the footer, which the spec makes smaller.
469
+ export const footerScrollSpacer = style({
470
+ ...scrollSpacerBase,
471
+ height: FOOTER_PADDING_TOP,
472
+ bottom: 0,
473
+ });
474
+
475
+ // The line of a spacer. It stops 1px before the right edge, so it never crosses the vertical divider
476
+ // that sits there (see the comment of `scrollDivider` below), and a boxed sidenav insets it on the left
477
+ // (see the `boxed` rule below).
478
+ export const scrollSpacerDivider = style({
479
+ height: 1,
480
+ marginRight: 1,
481
+ });
482
+
483
+ // A keyboard-focused row must stop clear of the band of the fixed footer: the height of the band plus the
484
+ // room of the ring, like `scrollPaddingTop` above. The inline footer keeps the `FOCUS_RING_ROOM` of
485
+ // `bodyBase`, because it scrolls with the content and needs no band.
486
+ export const bodyWithFixedFooter = style({
487
+ scrollPaddingBottom: FOOTER_PADDING_TOP + FOCUS_RING_ROOM,
488
+ });
489
+
490
+ // List of first-level entries (sections and stand-alone items). Every entry owns `ENTRY_SPACE_Y` above and
491
+ // below itself, whatever its kind: the gap carries the two spaces that meet between two neighbours, and the
492
+ // padding carries the space of the first entry and of the last one. The space lives on this list, so the
493
+ // scroll sentinels and the footer, which are its siblings, stay untouched.
494
+ export const bodyContent = style({
495
+ display: 'flex',
496
+ flexDirection: 'column',
497
+ gap: ENTRY_SPACE_Y * 2,
498
+ paddingTop: ENTRY_SPACE_Y,
499
+ paddingBottom: ENTRY_SPACE_Y,
500
+ });
501
+
502
+ // Scroll-intersection divider of the footer (appears when content scrolls past the footer).
503
+ // It stops 1px before the right edge, so it never crosses the vertical divider that sits there (the right
504
+ // divider, or the separator of the double panel). The divider token is translucent in dark mode, so two
505
+ // lines that overlap paint a brighter pixel at the crossing. The gap is invisible when no vertical divider
506
+ // is there, because the right edge of the sidenav is transparent then. A boxed sidenav also insets it on
507
+ // the left (see the `boxed` rule below), where its edge draws a border too.
508
+ export const scrollDivider = style({
509
+ height: 1,
510
+ flexShrink: 0,
511
+ pointerEvents: 'none',
512
+ position: 'sticky',
513
+ zIndex: 1,
514
+ marginRight: 1,
515
+ });
516
+
517
+ export const footerScrollDivider = style({
518
+ bottom: 0,
519
+ });
520
+
521
+ export const scrollDividerVariant = styleVariants(dividerColor, (color) => ({backgroundColor: color}));
522
+
523
+ // Footer region ---------------------------------------------------------------
524
+
525
+ // The horizontal padding travels with the rail, like the one of `headerSlot`: the two slots keep the same
526
+ // two edges through the whole movement, and neither of them snaps to its collapsed inset.
527
+ export const footerBase = style({
528
+ flexShrink: 0,
529
+ paddingTop: FOOTER_PADDING_TOP,
530
+ paddingBottom: FOOTER_PADDING_BOTTOM,
531
+ paddingLeft: SLOT_INSET_X,
532
+ paddingRight: SLOT_INSET_X,
533
+ transition: `padding ${collapseDurationVar} ${COLLAPSE_EASING}`,
534
+ ...reducedMotion,
535
+ });
536
+
537
+ export const footerCollapsed = style({
538
+ paddingLeft: COLLAPSED_SLOT_INSET_X,
539
+ paddingRight: COLLAPSED_SLOT_INSET_X,
540
+ });
541
+
542
+ // A fixed footer hands its top inset to `footerScrollSpacer`, which owns that space inside the
543
+ // scrollport, so the focus ring of the last row has room to draw. The footer content does not move: it
544
+ // anchors to the bottom, and only the boundary of its band shifts. The stacking mirrors `headerBase`:
545
+ // a control on the top edge of the footer slot draws its ring a few pixels above the footer, and the
546
+ // painted band would cover that part of the ring otherwise.
547
+ export const footerFixed = style({
548
+ paddingTop: 0,
549
+ position: 'relative',
550
+ zIndex: 2,
551
+ });
552
+
553
+ // Section ---------------------------------------------------------------------
554
+
555
+ // No vertical padding here: a section owns no space of its own. Its dividers own the space that faces the
556
+ // items (see `sectionDividerTop`), and the body list owns the space between the entries.
557
+ export const section = style({
558
+ display: 'flex',
559
+ flexDirection: 'column',
560
+ });
561
+
562
+ // The box of the title closes while the rail narrows, so the items move up with it. A grid row goes from
563
+ // `1fr` to `0fr` with a transition, which a height in `auto` cannot do (the same pattern as the panel of the
564
+ // Accordion). The CI Chromium predates that interpolation and snaps the row, which its screenshots accept.
565
+ // The text fades apart from the fold, so the fade shows instead of the clip of the row: it fades out over
566
+ // the first half of a collapse, before the row cuts it, and it fades in over the second half of an
567
+ // expansion, once the row has room for it. A transition runs with the timing of the state that it goes
568
+ // to, so this rule times the expansion and `sectionTitleCollapsed` times the collapse.
569
+ const TITLE_FADE_DURATION = `calc(${collapseDurationVar} / 2)`;
570
+
571
+ export const sectionTitle = style({
572
+ display: 'grid',
573
+ gridTemplateRows: '1fr',
574
+ marginBottom: 8,
575
+ transition: `grid-template-rows ${collapseDurationVar} ${COLLAPSE_EASING}, margin-bottom ${collapseDurationVar} ${COLLAPSE_EASING}, opacity ${TITLE_FADE_DURATION} ${COLLAPSE_EASING} ${TITLE_FADE_DURATION}`,
576
+ ...reducedMotion,
577
+ });
578
+
579
+ // The row of the grid clips its content, so the text disappears with the row and never paints over the
580
+ // items while the row closes.
581
+ export const sectionTitleContent = style({
582
+ minHeight: 0,
583
+ overflow: 'hidden',
584
+ padding: `0 ${SECTION_TITLE_INSET}px`,
585
+ });
586
+
587
+ // The title text inherits this colour (see the `color="inherit"` of its `Text3`), so every title of the
588
+ // sidenav takes its token from one place.
589
+ export const sectionTitleVariant = styleVariants(sectionTitleColor, (color) => ({color}));
590
+
591
+ // Collapsed: the title gives its space back, so the first item of a section moves up to where the title
592
+ // stood. The element stays in the document, out of the reading order with `aria-hidden`, because the
593
+ // list of the section takes its name from it (see `sidenav-bar-section.tsx`). No `visibility: hidden`: a
594
+ // box without height takes no click, and jsdom would drop the name of the list with it.
595
+ export const sectionTitleCollapsed = style({
596
+ gridTemplateRows: '0fr',
597
+ marginBottom: 0,
598
+ opacity: 0,
599
+ transition: `grid-template-rows ${collapseDurationVar} ${COLLAPSE_EASING}, margin-bottom ${collapseDurationVar} ${COLLAPSE_EASING}, opacity ${TITLE_FADE_DURATION} ${COLLAPSE_EASING}`,
600
+ ...reducedMotion,
601
+ });
602
+
603
+ // A title that the consumer hides (`title={{text, hidden: true}}`) never paints, in any state, and it
604
+ // takes no space. It stays in the document because the list of the section takes its name from it, as in
605
+ // the collapsed state above. No `display: none`: that drops the element from the accessibility tree, and
606
+ // the name of the list would go with it.
607
+ export const sectionTitleHidden = style({
608
+ gridTemplateRows: '0fr',
609
+ marginBottom: 0,
610
+ opacity: 0,
611
+ transition: 'none',
612
+ });
613
+
614
+ // While the sidenav moves, the title keeps the width that it had at rest (an inline `width`, see
615
+ // `useRestWidth`), for the same reason as the label of an item (see `itemLabelFrozenWidth`). Without
616
+ // this, the title would wrap over several lines as the rail narrows, and the whole body of the sidenav
617
+ // would move down with it. A title with no width at rest yet takes the width of its text on one line.
618
+ export const sectionTitleKeepsWidth = style({
619
+ width: 'max-content',
620
+ });
621
+
622
+ // The rail that carries the items of a section. A first-level stand-alone item reuses it, so that
623
+ // it lands on the same rail as the items that belong to a section (see `standaloneItem`).
624
+ // The left inset hosts the selected indicator, and the row of each item adds `ITEM_ROW_INSET` on top of
625
+ // it, which gives the 18px that the spec measures from the edge of the sidenav to the row.
626
+ export const sectionContent = style({
627
+ display: 'flex',
628
+ flexDirection: 'column',
629
+ paddingLeft: RAIL_INSET,
630
+ paddingRight: RAIL_INSET,
631
+ });
632
+
633
+ // A stand-alone item is not wrapped in a section, so it carries the items rail itself. It is a class of
634
+ // its own, so that a selector can tell it from the rail inside a section.
635
+ export const standaloneItem = style([sectionContent]);
636
+
637
+ // The dividers sit outside `sectionContent`, on the edges of the section. The anatomy of a section reads,
638
+ // top to bottom: top divider, 16px, title, 8px, items, 16px, bottom divider. Each divider carries its 16px
639
+ // as a margin on the side of the items only. The outward side is the edge of the entry, and the body list
640
+ // keeps every entry 16px from its neighbour there, so a line reads 16px on each side, shared or not. The
641
+ // collapsed rail keeps the same distances, because the title closes without a trace. The horizontal margin
642
+ // also keeps the line off the vertical divider on the right edge, for the same reason as `scrollDivider`
643
+ // above.
644
+ const sectionDividerBase = style({
645
+ marginLeft: SECTION_DIVIDER_MARGIN_X,
646
+ marginRight: SECTION_DIVIDER_MARGIN_X,
647
+ });
648
+
649
+ export const sectionDividerTop = style([sectionDividerBase, {marginBottom: SECTION_DIVIDER_MARGIN_Y}]);
650
+ export const sectionDividerBottom = style([sectionDividerBase, {marginTop: SECTION_DIVIDER_MARGIN_Y}]);
651
+
652
+ // A boxed sidenav draws a border on its left edge too (see `boxedBorder`), so the scroll dividers keep off
653
+ // that edge as well. A non-boxed sidenav has no divider on the left, so the lines reach that edge. A section
654
+ // divider needs no rule here: its 8px margin already clears both edges.
655
+ globalStyle(`${boxed} ${scrollDivider}, ${boxed} ${scrollSpacerDivider}`, {
656
+ marginLeft: 1,
657
+ });
658
+
659
+ // Item ------------------------------------------------------------------------
660
+
661
+ export const itemRow = style({
662
+ position: 'relative',
663
+ display: 'flex',
664
+ alignItems: 'center',
665
+ gap: 6,
666
+ });
667
+
668
+ // The row of an item takes the same box in both states: `ITEM_ROW_INSET` on each side of the items rail.
669
+ // Its width is a percentage of the rail, so it follows the rail while the rail moves, and it needs no
670
+ // transition of its own. The collapsed rail leaves it 36px, which holds the icon and its two paddings.
671
+ // The overflow keeps the label, the right slot and the chevron inside the row while it narrows.
672
+ // The height is a minimum, and not a fixed number: the spec asks for a label that wraps over several
673
+ // lines instead of one that truncates, and the row grows with it. A row that holds a single line keeps the
674
+ // 44px of the spec, because `ITEM_ROW_PADDING_Y` leaves that line the room that it needs: one line of
675
+ // `Text2` measures 24px on the widest skin, and 44px hold it with the two paddings.
676
+ export const itemTouchable = style({
677
+ boxSizing: 'border-box',
678
+ display: 'flex',
679
+ alignItems: 'center',
680
+ gap: ITEM_ROW_GAP,
681
+ flex: 'none',
682
+ width: `calc(100% - ${ITEM_ROW_INSET * 2}px)`,
683
+ minWidth: 0,
684
+ minHeight: ITEM_ROW_HEIGHT,
685
+ padding: `${ITEM_ROW_PADDING_Y}px 8px`,
686
+ marginLeft: ITEM_ROW_INSET,
687
+ marginRight: ITEM_ROW_INSET,
688
+ borderRadius: 8,
689
+ backgroundColor: 'transparent',
690
+ overflow: 'hidden',
691
+ });
692
+
693
+ // The label inherits the `color` of the row (see the `color="inherit"` of its `Text2`). The asset inherits it
694
+ // too (the spec paints it with `currentColor`), while the chevron overrides it with its own token (see
695
+ // `itemChevronVariant`).
696
+ export const itemTouchableVariant = styleVariants(itemColors, (colors) => ({
697
+ color: colors.label,
698
+ selectors: {
699
+ '&:hover': {backgroundColor: colors.hover},
700
+ '&:focus-visible': {backgroundColor: colors.hover},
701
+ '&:active': {backgroundColor: colors.pressed},
702
+ },
703
+ }));
704
+
705
+ // The collapsed rail keeps the box of the row untouched, so that the row never moves between the two
706
+ // states. The 36px that the rail leaves hold the icon and its two paddings exactly, which places the icon
707
+ // at the centre of the rail. The label and the gap that precedes it overflow that box, and the row clips
708
+ // them, so the icon keeps its place from the first frame of the movement to the last one.
709
+ export const itemTouchableCollapsed = style({
710
+ border: 'none',
711
+ lineHeight: 1,
712
+ textDecoration: 'none',
713
+ });
714
+
715
+ // It follows `itemTouchableVariant` in this file on purpose: both rules have the same specificity, so the
716
+ // selected background wins over the resting one by source order.
717
+ export const itemTouchableSelected = styleVariants(itemColors, (colors) => ({
718
+ backgroundColor: colors.selected,
719
+ selectors: {
720
+ '&:hover': {backgroundColor: colors.selectedHover},
721
+ '&:focus-visible': {backgroundColor: colors.selectedHover},
722
+ '&:active': {backgroundColor: colors.selectedPressed},
723
+ },
724
+ }));
725
+
726
+ // The accent stays on the collapsed rail: a selected first-level item keeps its bar in both states. Only
727
+ // a parent whose descendant is selected marks the selection with the background alone, because the bar
728
+ // belongs to the selected child (see `showAccent` in `sidenav-bar-first-level-item.tsx`).
729
+ export const itemAccent = style({
730
+ position: 'absolute',
731
+ left: 0,
732
+ top: '50%',
733
+ transform: 'translateY(-50%)',
734
+ width: 2,
735
+ height: 20,
736
+ borderRadius: 8,
737
+ pointerEvents: 'none',
738
+ });
739
+
740
+ export const itemAccentVariant = styleVariants(itemColors, (colors) => ({
741
+ backgroundColor: colors.indicator,
742
+ }));
743
+
744
+ export const itemAsset = style({
745
+ display: 'flex',
746
+ flexShrink: 0,
747
+ width: 20,
748
+ height: 20,
749
+ });
750
+
751
+ export const itemAssetVariant = styleVariants(itemColors, (colors) => ({color: colors.asset}));
752
+
753
+ // The label keeps its box in the DOM on the collapsed rail, so a screen reader still reads it, and so the
754
+ // fade of the spec has something to fade. Its own box needs no width animation: it grows and shrinks with
755
+ // the row that holds it, because it takes the space that the row leaves.
756
+ // The box is a grid row that folds from `1fr` to the height of one line while the rail collapses, the same
757
+ // pattern as the section title: a label that wraps over several lines then shrinks its row with the rail,
758
+ // instead of making it jump to one line at the first frame. The CI Chromium snaps that row (see
759
+ // `sectionTitle`).
760
+ export const itemLabel = style({
761
+ flex: 1,
762
+ minWidth: 0,
763
+ display: 'grid',
764
+ gridTemplateRows: '1fr',
765
+ transition: `grid-template-rows ${collapseDurationVar} ${COLLAPSE_EASING}, opacity ${collapseDurationVar} ${COLLAPSE_EASING}`,
766
+ ...reducedMotion,
767
+ });
768
+
769
+ // The folded row stops at one line of text, which is what a row of 44px holds, so a label of one line
770
+ // never changes its box. The clip hides the lines below the first one while the row folds.
771
+ export const itemLabelContent = style({
772
+ minHeight: skinVars.textPresets.text2.lineHeight,
773
+ overflow: 'hidden',
774
+ });
775
+
776
+ // The label keeps its place beside the icon, so the text stands still while it fades. A margin or a width
777
+ // of its own would drag the text toward the icon instead.
778
+ export const itemLabelCollapsed = style({
779
+ gridTemplateRows: '0fr',
780
+ opacity: 0,
781
+ });
782
+
783
+ // While the sidenav moves, the label keeps the width that it had at rest (an inline `width`, see
784
+ // `useRestWidth`), instead of taking the share of the row that the flex layout would give it. The row
785
+ // narrows under a text that does not move, and the edge of the sidenav passes over that text: without
786
+ // this, the label would wrap over more and more lines as the rail narrows, and every row of the body would
787
+ // grow and then shrink again. The expanded sidenav at rest drops this rule, so a label longer than the
788
+ // row wraps there, which is what the spec asks for.
789
+ export const itemLabelFrozenWidth = style({
790
+ flex: 'none',
791
+ });
792
+
793
+ // Fallback for a label with no width at rest yet (a sidenav that mounted collapsed): the width that its
794
+ // text asks for, on one line. The label then wraps when the rail settles, which is one jump at the end.
795
+ export const itemLabelKeepsWidth = style({
796
+ minWidth: 'max-content',
797
+ });
798
+
799
+ // The right slot and the chevron stay in the DOM on the collapsed rail and fade with the label of their
800
+ // item, so that nothing of the row pops while the rail moves. The `visibility` step ends with the fade,
801
+ // which takes the slot out of the accessibility tree and the tab order once the rail stopped.
802
+ export const itemRightSlot = style({
803
+ display: 'flex',
804
+ alignItems: 'center',
805
+ flexShrink: 0,
806
+ transition: `opacity ${collapseDurationVar} ${COLLAPSE_EASING}, visibility ${collapseDurationVar} ${COLLAPSE_EASING}`,
807
+ ...reducedMotion,
808
+ });
809
+
810
+ export const itemRightSlotCollapsed = style({
811
+ opacity: 0,
812
+ visibility: 'hidden',
813
+ });
814
+
815
+ export const itemChevron = style({
816
+ display: 'flex',
817
+ alignItems: 'center',
818
+ flexShrink: 0,
819
+ width: 16,
820
+ height: 16,
821
+ transition: `transform ${contentDurationVar} ${CONTENT_EASING}, opacity ${collapseDurationVar} ${COLLAPSE_EASING}, visibility ${collapseDurationVar} ${COLLAPSE_EASING}`,
822
+ ...reducedMotion,
823
+ });
824
+
825
+ export const itemChevronCollapsed = style({
826
+ opacity: 0,
827
+ visibility: 'hidden',
828
+ });
829
+
830
+ // The chevron of an open parent item turns half a turn counterclockwise, the same direction as the chevron
831
+ // of `Accordion` (see `icons/icon-chevron.tsx`), so that it reports the state of its group. It applies to
832
+ // the chevron that points down, which the sidenav uses for a group that opens in place. The double panel
833
+ // keeps the chevron that points right, and never turns it: half a turn would make it point away from the
834
+ // column that it opens.
835
+ export const itemChevronRotated = style({
836
+ transform: 'rotate(-180deg)',
837
+ });
838
+
839
+ export const itemChevronVariant = styleVariants(itemColors, (colors) => ({color: colors.chevron}));
840
+
841
+ // The children of a parent item grow and shrink as one group. A grid row of `0fr` collapses the group
842
+ // without a measured height, which is the pattern that `Accordion` uses (see `accordion.css.ts`).
843
+ export const accordionContainer = style({
844
+ display: 'grid',
845
+ });
846
+
847
+ // The group also fades while it folds: the fold clips its rows, and a selected row would otherwise leave
848
+ // at full opacity, with its accent and its background.
849
+ export const accordionTransitionClasses = {
850
+ enter: style({
851
+ gridTemplateRows: '0fr',
852
+ opacity: 0,
853
+ }),
854
+ enterActive: style({
855
+ gridTemplateRows: '1fr',
856
+ opacity: 1,
857
+ transition: `grid-template-rows ${contentDurationVar} ${CONTENT_EASING}, opacity ${contentDurationVar} ${CONTENT_EASING}`,
858
+ ...reducedMotion,
859
+ }),
860
+ exit: style({
861
+ gridTemplateRows: '1fr',
862
+ opacity: 1,
863
+ }),
864
+ exitActive: style({
865
+ gridTemplateRows: '0fr',
866
+ opacity: 0,
867
+ transition: `grid-template-rows ${contentDurationVar} ${CONTENT_EASING}, opacity ${contentDurationVar} ${CONTENT_EASING}`,
868
+ ...reducedMotion,
869
+ }),
870
+ };
871
+
872
+ export const accordion = style({
873
+ display: 'flex',
874
+ flexDirection: 'column',
875
+ });
876
+
877
+ // accordionContainer display: grid ← the only grid; its row animates 0fr ↔ 1fr
878
+ // └─ accordion flex column ← clips its rows while the track moves
879
+ // └─ accordionRows flex column, role="list"
880
+ // └─ item rows
881
+ // the selection would be clipped (borders) when not animating. this fixes it.
882
+ globalStyle(
883
+ `:is(${accordionTransitionClasses.enter}, ${accordionTransitionClasses.enterActive}, ${accordionTransitionClasses.exit}, ${accordionTransitionClasses.exitActive}) > ${accordion}`,
884
+ {overflow: 'hidden'}
885
+ );
886
+
887
+ // One node carries one role, so the group of the children and the list of their rows are two nodes. This
888
+ // one repeats the column of the group above it, and the rows keep the box that they had.
889
+ export const accordionRows = style({
890
+ display: 'flex',
891
+ flexDirection: 'column',
892
+ });
893
+
894
+ // The rows of a panel list the children at the edge, like a first-level row, so only the accordion
895
+ // rows take the indent.
896
+ globalStyle(`${accordionRows} ${itemRow}`, {
897
+ paddingLeft: SECOND_LEVEL_INDENT,
898
+ });
899
+
900
+ // Panel (the dialog panel and the second column) -------------------------------
901
+
902
+ // The rows of a panel, under the group that names it. It repeats the column of that group, for the
903
+ // same reason as `accordionRows`.
904
+ export const panelRows = style({
905
+ display: 'flex',
906
+ flexDirection: 'column',
907
+ });
908
+
909
+ export const dialogPanel = style({
910
+ display: 'flex',
911
+ flexDirection: 'column',
912
+ backgroundColor: skinVars.colors.backgroundContainer,
913
+ borderRadius: skinVars.borderRadii.popup,
914
+ border: `1px solid ${skinVars.colors.border}`,
915
+ minWidth: DEFAULT_WIDTH,
916
+ maxHeight: '70vh',
917
+ overflowY: 'auto',
918
+ paddingTop: DIALOG_PANEL_PADDING_Y,
919
+ paddingBottom: DIALOG_PANEL_PADDING_Y,
920
+ paddingLeft: DIALOG_PANEL_INSET,
921
+ paddingRight: DIALOG_PANEL_INSET,
922
+ boxShadow: '0px 4px 12px rgba(0,0,0,0.15)',
923
+ position: 'relative',
924
+ zIndex: 1001,
925
+ });
926
+
927
+ // The inset of the panel plus this padding place the title where a section title stands, at
928
+ // `SECTION_TITLE_INSET` from the edge of the panel, on the rail of the content of the items below it.
929
+ export const dialogPanelTitle = style({
930
+ paddingBottom: 8,
931
+ paddingLeft: SECTION_TITLE_INSET - DIALOG_PANEL_INSET,
932
+ paddingRight: SECTION_TITLE_INSET - DIALOG_PANEL_INSET,
933
+ });
934
+
935
+ // The second column of the sidenav. It holds the children of the open parent item, spans the whole
936
+ // height of the sidenav, and scrolls on its own. Its horizontal inset (8px) is the same as the items
937
+ // rail of a section, so the children land on the same rail as the items of the main column.
938
+ export const doublePanelColumn = style({
939
+ boxSizing: 'border-box',
940
+ display: 'flex',
941
+ flexDirection: 'column',
942
+ // The content hangs from the right edge of the column, so it slides out from under the main column
943
+ // while the column opens, and slides back under it while the column closes. Anchored to the left edge,
944
+ // the content stood still and the edge wiped it instead, in one direction only: on opening, the focus
945
+ // of the first item scrolled the narrow column, which dragged the content by accident.
946
+ alignItems: 'flex-end',
947
+ width: sidenavPanelWidthVar,
948
+ height: '100%',
949
+ flexShrink: 0,
950
+ // The column only clips. The content scrolls (see `doublePanelContent`), so a classic scrollbar
951
+ // takes its room inside the content instead of pushing the content, which hangs from the right edge,
952
+ // out of the left edge of the column.
953
+ overflow: 'hidden',
954
+ });
955
+
956
+ // The column slides out of the main column and slides back into it, with the movement of the rail. Its
957
+ // children keep the width of the open column while it moves, so the text never reflows: the column clips
958
+ // them instead (see the `overflow` above, and `doublePanelContent` below).
959
+ const doublePanelClosed = style({
960
+ width: 0,
961
+ });
962
+
963
+ const doublePanelOpening = style({
964
+ width: sidenavPanelWidthVar,
965
+ transition: `width ${collapseDurationVar} ${COLLAPSE_EASING}`,
966
+ ...reducedMotion,
967
+ });
968
+
969
+ // The first column that a sidenav opens arrives with the item that owns it, so it enters the tree while it
970
+ // is already open. `appear` gives that first column the same movement as every later one.
971
+ export const doublePanelTransitionClasses = {
972
+ appear: doublePanelClosed,
973
+ appearActive: doublePanelOpening,
974
+ enter: doublePanelClosed,
975
+ enterActive: doublePanelOpening,
976
+ exit: style({
977
+ width: sidenavPanelWidthVar,
978
+ }),
979
+ exitActive: style({
980
+ width: 0,
981
+ transition: `width ${collapseDurationVar} ${COLLAPSE_EASING}`,
982
+ ...reducedMotion,
983
+ }),
984
+ };
985
+
986
+ // The paddings of the column belong to this box, so the column itself can reach a width of zero. Its
987
+ // horizontal inset is the inset of the items rail, so the children of the column land on the same rail as
988
+ // the items of the main column. It scrolls up and down on its own, never sideways.
989
+ export const doublePanelContent = style({
990
+ boxSizing: 'border-box',
991
+ display: 'flex',
992
+ flexDirection: 'column',
993
+ width: sidenavPanelWidthVar,
994
+ height: '100%',
995
+ flexShrink: 0,
996
+ overflowX: 'hidden',
997
+ overflowY: 'auto',
998
+ paddingTop: 24,
999
+ paddingBottom: 24,
1000
+ paddingLeft: RAIL_INSET,
1001
+ paddingRight: RAIL_INSET,
1002
+ });
1003
+
1004
+ // The inset of the column plus this padding place the title where a section title stands, at
1005
+ // `SECTION_TITLE_INSET` from the edge of the column. The 16px bottom margin is the title-to-items gap of
1006
+ // the spec.
1007
+ export const doublePanelTitle = style({
1008
+ padding: `0 ${SECTION_TITLE_INSET - RAIL_INSET}px`,
1009
+ marginBottom: 16,
1010
+ });
1011
+
1012
+ // Separates the main column from the double panel column. It renders whenever the panel is open, even
1013
+ // when the sidenav hides its right divider, because the two columns always need a visible boundary.
1014
+ // It is an overlay too (see `verticalDividerOverlay`), so the items of the main column keep the same
1015
+ // width when the panel opens.
1016
+ export const columnSeparator = styleVariants(dividerColor, (color) => ({
1017
+ '::after': {...verticalDividerOverlay, backgroundColor: color},
1018
+ }));