@telefonica/mistica 17.2.0 → 17.4.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 (347) hide show
  1. package/css/blau.css +30 -16
  2. package/css/community/cyber.css +1491 -0
  3. package/css/esimflag.css +41 -18
  4. package/css/mistica-common.css +6 -0
  5. package/css/mistica.css +1 -1
  6. package/css/movistar.css +35 -18
  7. package/css/o2.css +32 -18
  8. package/css/telefonica.css +44 -18
  9. package/css/vivo-evolution.css +72 -20
  10. package/css/vivo.css +32 -18
  11. package/dist/accordion.css-mistica.js +10 -10
  12. package/dist/align.css-mistica.js +1 -1
  13. package/dist/autocomplete.css-mistica.js +4 -4
  14. package/dist/avatar.css-mistica.js +1 -1
  15. package/dist/badge.css-mistica.js +1 -1
  16. package/dist/box.css-mistica.js +13 -13
  17. package/dist/boxed.css-mistica.js +24 -24
  18. package/dist/boxed.d.ts +9 -0
  19. package/dist/boxed.js +18 -15
  20. package/dist/button-group.css-mistica.js +1 -1
  21. package/dist/button-layout.css-mistica.js +19 -19
  22. package/dist/button.css-mistica.js +50 -50
  23. package/dist/callout.css-mistica.js +13 -13
  24. package/dist/card-internal.css-mistica.js +22 -22
  25. package/dist/carousel.css-mistica.js +30 -30
  26. package/dist/checkbox.css-mistica.js +15 -15
  27. package/dist/chip.css-mistica.js +18 -18
  28. package/dist/circle.css-mistica.js +2 -2
  29. package/dist/community/advanced-data-card.css-mistica.js +19 -19
  30. package/dist/community/ai-card.css-mistica.js +9 -9
  31. package/dist/community/blocks.css-mistica.js +3 -3
  32. package/dist/community/cyber/example-component.css-mistica.js +1 -1
  33. package/dist/community/example-component.css-mistica.js +1 -1
  34. package/dist/community/skins/cyber-skin.d.ts +5 -0
  35. package/dist/community/skins/cyber-skin.js +289 -256
  36. package/dist/counter.css-mistica.js +6 -6
  37. package/dist/cover-hero.css-mistica.js +7 -7
  38. package/dist/credit-card-number-field.css-mistica.js +3 -3
  39. package/dist/date-field.css-mistica.js +1 -1
  40. package/dist/date-time-picker.css-mistica.js +1 -1
  41. package/dist/dialog.css-mistica.js +10 -10
  42. package/dist/divider.css-mistica.js +5 -5
  43. package/dist/double-field.css-mistica.js +2 -2
  44. package/dist/drawer.css-mistica.js +4 -4
  45. package/dist/empty-state-card.css-mistica.js +1 -1
  46. package/dist/empty-state.css-mistica.js +8 -8
  47. package/dist/fade-in.css-mistica.js +1 -1
  48. package/dist/feedback.css-mistica.js +5 -5
  49. package/dist/file-upload.css-mistica.js +10 -10
  50. package/dist/fixed-footer-layout.css-mistica.js +6 -6
  51. package/dist/form.css-mistica.js +1 -1
  52. package/dist/generated/mistica-icons/icon-panel-collapse-regular.js +165 -0
  53. package/dist/generated/mistica-icons/icon-panel-expand-regular.js +159 -0
  54. package/dist/grid-layout.css-mistica.js +3 -3
  55. package/dist/grid.css-mistica.js +120 -120
  56. package/dist/header.css-mistica.js +1 -1
  57. package/dist/hero.css-mistica.js +4 -4
  58. package/dist/horizontal-scroll.css-mistica.js +1 -1
  59. package/dist/icon-button.css-mistica.js +53 -53
  60. package/dist/icons/icon-chevron.css-mistica.js +2 -2
  61. package/dist/icons/icon-error.css-mistica.js +1 -1
  62. package/dist/image.css-mistica.js +8 -8
  63. package/dist/index.d.ts +5 -0
  64. package/dist/index.js +10 -1
  65. package/dist/inline.css-mistica.js +11 -11
  66. package/dist/list.css-mistica.js +40 -28
  67. package/dist/list.css.d.ts +2 -0
  68. package/dist/list.d.ts +3 -1
  69. package/dist/list.js +176 -165
  70. package/dist/loading-bar.css-mistica.js +1 -1
  71. package/dist/loading-screen.css-mistica.js +12 -12
  72. package/dist/logo-movistar.js +1 -1
  73. package/dist/logo.css-mistica.js +5 -5
  74. package/dist/menu.css-mistica.js +13 -13
  75. package/dist/mobile-navigation-menu.d.ts +26 -0
  76. package/dist/mobile-navigation-menu.js +145 -0
  77. package/dist/mosaic.css-mistica.js +1 -1
  78. package/dist/navigation-bar.css-mistica.js +31 -97
  79. package/dist/navigation-bar.css.d.ts +0 -24
  80. package/dist/navigation-bar.d.ts +3 -38
  81. package/dist/navigation-bar.js +399 -586
  82. package/dist/navigation-breadcrumbs.css-mistica.js +1 -1
  83. package/dist/navigation-shared.css-mistica.js +79 -0
  84. package/dist/navigation-shared.css.d.ts +26 -0
  85. package/dist/navigation-shared.d.ts +66 -0
  86. package/dist/navigation-shared.js +264 -0
  87. package/dist/package-version.js +1 -1
  88. package/dist/pagination.css-mistica.js +22 -22
  89. package/dist/pin-field.css-mistica.js +4 -4
  90. package/dist/popover.css-mistica.js +1 -1
  91. package/dist/portal.d.ts +1 -1
  92. package/dist/progress-bar.css-mistica.js +7 -7
  93. package/dist/radio-button.css-mistica.js +27 -27
  94. package/dist/rating.css-mistica.js +4 -4
  95. package/dist/responsive-layout.css-mistica.js +6 -6
  96. package/dist/screen-reader-only.css-mistica.js +1 -1
  97. package/dist/select.css-mistica.js +21 -21
  98. package/dist/sheet-action-row.css-mistica.js +1 -1
  99. package/dist/sheet-common.css-mistica.js +7 -7
  100. package/dist/sheet-info.css-mistica.js +1 -1
  101. package/dist/sidenav-bar-context.d.ts +25 -0
  102. package/dist/sidenav-bar-context.js +72 -0
  103. package/dist/sidenav-bar-data.d.ts +15 -0
  104. package/dist/sidenav-bar-data.js +38 -0
  105. package/dist/sidenav-bar-first-level-item.d.ts +42 -0
  106. package/dist/sidenav-bar-first-level-item.js +174 -0
  107. package/dist/sidenav-bar-keyboard.d.ts +13 -0
  108. package/dist/sidenav-bar-keyboard.js +314 -0
  109. package/dist/sidenav-bar-layout.css-mistica.js +28 -0
  110. package/dist/sidenav-bar-layout.css.d.ts +5 -0
  111. package/dist/sidenav-bar-layout.d.ts +22 -0
  112. package/dist/sidenav-bar-layout.js +103 -0
  113. package/dist/sidenav-bar-mobile.d.ts +24 -0
  114. package/dist/sidenav-bar-mobile.js +332 -0
  115. package/dist/sidenav-bar-motion.d.ts +32 -0
  116. package/dist/sidenav-bar-motion.js +84 -0
  117. package/dist/sidenav-bar-panel.d.ts +31 -0
  118. package/dist/sidenav-bar-panel.js +208 -0
  119. package/dist/sidenav-bar-row.d.ts +82 -0
  120. package/dist/sidenav-bar-row.js +230 -0
  121. package/dist/sidenav-bar-second-level-item.d.ts +43 -0
  122. package/dist/sidenav-bar-second-level-item.js +89 -0
  123. package/dist/sidenav-bar-section.d.ts +23 -0
  124. package/dist/sidenav-bar-section.js +167 -0
  125. package/dist/sidenav-bar-types.d.ts +192 -0
  126. package/dist/sidenav-bar-types.js +11 -0
  127. package/dist/sidenav-bar.css-mistica.js +325 -0
  128. package/dist/sidenav-bar.css.d.ts +93 -0
  129. package/dist/sidenav-bar.d.ts +102 -0
  130. package/dist/sidenav-bar.js +492 -0
  131. package/dist/skeletons.css-mistica.js +8 -8
  132. package/dist/skins/blau.d.ts +5 -0
  133. package/dist/skins/blau.js +12 -8
  134. package/dist/skins/esimflag.d.ts +5 -0
  135. package/dist/skins/esimflag.js +13 -9
  136. package/dist/skins/movistar.d.ts +5 -0
  137. package/dist/skins/movistar.js +13 -9
  138. package/dist/skins/o2.d.ts +5 -0
  139. package/dist/skins/o2.js +13 -9
  140. package/dist/skins/skin-contract.css-mistica.js +735 -731
  141. package/dist/skins/skin-contract.css.d.ts +16 -12
  142. package/dist/skins/telefonica.d.ts +5 -0
  143. package/dist/skins/telefonica.js +13 -9
  144. package/dist/skins/types/colors.d.ts +13 -6
  145. package/dist/skins/vivo-evolution.d.ts +5 -0
  146. package/dist/skins/vivo-evolution.js +14 -10
  147. package/dist/skins/vivo.d.ts +5 -0
  148. package/dist/skins/vivo.js +13 -9
  149. package/dist/skip-link.css-mistica.js +2 -2
  150. package/dist/slider.css-mistica.js +24 -24
  151. package/dist/snackbar.css-mistica.js +14 -14
  152. package/dist/spinner.css-mistica.js +1 -1
  153. package/dist/square.css-mistica.js +1 -1
  154. package/dist/stack.css-mistica.js +5 -5
  155. package/dist/stacking-group.css-mistica.js +1 -1
  156. package/dist/stepper.css-mistica.js +9 -9
  157. package/dist/switch-component.css-mistica.js +48 -42
  158. package/dist/switch-component.css.d.ts +2 -0
  159. package/dist/switch-component.js +18 -18
  160. package/dist/table.css-mistica.js +9 -9
  161. package/dist/tabs.css-mistica.js +22 -22
  162. package/dist/tag.css-mistica.js +3 -3
  163. package/dist/text-field-base.css-mistica.js +19 -19
  164. package/dist/text-field-components.css-mistica.js +10 -10
  165. package/dist/text-link.css-mistica.js +6 -6
  166. package/dist/text-tokens.d.ts +6 -0
  167. package/dist/text-tokens.js +157 -133
  168. package/dist/text.css-mistica.js +6 -6
  169. package/dist/timeline.css-mistica.js +11 -11
  170. package/dist/timer.css-mistica.js +6 -6
  171. package/dist/tooltip.css-mistica.js +2 -2
  172. package/dist/touchable.css-mistica.js +4 -4
  173. package/dist/utils/aspect-ratio-support.css-mistica.js +2 -2
  174. package/dist/video.css-mistica.js +1 -1
  175. package/dist/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +1 -1
  176. package/dist-es/accordion.css-mistica.js +7 -7
  177. package/dist-es/align.css-mistica.js +1 -1
  178. package/dist-es/autocomplete.css-mistica.js +2 -2
  179. package/dist-es/avatar.css-mistica.js +1 -1
  180. package/dist-es/badge.css-mistica.js +1 -1
  181. package/dist-es/box.css-mistica.js +13 -13
  182. package/dist-es/boxed.css-mistica.js +23 -23
  183. package/dist-es/boxed.js +25 -25
  184. package/dist-es/button-group.css-mistica.js +1 -1
  185. package/dist-es/button-layout.css-mistica.js +16 -16
  186. package/dist-es/button.css-mistica.js +38 -38
  187. package/dist-es/callout.css-mistica.js +12 -12
  188. package/dist-es/card-internal.css-mistica.js +17 -17
  189. package/dist-es/carousel.css-mistica.js +10 -10
  190. package/dist-es/checkbox.css-mistica.js +13 -13
  191. package/dist-es/chip.css-mistica.js +17 -17
  192. package/dist-es/circle.css-mistica.js +2 -2
  193. package/dist-es/community/advanced-data-card.css-mistica.js +7 -7
  194. package/dist-es/community/ai-card.css-mistica.js +3 -3
  195. package/dist-es/community/blocks.css-mistica.js +2 -2
  196. package/dist-es/community/cyber/example-component.css-mistica.js +1 -1
  197. package/dist-es/community/example-component.css-mistica.js +1 -1
  198. package/dist-es/community/skins/cyber-skin.js +289 -256
  199. package/dist-es/counter.css-mistica.js +2 -2
  200. package/dist-es/cover-hero.css-mistica.js +4 -4
  201. package/dist-es/credit-card-number-field.css-mistica.js +3 -3
  202. package/dist-es/date-field.css-mistica.js +1 -1
  203. package/dist-es/date-time-picker.css-mistica.js +1 -1
  204. package/dist-es/dialog.css-mistica.js +5 -5
  205. package/dist-es/divider.css-mistica.js +5 -5
  206. package/dist-es/double-field.css-mistica.js +2 -2
  207. package/dist-es/drawer.css-mistica.js +2 -2
  208. package/dist-es/empty-state-card.css-mistica.js +1 -1
  209. package/dist-es/empty-state.css-mistica.js +7 -7
  210. package/dist-es/fade-in.css-mistica.js +1 -1
  211. package/dist-es/feedback.css-mistica.js +2 -2
  212. package/dist-es/file-upload.css-mistica.js +8 -8
  213. package/dist-es/fixed-footer-layout.css-mistica.js +3 -3
  214. package/dist-es/form.css-mistica.js +1 -1
  215. package/dist-es/generated/mistica-icons/icon-panel-collapse-regular.js +115 -0
  216. package/dist-es/generated/mistica-icons/icon-panel-expand-regular.js +109 -0
  217. package/dist-es/grid-layout.css-mistica.js +3 -3
  218. package/dist-es/grid.css-mistica.js +120 -120
  219. package/dist-es/header.css-mistica.js +1 -1
  220. package/dist-es/hero.css-mistica.js +3 -3
  221. package/dist-es/horizontal-scroll.css-mistica.js +1 -1
  222. package/dist-es/icon-button.css-mistica.js +53 -53
  223. package/dist-es/icons/icon-chevron.css-mistica.js +2 -2
  224. package/dist-es/icons/icon-error.css-mistica.js +1 -1
  225. package/dist-es/image.css-mistica.js +4 -4
  226. package/dist-es/index.js +2279 -2276
  227. package/dist-es/inline.css-mistica.js +11 -11
  228. package/dist-es/list.css-mistica.js +8 -2
  229. package/dist-es/list.js +275 -264
  230. package/dist-es/loading-bar.css-mistica.js +1 -1
  231. package/dist-es/loading-screen.css-mistica.js +5 -5
  232. package/dist-es/logo-movistar.js +1 -1
  233. package/dist-es/logo.css-mistica.js +5 -5
  234. package/dist-es/menu.css-mistica.js +13 -13
  235. package/dist-es/mobile-navigation-menu.js +90 -0
  236. package/dist-es/mosaic.css-mistica.js +1 -1
  237. package/dist-es/navigation-bar.css-mistica.js +11 -20
  238. package/dist-es/navigation-bar.js +469 -656
  239. package/dist-es/navigation-breadcrumbs.css-mistica.js +1 -1
  240. package/dist-es/navigation-shared.css-mistica.js +11 -0
  241. package/dist-es/navigation-shared.js +192 -0
  242. package/dist-es/package-version.js +1 -1
  243. package/dist-es/pagination.css-mistica.js +19 -19
  244. package/dist-es/pin-field.css-mistica.js +2 -2
  245. package/dist-es/popover.css-mistica.js +1 -1
  246. package/dist-es/progress-bar.css-mistica.js +7 -7
  247. package/dist-es/radio-button.css-mistica.js +22 -22
  248. package/dist-es/rating.css-mistica.js +3 -3
  249. package/dist-es/responsive-layout.css-mistica.js +6 -6
  250. package/dist-es/screen-reader-only.css-mistica.js +1 -1
  251. package/dist-es/select.css-mistica.js +18 -18
  252. package/dist-es/sheet-action-row.css-mistica.js +1 -1
  253. package/dist-es/sheet-common.css-mistica.js +2 -2
  254. package/dist-es/sheet-info.css-mistica.js +1 -1
  255. package/dist-es/sidenav-bar-context.js +14 -0
  256. package/dist-es/sidenav-bar-data.js +12 -0
  257. package/dist-es/sidenav-bar-first-level-item.js +124 -0
  258. package/dist-es/sidenav-bar-keyboard.js +253 -0
  259. package/dist-es/sidenav-bar-layout.css-mistica.js +2 -0
  260. package/dist-es/sidenav-bar-layout.js +86 -0
  261. package/dist-es/sidenav-bar-mobile.js +277 -0
  262. package/dist-es/sidenav-bar-motion.js +26 -0
  263. package/dist-es/sidenav-bar-panel.js +146 -0
  264. package/dist-es/sidenav-bar-row.js +208 -0
  265. package/dist-es/sidenav-bar-second-level-item.js +72 -0
  266. package/dist-es/sidenav-bar-section.js +112 -0
  267. package/dist-es/sidenav-bar-types.js +2 -0
  268. package/dist-es/sidenav-bar.css-mistica.js +74 -0
  269. package/dist-es/sidenav-bar.js +429 -0
  270. package/dist-es/skeletons.css-mistica.js +7 -7
  271. package/dist-es/skins/blau.js +12 -8
  272. package/dist-es/skins/esimflag.js +13 -9
  273. package/dist-es/skins/movistar.js +13 -9
  274. package/dist-es/skins/o2.js +13 -9
  275. package/dist-es/skins/skin-contract.css-mistica.js +735 -731
  276. package/dist-es/skins/telefonica.js +13 -9
  277. package/dist-es/skins/vivo-evolution.js +14 -10
  278. package/dist-es/skins/vivo.js +13 -9
  279. package/dist-es/skip-link.css-mistica.js +2 -2
  280. package/dist-es/slider.css-mistica.js +20 -20
  281. package/dist-es/snackbar.css-mistica.js +5 -5
  282. package/dist-es/spinner.css-mistica.js +1 -1
  283. package/dist-es/square.css-mistica.js +1 -1
  284. package/dist-es/stack.css-mistica.js +5 -5
  285. package/dist-es/stacking-group.css-mistica.js +1 -1
  286. package/dist-es/stepper.css-mistica.js +3 -3
  287. package/dist-es/style.css +1 -1
  288. package/dist-es/switch-component.css-mistica.js +37 -37
  289. package/dist-es/switch-component.js +26 -26
  290. package/dist-es/table.css-mistica.js +9 -9
  291. package/dist-es/tabs.css-mistica.js +19 -19
  292. package/dist-es/tag.css-mistica.js +2 -2
  293. package/dist-es/text-field-base.css-mistica.js +17 -17
  294. package/dist-es/text-field-components.css-mistica.js +4 -4
  295. package/dist-es/text-link.css-mistica.js +6 -6
  296. package/dist-es/text-tokens.js +82 -67
  297. package/dist-es/text.css-mistica.js +6 -6
  298. package/dist-es/timeline.css-mistica.js +10 -10
  299. package/dist-es/timer.css-mistica.js +6 -6
  300. package/dist-es/tooltip.css-mistica.js +2 -2
  301. package/dist-es/touchable.css-mistica.js +2 -2
  302. package/dist-es/utils/aspect-ratio-support.css-mistica.js +2 -2
  303. package/dist-es/video.css-mistica.js +1 -1
  304. package/dist-es/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +1 -1
  305. package/package.json +3 -2
  306. package/src/boxed.css.ts +1 -0
  307. package/src/boxed.tsx +18 -5
  308. package/src/callout.css.ts +4 -2
  309. package/src/community/skins/cyber-skin.tsx +127 -439
  310. package/src/index.tsx +14 -0
  311. package/src/list.css.ts +36 -1
  312. package/src/list.tsx +370 -344
  313. package/src/logo-movistar.tsx +1 -1
  314. package/src/mobile-navigation-menu.tsx +168 -0
  315. package/src/navigation-bar.css.ts +2 -267
  316. package/src/navigation-bar.tsx +77 -370
  317. package/src/navigation-shared.css.ts +289 -0
  318. package/src/navigation-shared.tsx +262 -0
  319. package/src/package-version.tsx +1 -1
  320. package/src/portal.tsx +1 -1
  321. package/src/sidenav-bar-context.tsx +41 -0
  322. package/src/sidenav-bar-data.ts +49 -0
  323. package/src/sidenav-bar-first-level-item.tsx +203 -0
  324. package/src/sidenav-bar-keyboard.tsx +393 -0
  325. package/src/sidenav-bar-layout.css.ts +89 -0
  326. package/src/sidenav-bar-layout.tsx +61 -0
  327. package/src/sidenav-bar-mobile.tsx +302 -0
  328. package/src/sidenav-bar-motion.tsx +70 -0
  329. package/src/sidenav-bar-panel.tsx +269 -0
  330. package/src/sidenav-bar-row.tsx +272 -0
  331. package/src/sidenav-bar-second-level-item.tsx +99 -0
  332. package/src/sidenav-bar-section.tsx +98 -0
  333. package/src/sidenav-bar-types.ts +224 -0
  334. package/src/sidenav-bar.css.ts +1018 -0
  335. package/src/sidenav-bar.tsx +821 -0
  336. package/src/skins/blau.tsx +18 -8
  337. package/src/skins/esimflag.tsx +19 -9
  338. package/src/skins/movistar.tsx +19 -9
  339. package/src/skins/o2.tsx +19 -9
  340. package/src/skins/skin-contract.css.ts +2 -0
  341. package/src/skins/telefonica.tsx +19 -9
  342. package/src/skins/types/colors.tsx +14 -6
  343. package/src/skins/vivo-evolution.tsx +20 -10
  344. package/src/skins/vivo.tsx +19 -9
  345. package/src/switch-component.css.ts +20 -0
  346. package/src/switch-component.tsx +9 -1
  347. package/src/text-tokens.tsx +24 -0
@@ -0,0 +1,289 @@
1
+ import {style, styleVariants} from '@vanilla-extract/css';
2
+ import {sprinkles} from './sprinkles.css';
3
+ import {NAVBAR_HEIGHT_DESKTOP, NAVBAR_HEIGHT_MOBILE} from './theme';
4
+ import * as mq from './media-queries.css';
5
+ import {vars} from './skins/skin-contract.css';
6
+
7
+ /*
8
+ * Styles of the parts that every navigation surface shares: the header of a bar, the content of that
9
+ * header, the burger icon, the panel that the burger opens, and the spacer of a fixed bar. `NavigationBar`,
10
+ * `MainNavigationBar`, `FunnelNavigationBar` and `SidenavBar` all read them, so a change here reaches the
11
+ * four of them.
12
+ *
13
+ * The styles of the desktop menu of `MainNavigationBar` stay in `navigation-bar.css.ts`, because that menu
14
+ * belongs to that component alone.
15
+ */
16
+
17
+ export const NAVBAR_ZINDEX = 25;
18
+
19
+ export const BURGER_MENU_ANIMATION_DURATION_MS = 300;
20
+
21
+ const borderWidth = 1;
22
+
23
+ // Header ----------------------------------------------------------------------
24
+
25
+ export const topFixed = style([
26
+ sprinkles({
27
+ position: 'fixed',
28
+ top: 0,
29
+ left: 0,
30
+ right: 0,
31
+ }),
32
+ {
33
+ zIndex: NAVBAR_ZINDEX,
34
+ },
35
+ ]);
36
+
37
+ const navbarBase = style([
38
+ sprinkles({
39
+ display: 'flex',
40
+ alignItems: 'center',
41
+ width: '100%',
42
+ }),
43
+ {
44
+ borderWidth,
45
+ borderBottomStyle: 'solid',
46
+
47
+ '@media': {
48
+ [mq.tabletOrSmaller]: {
49
+ transition: 'border-color 300ms',
50
+ },
51
+ },
52
+ },
53
+ ]);
54
+
55
+ export const navbarBorderColorVariants = styleVariants({
56
+ default: [navbarBase, {borderColor: vars.colors.divider}],
57
+ noBorder: [navbarBase, {borderColor: 'transparent'}],
58
+ menuOpen: [
59
+ navbarBase,
60
+ {
61
+ borderColor: vars.colors.divider,
62
+
63
+ '@media': {
64
+ [mq.tabletOrSmaller]: {
65
+ borderColor: 'transparent',
66
+ },
67
+ },
68
+ },
69
+ ],
70
+ });
71
+
72
+ export const navigationBarContent = style([
73
+ sprinkles({
74
+ alignItems: 'center',
75
+ width: '100%',
76
+ display: 'flex',
77
+ }),
78
+ {
79
+ height: NAVBAR_HEIGHT_DESKTOP,
80
+ '@media': {
81
+ [mq.tabletOrSmaller]: {
82
+ height: NAVBAR_HEIGHT_MOBILE - borderWidth,
83
+ },
84
+ [mq.desktopOrBigger]: {
85
+ ':last-child': {
86
+ height: NAVBAR_HEIGHT_DESKTOP - borderWidth,
87
+ },
88
+ },
89
+ },
90
+ },
91
+ ]);
92
+
93
+ export const navigationBarContentRight = style([
94
+ sprinkles({
95
+ display: 'flex',
96
+ alignItems: 'center',
97
+ justifyContent: 'flex-end',
98
+ }),
99
+ {
100
+ height: NAVBAR_HEIGHT_DESKTOP,
101
+ '@media': {
102
+ [mq.tabletOrSmaller]: {
103
+ paddingLeft: 24,
104
+ flex: 1,
105
+ height: NAVBAR_HEIGHT_MOBILE - borderWidth,
106
+ },
107
+ [mq.desktopOrBigger]: {
108
+ ':last-child': {
109
+ height: NAVBAR_HEIGHT_DESKTOP - borderWidth,
110
+ },
111
+ },
112
+ },
113
+ },
114
+ ]);
115
+
116
+ export const navigationBarContentRightExpanded = style([
117
+ navigationBarContentRight,
118
+ sprinkles({
119
+ flex: 1,
120
+ }),
121
+ {
122
+ paddingLeft: 56,
123
+ },
124
+ ]);
125
+
126
+ export const desktopOnly = style({
127
+ '@media': {
128
+ [mq.tabletOrSmaller]: {
129
+ display: 'none',
130
+ },
131
+ },
132
+ });
133
+
134
+ export const logoContainer = style([
135
+ sprinkles({
136
+ display: 'flex',
137
+ justifyContent: 'center',
138
+ }),
139
+ {
140
+ '@media': {
141
+ [mq.tabletOrSmaller]: {
142
+ marginRight: 0,
143
+ },
144
+ },
145
+ },
146
+ ]);
147
+
148
+ // The spacer keeps the content of the page below a bar that is fixed to the top of the viewport.
149
+ export const spacerMobile = style({
150
+ '@media': {
151
+ [mq.tabletOrSmaller]: {
152
+ height: NAVBAR_HEIGHT_MOBILE,
153
+ },
154
+ },
155
+ });
156
+
157
+ export const spacer = style([
158
+ sprinkles({
159
+ height: NAVBAR_HEIGHT_DESKTOP,
160
+ }),
161
+ spacerMobile,
162
+ ]);
163
+
164
+ // Burger icon -----------------------------------------------------------------
165
+
166
+ export const burgerIconContainer = style([
167
+ sprinkles({
168
+ position: 'relative',
169
+ width: 24,
170
+ height: 24,
171
+ }),
172
+ {
173
+ verticalAlign: 'middle',
174
+ borderRadius: 50,
175
+ },
176
+ ]);
177
+
178
+ const iconBase = style([
179
+ sprinkles({
180
+ position: 'absolute',
181
+ }),
182
+ {
183
+ top: 0,
184
+ left: 0,
185
+ transition: 'transform 300ms, opacity 100ms',
186
+ },
187
+ ]);
188
+
189
+ export const iconCloseOpen = style([
190
+ iconBase,
191
+ {
192
+ opacity: 1,
193
+ transform: 'rotate(0) scale(1)',
194
+ },
195
+ ]);
196
+
197
+ export const iconCloseHidden = style([
198
+ iconBase,
199
+ {
200
+ opacity: 0,
201
+ transform: 'rotate(-45deg) scale(0.9)',
202
+ },
203
+ ]);
204
+
205
+ export const iconMenuOpen = style([
206
+ iconBase,
207
+ {
208
+ opacity: 1,
209
+ transform: 'scale(1)',
210
+ },
211
+ ]);
212
+
213
+ export const iconMenuHidden = style([
214
+ iconBase,
215
+ {
216
+ opacity: 0,
217
+ transform: 'scale(0.7)',
218
+ },
219
+ ]);
220
+
221
+ export const burgerMenuButton = style({
222
+ marginRight: 24,
223
+ width: 'fit-content',
224
+ '@media': {
225
+ [mq.desktopOrBigger]: {
226
+ display: 'none',
227
+ },
228
+ },
229
+ });
230
+
231
+ // Burger menu panel -----------------------------------------------------------
232
+
233
+ export const burgerMenu = sprinkles({
234
+ position: 'fixed',
235
+ left: 0,
236
+ right: 0,
237
+ bottom: 0,
238
+ background: vars.colors.background,
239
+ });
240
+
241
+ export const burgerMenuContainer = sprinkles({
242
+ height: '100%',
243
+ position: 'relative',
244
+ });
245
+
246
+ export const burgerMenuContentContainer = style([
247
+ sprinkles({
248
+ overflowY: 'auto',
249
+ width: '100%',
250
+ height: '100%',
251
+ position: 'absolute',
252
+ top: 0,
253
+ }),
254
+ {
255
+ transition: `transform ${BURGER_MENU_ANIMATION_DURATION_MS}ms ease-out`,
256
+ '@media': {
257
+ ['(prefers-reduced-motion)']: {
258
+ transition: 'none',
259
+ },
260
+ },
261
+ },
262
+ ]);
263
+
264
+ export const burgerMenuTransition = {
265
+ enter: style({
266
+ transform: 'translate(-100vw)',
267
+ }),
268
+ enterActive: style({
269
+ transform: 'translate(0)',
270
+ transition: `transform ${BURGER_MENU_ANIMATION_DURATION_MS}ms ease-out`,
271
+ '@media': {
272
+ ['(prefers-reduced-motion)']: {
273
+ transition: 'none',
274
+ },
275
+ },
276
+ }),
277
+ exit: style({
278
+ transform: 'translate(0)',
279
+ }),
280
+ exitActive: style({
281
+ transform: 'translate(-100vw)',
282
+ transition: `transform ${BURGER_MENU_ANIMATION_DURATION_MS}ms ease-out`,
283
+ '@media': {
284
+ ['(prefers-reduced-motion)']: {
285
+ transition: 'none',
286
+ },
287
+ },
288
+ }),
289
+ };
@@ -0,0 +1,262 @@
1
+ 'use client';
2
+ import * as React from 'react';
3
+ import classnames from 'classnames';
4
+ import ResponsiveLayout from './responsive-layout';
5
+ import Inline from './inline';
6
+ import Box from './box';
7
+ import {Text3} from './text';
8
+ import {IconButton} from './icon-button';
9
+ import IconMenuRegular from './generated/mistica-icons/icon-menu-regular';
10
+ import IconCloseRegular from './generated/mistica-icons/icon-close-regular';
11
+ import IconChevronLeftRegular from './generated/mistica-icons/icon-chevron-left-regular';
12
+ import {ThemeVariant, normalizeVariant} from './theme-variant-context';
13
+ import {useTheme} from './hooks';
14
+ import {vars} from './skins/skin-contract.css';
15
+ import {getPrefixedDataAttributes} from './utils/dom';
16
+ import * as tokens from './text-tokens';
17
+ import * as styles from './navigation-shared.css';
18
+
19
+ import type {BoxProps} from './box';
20
+ import type {NonDeprecatedVariant, Variant} from './theme-variant-context';
21
+ import type {DataAttributes, HeadingType} from './utils/types';
22
+ import type {ExclusifyUnion} from './utils/utility-types';
23
+
24
+ /*
25
+ * The parts that every navigation surface shares. `NavigationBar`, `MainNavigationBar` and
26
+ * `FunnelNavigationBar` build their bars with them, and so does the mobile `SidenavBar`. A change here
27
+ * reaches the four components, so every one of them carries screenshot tests.
28
+ *
29
+ * The desktop menu of `MainNavigationBar` stays in `navigation-bar.tsx`, because that menu belongs to that
30
+ * component alone. The panel of a burger menu lives in `mobile-navigation-menu.tsx`.
31
+ */
32
+
33
+ export const BurgerMenuIcon = ({isOpen}: {isOpen: boolean}): JSX.Element => {
34
+ return (
35
+ <div className={styles.burgerIconContainer} role="presentation" data-testid="BurgerMenuIcon">
36
+ <div className={isOpen ? styles.iconCloseOpen : styles.iconCloseHidden}>
37
+ <IconCloseRegular />
38
+ </div>
39
+ <div className={isOpen ? styles.iconMenuHidden : styles.iconMenuOpen}>
40
+ <IconMenuRegular />
41
+ </div>
42
+ </div>
43
+ );
44
+ };
45
+
46
+ type HeaderProps = {
47
+ children: React.ReactNode;
48
+ topFixed?: boolean;
49
+ variant: NonDeprecatedVariant;
50
+ withBorder?: boolean;
51
+ isBurgerMenuOpen?: boolean;
52
+ dataAttributes?: DataAttributes;
53
+ isBottomRow?: boolean;
54
+ };
55
+
56
+ export const Header = ({
57
+ children,
58
+ topFixed,
59
+ withBorder,
60
+ isBurgerMenuOpen,
61
+ variant,
62
+ dataAttributes,
63
+ }: HeaderProps): JSX.Element => {
64
+ const {isDarkMode} = useTheme();
65
+
66
+ const getBorderClass = () => {
67
+ const isBrandVariant = (variant === 'brand' || variant === 'negative') && !isDarkMode;
68
+ if (isBrandVariant || !withBorder) return styles.navbarBorderColorVariants.noBorder;
69
+ if (isBurgerMenuOpen) return styles.navbarBorderColorVariants.menuOpen;
70
+
71
+ return styles.navbarBorderColorVariants.default;
72
+ };
73
+
74
+ const backgroundColor = {
75
+ default: vars.colors.background,
76
+ brand: vars.colors.navigationBarBackground,
77
+ negative: vars.colors.backgroundNegative,
78
+ alternative: vars.colors.backgroundAlternative,
79
+ media: vars.colors.navigationBarBackground,
80
+ } as const;
81
+
82
+ return (
83
+ <header
84
+ className={classnames(getBorderClass(), {[styles.topFixed]: topFixed})}
85
+ style={{
86
+ background: backgroundColor[variant],
87
+ }}
88
+ {...getPrefixedDataAttributes(dataAttributes)}
89
+ >
90
+ {children}
91
+ </header>
92
+ );
93
+ };
94
+
95
+ type NavigationBarContentContainerProps = {
96
+ right?: React.ReactNode;
97
+ children?: React.ReactNode;
98
+ desktopOnly?: boolean;
99
+ expandRightContent?: boolean;
100
+ };
101
+
102
+ export const NavigationBarContentContainer = React.forwardRef<
103
+ HTMLDivElement,
104
+ NavigationBarContentContainerProps
105
+ >(({right, children, desktopOnly, expandRightContent}, ref) => {
106
+ return (
107
+ <div
108
+ ref={ref}
109
+ className={classnames(styles.navigationBarContent, {[styles.desktopOnly]: desktopOnly})}
110
+ >
111
+ {children}
112
+ {right && (
113
+ <div
114
+ className={
115
+ expandRightContent
116
+ ? styles.navigationBarContentRightExpanded
117
+ : styles.navigationBarContentRight
118
+ }
119
+ >
120
+ {right}
121
+ </div>
122
+ )}
123
+ </div>
124
+ );
125
+ });
126
+
127
+ type WideConfig = {
128
+ paddingX: BoxProps['paddingX'];
129
+ };
130
+
131
+ export const NavigationBarSideMargins = ({
132
+ children,
133
+ wide,
134
+ backgroundColor,
135
+ }: {
136
+ children: React.ReactNode;
137
+ wide: boolean | WideConfig;
138
+ backgroundColor?: string;
139
+ }): JSX.Element => {
140
+ if (!wide) {
141
+ return <ResponsiveLayout backgroundColor={backgroundColor}>{children}</ResponsiveLayout>;
142
+ }
143
+
144
+ const defaultWidePaddingX: BoxProps['paddingX'] = {
145
+ mobile: 16,
146
+ tablet: 24,
147
+ desktop: 24,
148
+ };
149
+
150
+ return (
151
+ <Box
152
+ width="100%"
153
+ paddingX={
154
+ wide === true
155
+ ? defaultWidePaddingX
156
+ : typeof wide.paddingX === 'number'
157
+ ? wide.paddingX
158
+ : {
159
+ ...defaultWidePaddingX,
160
+ ...wide.paddingX,
161
+ }
162
+ }
163
+ background={backgroundColor}
164
+ >
165
+ {children}
166
+ </Box>
167
+ );
168
+ };
169
+
170
+ type InteractiveProps = ExclusifyUnion<{href: string} | {to: string} | {onPress: () => void}>;
171
+
172
+ type MaybeInteractiveProps = ExclusifyUnion<{href?: string} | {to?: string} | {onPress?: () => void}>;
173
+
174
+ interface NavigationBarCommonProps {
175
+ variant?: Variant;
176
+ onBack?: () => void;
177
+ title?: string;
178
+ titleAs?: HeadingType;
179
+ right?: React.ReactElement;
180
+ withBorder?: boolean;
181
+ children?: undefined;
182
+ wide?: boolean | WideConfig;
183
+ }
184
+
185
+ interface NavigationBarTopFixedProps extends NavigationBarCommonProps {
186
+ topFixed?: true;
187
+ }
188
+
189
+ interface NavigationBarNotFixedProps extends NavigationBarCommonProps {
190
+ topFixed: false;
191
+ }
192
+
193
+ type NavigationBarProps = NavigationBarTopFixedProps | NavigationBarNotFixedProps;
194
+
195
+ export const NavigationBar = ({
196
+ onBack,
197
+ title,
198
+ titleAs,
199
+ right,
200
+ variant = 'default',
201
+ topFixed = true,
202
+ withBorder = true,
203
+ wide = false,
204
+ }: NavigationBarProps): JSX.Element => {
205
+ const {texts, t} = useTheme();
206
+ const content = (
207
+ <NavigationBarContentContainer right={right} expandRightContent>
208
+ <Inline space={24} alignItems="center">
209
+ {onBack && (
210
+ <IconButton
211
+ aria-label={texts.backNavigationBar || t(tokens.backNavigationBar)}
212
+ onPress={onBack}
213
+ Icon={IconChevronLeftRegular}
214
+ bleedLeft
215
+ bleedRight
216
+ />
217
+ )}
218
+ <Text3 regular truncate as={titleAs}>
219
+ {title}
220
+ </Text3>
221
+ </Inline>
222
+ </NavigationBarContentContainer>
223
+ );
224
+
225
+ const calcPaddingXWhenNotTopFixed = (): BoxProps['paddingX'] => {
226
+ if (typeof wide !== 'object') {
227
+ return 0;
228
+ }
229
+ return wide.paddingX ?? 0;
230
+ };
231
+
232
+ const normalizedVariant = normalizeVariant(variant);
233
+
234
+ return (
235
+ <ThemeVariant variant={normalizedVariant}>
236
+ <Header
237
+ topFixed={topFixed}
238
+ withBorder={withBorder}
239
+ variant={normalizedVariant}
240
+ dataAttributes={{testid: 'NavigationBar'}}
241
+ >
242
+ {topFixed ? (
243
+ <NavigationBarSideMargins wide={wide}>{content}</NavigationBarSideMargins>
244
+ ) : (
245
+ <Box width="100%" paddingX={calcPaddingXWhenNotTopFixed()}>
246
+ {content}
247
+ </Box>
248
+ )}
249
+ </Header>
250
+ {topFixed && <div className={styles.spacer} />}
251
+ </ThemeVariant>
252
+ );
253
+ };
254
+
255
+ export type {
256
+ HeaderProps,
257
+ NavigationBarContentContainerProps,
258
+ WideConfig,
259
+ NavigationBarProps,
260
+ InteractiveProps,
261
+ MaybeInteractiveProps,
262
+ };
@@ -1,2 +1,2 @@
1
1
  // DO NOT EDIT THIS FILE. It's autogenerated by set-version.js
2
- export const PACKAGE_VERSION = '17.2.0' as string;
2
+ export const PACKAGE_VERSION = '17.4.0' as string;
package/src/portal.tsx CHANGED
@@ -8,7 +8,7 @@ import ReactDOM from 'react-dom';
8
8
  * This is useful for components that need position fixed, for example
9
9
  * for menus, alerts, overlays, etc.
10
10
  *
11
- * See https://reactjs.org/docs/portals.html
11
+ * @see https://react.dev/reference/react-dom/createPortal#usage
12
12
  */
13
13
 
14
14
  type Props = {
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+ import * as React from 'react';
3
+
4
+ import type {SidenavCollapseState} from './sidenav-bar-types';
5
+
6
+ type SidenavBarContextValue = {
7
+ /** Target collapsed state. It flips at the first frame of the motion. */
8
+ collapsed: boolean;
9
+ /** Phase of the collapse motion, for the parts of a row that must wait until the rail rests. */
10
+ collapseState: SidenavCollapseState;
11
+ /** True when every movement of the sidenav takes zero time. See `useIsMotionOff`. */
12
+ isMotionOff: boolean;
13
+ doublePanel: boolean;
14
+ /** The first-level item whose children show in the panel. One panel opens at a time. */
15
+ panelOpenForItemId: string | null;
16
+ setPanelOpenForItemId: (id: string | null) => void;
17
+ /**
18
+ * The press of an item that navigates: it closes the open panel, then it reports the item as the
19
+ * new selection. One call does both, because the selection alone would reopen the second column that
20
+ * the press just closed. The item passes `null` when it has no id.
21
+ */
22
+ selectItemAndClosePanel: (itemId: string | null) => void;
23
+ containerRef: React.RefObject<HTMLElement | null>;
24
+ selectedItemId: string | null;
25
+ };
26
+
27
+ const SidenavBarContext = React.createContext<SidenavBarContextValue>({
28
+ collapsed: false,
29
+ collapseState: 'expanded',
30
+ isMotionOff: false,
31
+ doublePanel: false,
32
+ panelOpenForItemId: null,
33
+ setPanelOpenForItemId: () => {},
34
+ selectItemAndClosePanel: () => {},
35
+ containerRef: React.createRef(),
36
+ selectedItemId: null,
37
+ });
38
+
39
+ const useSidenavBarContext = (): SidenavBarContextValue => React.useContext(SidenavBarContext);
40
+
41
+ export {SidenavBarContext, useSidenavBarContext};
@@ -0,0 +1,49 @@
1
+ import type {
2
+ SidenavEntry,
3
+ SidenavFirstLevelItem,
4
+ SidenavLogo,
5
+ SidenavSection,
6
+ SidenavSectionTitle,
7
+ SidenavSlot,
8
+ SidenavSlotRenderProps,
9
+ } from './sidenav-bar-types';
10
+
11
+ /** Tells a first-level section apart from a first-level stand-alone item. */
12
+ const isSidenavSection = (entry: SidenavEntry): entry is SidenavSection =>
13
+ Array.isArray((entry as SidenavSection).items);
14
+
15
+ /** The items of the first level, in order: the items of every section, and every stand-alone item. */
16
+ const getFirstLevelItems = (entries: ReadonlyArray<SidenavEntry>): Array<SidenavFirstLevelItem> =>
17
+ entries.flatMap((entry) =>
18
+ isSidenavSection(entry) ? [...entry.items] : [entry as SidenavFirstLevelItem]
19
+ );
20
+
21
+ /** Reads the two shapes of a section title as one pair: the text, and the visibility of the heading. */
22
+ const getSidenavSectionTitle = (title: SidenavSectionTitle): {text: string; isHeadingVisible: boolean} =>
23
+ typeof title === 'string'
24
+ ? {text: title, isHeadingVisible: true}
25
+ : {text: title.text, isHeadingVisible: !title.hidden};
26
+
27
+ /** Resolves the function form of a slot with the props of the current state. */
28
+ const renderSidenavSlot = (slot: SidenavSlot, props: SidenavSlotRenderProps): React.ReactNode =>
29
+ typeof slot === 'function' ? slot(props) : slot;
30
+
31
+ /** Resolves the four forms of the logo prop. `defaultLogo` is the logo of the skin, sized by the caller. */
32
+ const renderSidenavLogo = (
33
+ logo: SidenavLogo | undefined,
34
+ props: SidenavSlotRenderProps,
35
+ defaultLogo: React.ReactNode
36
+ ): React.ReactNode => {
37
+ if (logo === false) {
38
+ return null;
39
+ }
40
+ if (typeof logo === 'function') {
41
+ return logo(props);
42
+ }
43
+ if (logo === undefined || logo === true) {
44
+ return defaultLogo;
45
+ }
46
+ return logo;
47
+ };
48
+
49
+ export {isSidenavSection, getFirstLevelItems, getSidenavSectionTitle, renderSidenavSlot, renderSidenavLogo};