@telefonica/mistica 16.55.0 → 16.56.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/README.md +31 -0
  2. package/css/mistica.css +1 -1
  3. package/dist/accordion.css-mistica.js +16 -16
  4. package/dist/align.css-mistica.js +2 -2
  5. package/dist/autocomplete.css-mistica.js +6 -6
  6. package/dist/autocomplete.css.d.ts +1 -0
  7. package/dist/avatar.css-mistica.js +3 -3
  8. package/dist/badge.css-mistica.js +7 -7
  9. package/dist/box.css-mistica.js +15 -15
  10. package/dist/boxed.css-mistica.js +31 -31
  11. package/dist/button-group.css-mistica.js +10 -10
  12. package/dist/button-layout.css-mistica.js +21 -21
  13. package/dist/button.css-mistica.js +51 -51
  14. package/dist/callout.css-mistica.js +16 -16
  15. package/dist/card-internal.css-mistica.js +36 -36
  16. package/dist/carousel.css-mistica.js +18 -18
  17. package/dist/checkbox.css-mistica.js +21 -21
  18. package/dist/chip.css-mistica.js +30 -30
  19. package/dist/circle.css-mistica.js +2 -2
  20. package/dist/community/advanced-data-card.css-mistica.js +26 -26
  21. package/dist/community/blocks.css-mistica.js +3 -3
  22. package/dist/community/example-component.css-mistica.js +2 -2
  23. package/dist/counter.css-mistica.js +12 -12
  24. package/dist/cover-hero.css-mistica.js +16 -16
  25. package/dist/credit-card-number-field.css-mistica.js +6 -6
  26. package/dist/date-field.css-mistica.js +1 -1
  27. package/dist/date-time-picker.css-mistica.js +2 -2
  28. package/dist/dialog.css-mistica.js +15 -15
  29. package/dist/divider.css-mistica.js +5 -5
  30. package/dist/double-field.css-mistica.js +4 -4
  31. package/dist/drawer.css-mistica.js +15 -15
  32. package/dist/empty-state-card.css-mistica.js +4 -4
  33. package/dist/empty-state.css-mistica.js +14 -14
  34. package/dist/fade-in.css-mistica.js +1 -1
  35. package/dist/feedback.css-mistica.js +14 -14
  36. package/dist/file-upload.css-mistica.js +14 -14
  37. package/dist/fixed-footer-layout.css-mistica.js +12 -12
  38. package/dist/form.css-mistica.js +2 -2
  39. package/dist/grid-layout.css-mistica.js +9 -9
  40. package/dist/grid.css-mistica.js +147 -147
  41. package/dist/header.css-mistica.js +5 -5
  42. package/dist/hero.css-mistica.js +11 -11
  43. package/dist/horizontal-scroll.css-mistica.js +3 -3
  44. package/dist/icon-button.css-mistica.js +66 -66
  45. package/dist/icons/icon-chevron.css-mistica.js +6 -6
  46. package/dist/icons/icon-error.css-mistica.js +3 -3
  47. package/dist/image.css-mistica.js +11 -11
  48. package/dist/inline.css-mistica.js +16 -16
  49. package/dist/list.css-mistica.js +15 -15
  50. package/dist/loading-bar.css-mistica.js +5 -5
  51. package/dist/loading-screen.css-mistica.js +15 -15
  52. package/dist/logo-blau-shell.d.ts +10 -0
  53. package/dist/logo-blau-shell.js +25 -0
  54. package/dist/logo-blau.d.ts +1 -1
  55. package/dist/logo-blau.js +25 -40
  56. package/dist/logo-common.d.ts +0 -1
  57. package/dist/logo-esimflag-shell.d.ts +10 -0
  58. package/dist/logo-esimflag-shell.js +25 -0
  59. package/dist/logo-esimflag.d.ts +1 -1
  60. package/dist/logo-esimflag.js +11 -26
  61. package/dist/logo-movistar-new-shell.d.ts +10 -0
  62. package/dist/logo-movistar-new-shell.js +25 -0
  63. package/dist/logo-movistar-new.d.ts +1 -1
  64. package/dist/logo-movistar-new.js +84 -103
  65. package/dist/logo-movistar-shell.d.ts +10 -0
  66. package/dist/logo-movistar-shell.js +25 -0
  67. package/dist/logo-movistar.d.ts +1 -1
  68. package/dist/logo-movistar.js +16 -31
  69. package/dist/logo-o2-new-shell.d.ts +8 -0
  70. package/dist/logo-o2-new-shell.js +24 -0
  71. package/dist/logo-o2-new.d.ts +1 -1
  72. package/dist/logo-o2-new.js +6 -13
  73. package/dist/logo-o2-shell.d.ts +8 -0
  74. package/dist/logo-o2-shell.js +24 -0
  75. package/dist/logo-o2.d.ts +1 -1
  76. package/dist/logo-o2.js +6 -13
  77. package/dist/logo-telefonica-shell.d.ts +10 -0
  78. package/dist/logo-telefonica-shell.js +25 -0
  79. package/dist/logo-telefonica.d.ts +1 -1
  80. package/dist/logo-telefonica.js +11 -26
  81. package/dist/logo-tu-shell.d.ts +8 -0
  82. package/dist/logo-tu-shell.js +24 -0
  83. package/dist/logo-tu.d.ts +1 -1
  84. package/dist/logo-tu.js +10 -14
  85. package/dist/logo-vivo-shell.d.ts +10 -0
  86. package/dist/logo-vivo-shell.js +25 -0
  87. package/dist/logo-vivo.d.ts +1 -1
  88. package/dist/logo-vivo.js +11 -26
  89. package/dist/logo.css-mistica.js +9 -9
  90. package/dist/logo.js +223 -205
  91. package/dist/media-queries.css-mistica.js +13 -13
  92. package/dist/menu.css-mistica.js +24 -24
  93. package/dist/mosaic.css-mistica.js +3 -3
  94. package/dist/navigation-bar.css-mistica.js +45 -45
  95. package/dist/navigation-breadcrumbs.css-mistica.js +5 -5
  96. package/dist/package-version.js +2 -2
  97. package/dist/pin-field.css-mistica.js +10 -10
  98. package/dist/popover.css-mistica.js +2 -2
  99. package/dist/progress-bar.css-mistica.js +12 -12
  100. package/dist/radio-button.css-mistica.js +33 -33
  101. package/dist/rating.css-mistica.js +12 -12
  102. package/dist/responsive-layout.css-mistica.js +20 -20
  103. package/dist/screen-reader-only.css-mistica.js +2 -2
  104. package/dist/select.css-mistica.js +29 -29
  105. package/dist/select.css.d.ts +1 -0
  106. package/dist/sheet-action-row.css-mistica.js +2 -2
  107. package/dist/sheet-common.css-mistica.js +16 -16
  108. package/dist/sheet-info.css-mistica.js +4 -4
  109. package/dist/skeletons.css-mistica.js +12 -12
  110. package/dist/skins/skin-contract.css-mistica.js +686 -686
  111. package/dist/skip-link.css-mistica.js +3 -3
  112. package/dist/slider.css-mistica.js +28 -28
  113. package/dist/snackbar.css-mistica.js +16 -16
  114. package/dist/spinner.css-mistica.js +5 -5
  115. package/dist/square.css-mistica.js +2 -2
  116. package/dist/stack.css-mistica.js +9 -9
  117. package/dist/stacking-group.css-mistica.js +2 -2
  118. package/dist/stepper.css-mistica.js +16 -16
  119. package/dist/switch-component.css-mistica.js +53 -53
  120. package/dist/table.css-mistica.js +24 -24
  121. package/dist/tabs.css-mistica.js +30 -30
  122. package/dist/tag.css-mistica.js +5 -5
  123. package/dist/text-field-base.css-mistica.js +30 -30
  124. package/dist/text-field-base.css.d.ts +1 -0
  125. package/dist/text-field-base.js +52 -51
  126. package/dist/text-field-components.css-mistica.js +20 -17
  127. package/dist/text-field-components.css.d.ts +1 -0
  128. package/dist/text-field-components.d.ts +2 -1
  129. package/dist/text-field-components.js +25 -25
  130. package/dist/text-link.css-mistica.js +10 -10
  131. package/dist/text.css-mistica.js +13 -13
  132. package/dist/theme-context.css-mistica.js +2 -2
  133. package/dist/timeline.css-mistica.js +18 -18
  134. package/dist/timer.css-mistica.js +13 -13
  135. package/dist/tooltip.css-mistica.js +12 -12
  136. package/dist/touchable.css-mistica.js +5 -5
  137. package/dist/utils/aspect-ratio-support.css-mistica.js +7 -7
  138. package/dist/video.css-mistica.js +2 -2
  139. package/dist/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +3 -3
  140. package/dist-es/accordion.css-mistica.js +7 -7
  141. package/dist-es/align.css-mistica.js +2 -2
  142. package/dist-es/autocomplete.css-mistica.js +2 -2
  143. package/dist-es/avatar.css-mistica.js +2 -2
  144. package/dist-es/badge.css-mistica.js +2 -2
  145. package/dist-es/box.css-mistica.js +15 -15
  146. package/dist-es/boxed.css-mistica.js +25 -25
  147. package/dist-es/button-group.css-mistica.js +2 -2
  148. package/dist-es/button-layout.css-mistica.js +16 -16
  149. package/dist-es/button.css-mistica.js +38 -38
  150. package/dist-es/callout.css-mistica.js +12 -12
  151. package/dist-es/card-internal.css-mistica.js +20 -20
  152. package/dist-es/carousel.css-mistica.js +10 -10
  153. package/dist-es/checkbox.css-mistica.js +14 -14
  154. package/dist-es/chip.css-mistica.js +17 -17
  155. package/dist-es/circle.css-mistica.js +2 -2
  156. package/dist-es/community/advanced-data-card.css-mistica.js +7 -7
  157. package/dist-es/community/blocks.css-mistica.js +2 -2
  158. package/dist-es/community/example-component.css-mistica.js +2 -2
  159. package/dist-es/counter.css-mistica.js +2 -2
  160. package/dist-es/cover-hero.css-mistica.js +4 -4
  161. package/dist-es/credit-card-number-field.css-mistica.js +4 -4
  162. package/dist-es/date-field.css-mistica.js +1 -1
  163. package/dist-es/date-time-picker.css-mistica.js +2 -2
  164. package/dist-es/dialog.css-mistica.js +5 -5
  165. package/dist-es/divider.css-mistica.js +5 -5
  166. package/dist-es/double-field.css-mistica.js +4 -4
  167. package/dist-es/drawer.css-mistica.js +2 -2
  168. package/dist-es/empty-state-card.css-mistica.js +2 -2
  169. package/dist-es/empty-state.css-mistica.js +7 -7
  170. package/dist-es/fade-in.css-mistica.js +1 -1
  171. package/dist-es/feedback.css-mistica.js +2 -2
  172. package/dist-es/file-upload.css-mistica.js +8 -8
  173. package/dist-es/fixed-footer-layout.css-mistica.js +4 -4
  174. package/dist-es/form.css-mistica.js +2 -2
  175. package/dist-es/grid-layout.css-mistica.js +4 -4
  176. package/dist-es/grid.css-mistica.js +127 -127
  177. package/dist-es/header.css-mistica.js +2 -2
  178. package/dist-es/hero.css-mistica.js +4 -4
  179. package/dist-es/horizontal-scroll.css-mistica.js +2 -2
  180. package/dist-es/icon-button.css-mistica.js +56 -56
  181. package/dist-es/icons/icon-chevron.css-mistica.js +4 -4
  182. package/dist-es/icons/icon-error.css-mistica.js +2 -2
  183. package/dist-es/image.css-mistica.js +4 -4
  184. package/dist-es/inline.css-mistica.js +10 -10
  185. package/dist-es/list.css-mistica.js +2 -2
  186. package/dist-es/loading-bar.css-mistica.js +2 -2
  187. package/dist-es/loading-screen.css-mistica.js +5 -5
  188. package/dist-es/logo-blau-shell.js +16 -0
  189. package/dist-es/logo-blau.js +36 -51
  190. package/dist-es/logo-esimflag-shell.js +16 -0
  191. package/dist-es/logo-esimflag.js +13 -28
  192. package/dist-es/logo-movistar-new-shell.js +16 -0
  193. package/dist-es/logo-movistar-new.js +86 -105
  194. package/dist-es/logo-movistar-shell.js +16 -0
  195. package/dist-es/logo-movistar.js +18 -33
  196. package/dist-es/logo-o2-new-shell.js +15 -0
  197. package/dist-es/logo-o2-new.js +7 -14
  198. package/dist-es/logo-o2-shell.js +15 -0
  199. package/dist-es/logo-o2.js +7 -14
  200. package/dist-es/logo-telefonica-shell.js +16 -0
  201. package/dist-es/logo-telefonica.js +13 -28
  202. package/dist-es/logo-tu-shell.js +15 -0
  203. package/dist-es/logo-tu.js +12 -16
  204. package/dist-es/logo-vivo-shell.js +16 -0
  205. package/dist-es/logo-vivo.js +13 -28
  206. package/dist-es/logo.css-mistica.js +7 -7
  207. package/dist-es/logo.js +221 -203
  208. package/dist-es/media-queries.css-mistica.js +3 -3
  209. package/dist-es/menu.css-mistica.js +15 -15
  210. package/dist-es/mosaic.css-mistica.js +2 -2
  211. package/dist-es/navigation-bar.css-mistica.js +20 -20
  212. package/dist-es/navigation-breadcrumbs.css-mistica.js +2 -2
  213. package/dist-es/package-version.js +2 -2
  214. package/dist-es/pin-field.css-mistica.js +2 -2
  215. package/dist-es/popover.css-mistica.js +2 -2
  216. package/dist-es/progress-bar.css-mistica.js +8 -8
  217. package/dist-es/radio-button.css-mistica.js +25 -25
  218. package/dist-es/rating.css-mistica.js +4 -4
  219. package/dist-es/responsive-layout.css-mistica.js +7 -7
  220. package/dist-es/screen-reader-only.css-mistica.js +2 -2
  221. package/dist-es/select.css-mistica.js +20 -20
  222. package/dist-es/sheet-action-row.css-mistica.js +2 -2
  223. package/dist-es/sheet-common.css-mistica.js +2 -2
  224. package/dist-es/sheet-info.css-mistica.js +2 -2
  225. package/dist-es/skeletons.css-mistica.js +8 -8
  226. package/dist-es/skins/skin-contract.css-mistica.js +686 -686
  227. package/dist-es/skip-link.css-mistica.js +2 -2
  228. package/dist-es/slider.css-mistica.js +20 -20
  229. package/dist-es/snackbar.css-mistica.js +5 -5
  230. package/dist-es/spinner.css-mistica.js +2 -2
  231. package/dist-es/square.css-mistica.js +2 -2
  232. package/dist-es/stack.css-mistica.js +7 -7
  233. package/dist-es/stacking-group.css-mistica.js +2 -2
  234. package/dist-es/stepper.css-mistica.js +4 -4
  235. package/dist-es/style.css +1 -1
  236. package/dist-es/switch-component.css-mistica.js +41 -41
  237. package/dist-es/table.css-mistica.js +11 -11
  238. package/dist-es/tabs.css-mistica.js +21 -21
  239. package/dist-es/tag.css-mistica.js +2 -2
  240. package/dist-es/text-field-base.css-mistica.js +17 -17
  241. package/dist-es/text-field-base.js +52 -51
  242. package/dist-es/text-field-components.css-mistica.js +4 -4
  243. package/dist-es/text-field-components.js +52 -52
  244. package/dist-es/text-link.css-mistica.js +9 -9
  245. package/dist-es/text.css-mistica.js +8 -8
  246. package/dist-es/theme-context.css-mistica.js +2 -2
  247. package/dist-es/timeline.css-mistica.js +11 -11
  248. package/dist-es/timer.css-mistica.js +7 -7
  249. package/dist-es/tooltip.css-mistica.js +3 -3
  250. package/dist-es/touchable.css-mistica.js +2 -2
  251. package/dist-es/utils/aspect-ratio-support.css-mistica.js +4 -4
  252. package/dist-es/video.css-mistica.js +2 -2
  253. package/dist-es/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +2 -2
  254. package/doc/analytics.md +145 -0
  255. package/doc/components.md +730 -0
  256. package/doc/design-tokens.md +199 -0
  257. package/doc/fonts.md +169 -0
  258. package/doc/forms.md +177 -0
  259. package/doc/images/layout/box.svg +6 -0
  260. package/doc/images/layout/grid-layout-desktop-5-4.svg +8 -0
  261. package/doc/images/layout/grid-layout-desktop-6-6.svg +8 -0
  262. package/doc/images/layout/grid-layout-desktop-8-4.svg +8 -0
  263. package/doc/images/layout/grid-layout-desktop.svg +16 -0
  264. package/doc/images/layout/grid-layout-mobile-5-4.svg +9 -0
  265. package/doc/images/layout/grid-layout-mobile-6-6.svg +9 -0
  266. package/doc/images/layout/grid-layout-mobile-8-4.svg +9 -0
  267. package/doc/images/layout/grid-layout-mobile.svg +5 -0
  268. package/doc/images/layout/grid-layout-tablet-5-4.svg +8 -0
  269. package/doc/images/layout/grid-layout-tablet-6-6.svg +8 -0
  270. package/doc/images/layout/grid-layout-tablet-8-4.svg +8 -0
  271. package/doc/images/layout/grid-layout-tablet.svg +5 -0
  272. package/doc/images/layout/header-layout-desktop.svg +6 -0
  273. package/doc/images/layout/header-layout-mobile.svg +6 -0
  274. package/doc/images/layout/header-layout-tablet.svg +6 -0
  275. package/doc/images/layout/inline-around.svg +6 -0
  276. package/doc/images/layout/inline-between.svg +6 -0
  277. package/doc/images/layout/inline-evenly.svg +6 -0
  278. package/doc/images/layout/inline.svg +6 -0
  279. package/doc/images/layout/master-detail-layout-desktop.svg +8 -0
  280. package/doc/images/layout/master-detail-layout-mobile-detail.svg +6 -0
  281. package/doc/images/layout/master-detail-layout-mobile-master.svg +6 -0
  282. package/doc/images/layout/negative-box-ok-outline.svg +17 -0
  283. package/doc/images/layout/negative-box-ok-preview.svg +11 -0
  284. package/doc/images/layout/negative-box-wrong-outline.svg +14 -0
  285. package/doc/images/layout/negative-box-wrong-preview.svg +11 -0
  286. package/doc/images/layout/responsive-layout-desktop.svg +4 -0
  287. package/doc/images/layout/responsive-layout-mobile.svg +4 -0
  288. package/doc/images/layout/responsive-layout-tablet.svg +4 -0
  289. package/doc/images/layout/stack.svg +8 -0
  290. package/doc/images/layout/vertical-rhythm.png +0 -0
  291. package/doc/layout.md +527 -0
  292. package/doc/llms.md +258 -0
  293. package/doc/lottie.md +17 -0
  294. package/doc/migration-guide.md +76 -0
  295. package/doc/patterns.md +546 -0
  296. package/doc/sheet.md +122 -0
  297. package/doc/testing.md +43 -0
  298. package/doc/texts.md +42 -0
  299. package/doc/theme-config.md +124 -0
  300. package/package.json +4 -4
@@ -0,0 +1,199 @@
1
+ # Design Tokens
2
+
3
+ Mistica uses design tokens via CSS custom properties. All tokens are accessed through the `skinVars` object
4
+ exported from `@telefonica/mistica`. Tokens adapt automatically to the active skin and color scheme
5
+ (light/dark mode).
6
+
7
+ ## Critical rules
8
+
9
+ - **NEVER hardcode colors.** Always use `skinVars.colors.*` for all color values.
10
+ - Use `skinVars.rawColors.*` (not `skinVars.colors.*`) when applying alpha with `applyAlpha`.
11
+ - Use `skinVars.borderRadii.*` for border radius values.
12
+ - Tokens are CSS custom properties at runtime (e.g. `var(--colorBrand)`), so they work in both inline styles
13
+ and CSS.
14
+
15
+ ## Color tokens
16
+
17
+ All colors are accessed via `skinVars.colors.*`. Each token resolves to a CSS custom property.
18
+
19
+ ### Semantic colors
20
+
21
+ | Token | Usage |
22
+ | ----------------------- | -------------------------------------------------------- |
23
+ | `brand` | Primary brand color |
24
+ | `brandHigh` | High-emphasis brand color |
25
+ | `inverse` | Inverse foreground color |
26
+ | `neutralHigh` | High-emphasis neutral (e.g. primary text on default) |
27
+ | `neutralMedium` | Medium-emphasis neutral (e.g. secondary text on default) |
28
+ | `neutralLow` | Low-emphasis neutral |
29
+ | `neutralLowAlternative` | Alternative low-emphasis neutral |
30
+ | `success` | Success semantic color |
31
+ | `warning` | Warning semantic color |
32
+ | `error` | Error semantic color |
33
+ | `promo` | Promotional color |
34
+ | `highlight` | Highlight color |
35
+
36
+ ### Background colors
37
+
38
+ | Token | Usage |
39
+ | -------------------------------- | ----------------------------------- |
40
+ | `background` | Default page background |
41
+ | `backgroundAlternative` | Alternative section background |
42
+ | `backgroundBrand` | Brand-colored background |
43
+ | `backgroundBrandSecondary` | Secondary brand background |
44
+ | `backgroundContainer` | Container/card background |
45
+ | `backgroundContainerBrand` | Container on brand background |
46
+ | `backgroundContainerAlternative` | Container on alternative background |
47
+ | `backgroundOverlay` | Modal/sheet overlay |
48
+ | `backgroundSkeleton` | Skeleton loading placeholder |
49
+ | `appBarBackground` | App bar background |
50
+ | `navigationBarBackground` | Navigation bar background |
51
+
52
+ ### Text colors
53
+
54
+ | Token | Usage |
55
+ | ---------------------- | ------------------------------------------ |
56
+ | `textPrimary` | Primary text on default background |
57
+ | `textPrimaryInverse` | Primary text on brand/inverse background |
58
+ | `textPrimaryBrand` | Primary text on brand background |
59
+ | `textPrimaryMedia` | Primary text on media background |
60
+ | `textSecondary` | Secondary text on default background |
61
+ | `textSecondaryInverse` | Secondary text on brand/inverse background |
62
+ | `textSecondaryBrand` | Secondary text on brand background |
63
+ | `textError` | Error text |
64
+ | `textLink` | Link text color |
65
+ | `textLinkInverse` | Link text on brand/inverse background |
66
+ | `textLinkDanger` | Danger link text color |
67
+
68
+ ### Border colors
69
+
70
+ | Token | Usage |
71
+ | ---------------- | ---------------------- |
72
+ | `borderLow` | Low-emphasis border |
73
+ | `border` | Default border |
74
+ | `borderHigh` | High-emphasis border |
75
+ | `borderSelected` | Selected/active border |
76
+
77
+ ### Status colors (low/high emphasis)
78
+
79
+ | Low emphasis | High emphasis | Usage |
80
+ | ------------ | ------------- | -------------- |
81
+ | `successLow` | `successHigh` | Success status |
82
+ | `warningLow` | `warningHigh` | Warning status |
83
+ | `errorLow` | `errorHigh` | Error status |
84
+ | `promoLow` | `promoHigh` | Promo status |
85
+ | `brandLow` | `brandHigh` | Brand status |
86
+
87
+ ### Control colors
88
+
89
+ | Token | Usage |
90
+ | ------------------ | ----------------------------------------- |
91
+ | `control` | Default control (checkbox, radio, switch) |
92
+ | `controlActivated` | Activated control |
93
+ | `controlError` | Error state control |
94
+ | `loadingBar` | Loading bar color |
95
+ | `divider` | Divider line color |
96
+
97
+ ### Tag colors
98
+
99
+ Tags have paired `tagText*` and `tagBackground*` tokens for each type: `Promo`, `Active`, `Inactive`, `Info`,
100
+ `Success`, `Warning`, `Error`. Each also has `Inverse`, `Negative`, and `Brand` variants.
101
+
102
+ Example: `skinVars.colors.tagTextPromo`, `skinVars.colors.tagBackgroundPromo`.
103
+
104
+ ## Using colors in code
105
+
106
+ ```tsx
107
+ import {skinVars, Text2, Box} from '@telefonica/mistica';
108
+
109
+ // In inline styles
110
+ <div style={{color: skinVars.colors.textPrimary, backgroundColor: skinVars.colors.backgroundContainer}}>
111
+ Content
112
+ </div>
113
+
114
+ // In component color props
115
+ <Text2 regular color={skinVars.colors.textSecondary}>Secondary text</Text2>
116
+
117
+ // Prefer Mistica components over raw divs:
118
+ <Box padding={16}>
119
+ <Text2 regular color={skinVars.colors.textSecondary}>Secondary text</Text2>
120
+ </Box>
121
+ ```
122
+
123
+ ## Applying alpha to colors
124
+
125
+ Use `applyAlpha` with `skinVars.rawColors` (not `skinVars.colors`):
126
+
127
+ ```tsx
128
+ import {applyAlpha, skinVars} from '@telefonica/mistica';
129
+
130
+ // Correct: use rawColors for alpha
131
+ const semiTransparentBrand = applyAlpha(skinVars.rawColors.brand, 0.5);
132
+
133
+ // Wrong: skinVars.colors contains CSS var() references, not raw RGB values
134
+ // applyAlpha(skinVars.colors.brand, 0.5) // Don't do this
135
+ ```
136
+
137
+ ## Border radius tokens
138
+
139
+ Access via `skinVars.borderRadii.*`:
140
+
141
+ | Token | Usage |
142
+ | ------------ | ----------------------- |
143
+ | `container` | Cards, boxed containers |
144
+ | `button` | Buttons |
145
+ | `input` | Form inputs |
146
+ | `popup` | Popups, tooltips |
147
+ | `checkbox` | Checkboxes |
148
+ | `indicator` | Indicators |
149
+ | `chip` | Chips |
150
+ | `sheet` | Bottom sheets |
151
+ | `bar` | Progress bars |
152
+ | `avatar` | Avatars |
153
+ | `mediaSmall` | Small media elements |
154
+ | `tag` | Tags |
155
+
156
+ ```tsx
157
+ // Use in styles when building custom elements (prefer Mistica components instead)
158
+ <div style={{borderRadius: skinVars.borderRadii.container}}>...</div>
159
+ ```
160
+
161
+ ## Text presets
162
+
163
+ Text sizing is handled by text components (`Text1`-`Text10`, `Title1`-`Title4`). Do not manually set font
164
+ sizes -- use the appropriate text component instead.
165
+
166
+ | Component | Weight options | Usage |
167
+ | ---------------- | ------------------------------------ | ---------------------------------- |
168
+ | `Text1`-`Text4` | `light`, `regular`, `medium`, `bold` | Body text with configurable weight |
169
+ | `Text5`-`Text10` | Fixed per skin | Display/headline text |
170
+ | `Title1` | Default weight from skin | Section title |
171
+ | `Title2` | Default weight from skin | Subsection title |
172
+ | `Title3` | Default weight from skin | Card/small title |
173
+ | `Title4` | Default weight from skin | Smallest title |
174
+
175
+ ## ThemeVariant (variant contexts)
176
+
177
+ Some sections of a page use different color contexts. Use `variant` prop on `ResponsiveLayout` or `Boxed`:
178
+
179
+ ```tsx
180
+ // Brand section (colored background)
181
+ <ResponsiveLayout variant="brand">
182
+ <Box paddingY={24}>
183
+ <Text2 regular>Text automatically adapts colors</Text2>
184
+ <ButtonPrimary onPress={() => {}}>Action</ButtonPrimary>
185
+ </Box>
186
+ </ResponsiveLayout>
187
+
188
+ // Alternative section
189
+ <ResponsiveLayout variant="alternative">
190
+ <Box paddingY={24}>
191
+ <Text2 regular>Alternative background section</Text2>
192
+ </Box>
193
+ </ResponsiveLayout>
194
+ ```
195
+
196
+ Available variants: `'default'`, `'brand'`, `'negative'`, `'alternative'`, `'media'`.
197
+
198
+ Components inside a variant section automatically adapt their colors. You do not need to manually set inverse
199
+ colors.
package/doc/fonts.md ADDED
@@ -0,0 +1,169 @@
1
+ # Fonts
2
+
3
+ <!-- TOC -->
4
+
5
+ - [Fonts](#fonts)
6
+ - [Font family](#font-family)
7
+ - [System Fonts (Roboto / San Francisco)](#system-fonts-roboto--san-francisco)
8
+ - [OnAir or Telefonica fonts](#onair-or-telefonica-fonts)
9
+ - [Override brower fonts for some specific html elements](#override-brower-fonts-for-some-specific-html-elements)
10
+ - [Dynamic font sizes](#dynamic-font-sizes)
11
+
12
+ <!-- /TOC -->
13
+
14
+ ## Font family
15
+
16
+ Mistica components are optimized to work with iOS/Android system fonts (Roboto and San Francisco), but it can
17
+ also work fine with other font families.
18
+
19
+ ### System Fonts (Roboto / San Francisco)
20
+
21
+ If you use system fonts in your web application we recommend you to setup it as follows:
22
+
23
+ ```css
24
+ body {
25
+ font-family: -apple-system, 'Roboto', 'Helvetica', 'Arial', sans-serif;
26
+ }
27
+ ```
28
+
29
+ And additionaly declare a Roboto font family for desktop browsers. For example:
30
+
31
+ ```css
32
+ @font-face {
33
+ font-family: 'Roboto';
34
+ font-style: normal;
35
+ font-weight: 300;
36
+ src:
37
+ local('Roboto Light'),
38
+ local('Roboto-Light'),
39
+ url('/static/fonts/roboto-v18-latin_latin-ext-300.woff2') format('woff2');
40
+ }
41
+ @font-face {
42
+ font-family: 'Roboto';
43
+ font-style: normal;
44
+ font-weight: 400;
45
+ src:
46
+ local('Roboto'),
47
+ local('Roboto-Regular'),
48
+ url('/static/fonts/roboto-v18-latin_latin-ext-regular.woff2') format('woff2');
49
+ }
50
+ @font-face {
51
+ font-family: 'Roboto';
52
+ font-style: normal;
53
+ font-weight: 500;
54
+ src:
55
+ local('Roboto Medium'),
56
+ local('Roboto-Medium'),
57
+ url('/static/fonts/roboto-v18-latin_latin-ext-500.woff2') format('woff2');
58
+ }
59
+ @font-face {
60
+ font-family: 'Roboto';
61
+ font-style: normal;
62
+ font-weight: 700;
63
+ src:
64
+ local('Roboto Bold'),
65
+ local('Roboto-Bold'),
66
+ url('/static/fonts/roboto-v18-latin_latin-ext-700.woff2') format('woff2');
67
+ }
68
+ ```
69
+
70
+ This is just an example, you'll need to change the `url()` declarations to point to the fonts served by your
71
+ web server. The important part here is to serve different font weights for 300 (light), 400 (regular), 500
72
+ (medium) and 700 (bold).
73
+
74
+ ### OnAir or Telefonica fonts
75
+
76
+ Mistica works fine too with other fonts like OnAir or Telefonica fonts, but these fonts don't have a medium
77
+ weight (only light, regular and bold). In these cases, we recomend to use the regular font weight for the 500
78
+ `font-weight`. Something like this:
79
+
80
+ ```css
81
+ @font-face {
82
+ font-family: 'OnAir';
83
+ font-style: normal;
84
+ font-weight: 300;
85
+ src: url('/static/fonts/OnAir-Light.woff2') format('woff2');
86
+ }
87
+ @font-face {
88
+ font-family: 'OnAir';
89
+ font-style: normal;
90
+ font-weight: 400;
91
+ src: url('/static/fonts/OnAir-Regular.woff2') format('woff2');
92
+ }
93
+ @font-face {
94
+ font-family: 'OnAir';
95
+ font-style: normal;
96
+ font-weight: 500;
97
+ /* Note we are using OnAir Regular for medium (500) font-weight too: */
98
+ src: url('/static/fonts/OnAir-Regular.woff2') format('woff2');
99
+ }
100
+ @font-face {
101
+ font-family: 'OnAir';
102
+ font-style: normal;
103
+ font-weight: 700;
104
+ src: url('/static/fonts/OnAir-Bold.woff2') format('woff2');
105
+ }
106
+
107
+ body {
108
+ font-family: 'OnAir', 'Helvetica', 'Arial', sans-serif;
109
+ }
110
+ ```
111
+
112
+ ### Override brower fonts for some specific html elements
113
+
114
+ All the html elements in your page will inherit the body font by default, except if a style sheet sets a
115
+ different font family for the element, and most browsers use to set specific font families for some elements
116
+ like `input`, `textarea`, `pre`, etc. If you want to avoid that browser behavior, you have different options:
117
+
118
+ 1. Explicitly set the your font family for those elements:
119
+
120
+ ```css
121
+ body {
122
+ font-family: -apple-system, 'Roboto', 'Helvetica', 'Arial', sans-serif;
123
+ }
124
+
125
+ input,
126
+ textarea,
127
+ pre,
128
+ code {
129
+ font: inherit;
130
+ }
131
+ ```
132
+
133
+ 2. Apply the font-family with a wildcard selector:
134
+
135
+ ```css
136
+ * {
137
+ font-family: -apple-system, 'Roboto', 'Helvetica', 'Arial', sans-serif;
138
+ }
139
+ ```
140
+
141
+ 3. Use a [reset.css](https://meyerweb.com/eric/tools/css/reset/) that does this for you.
142
+
143
+ We use to recomend option 3.
144
+
145
+ ## Dynamic font sizes
146
+
147
+ Mistica components support scalling font sizes automatically based on OS or browser accesibility settings. If
148
+ you want your web to properly work with dynamic font sizes, we recommend to setup a base font size of 16px or
149
+ 100% (which is the same as 16px in most browsers):
150
+
151
+ ```css
152
+ html {
153
+ font-size: 16px; /* or 100% */
154
+ }
155
+ ```
156
+
157
+ Also, to make dynamic font sizes work properly in iOS devices you need to include this:
158
+
159
+ ```css
160
+ /**
161
+ * To enable Dynamic Type in apple devices:
162
+ * See: https://dev.to/colingourlay/how-to-support-apple-s-dynamic-text-in-your-web-content-with-css-40c0
163
+ */
164
+ @supports (font: -apple-system-body) {
165
+ html {
166
+ font: -apple-system-body !important;
167
+ }
168
+ }
169
+ ```
package/doc/forms.md ADDED
@@ -0,0 +1,177 @@
1
+ # Forms
2
+
3
+ <!-- TOC depthFrom:2 -->
4
+
5
+ - [Form example](#form-example)
6
+ - [Important notes](#important-notes)
7
+ - [Form fields](#form-fields)
8
+ - [CreditCardFields](#creditcardfields)
9
+ - [CreditCardNumberField](#creditcardnumberfield)
10
+ - [CreditCardExpirationField](#creditcardexpirationfield)
11
+ - [CvvField](#cvvfield)
12
+ - [DateField](#datefield)
13
+ - [DecimalField](#decimalfield)
14
+ - [IntegerField](#integerfield)
15
+ - [PasswordField](#passwordfield)
16
+ - [EmailField](#emailfield)
17
+ - [Select](#select)
18
+ - [PhoneNumberField](#phonenumberfield)
19
+ - [IbanField](#ibanfield)
20
+ - [DoubleField](#doublefield)
21
+ - [useForm Hook](#useform-hook)
22
+
23
+ <!-- /TOC -->
24
+
25
+ You can build complex forms with automatic state handling using the components provided by this library
26
+
27
+ ## Form example
28
+
29
+ Let's see a quick example to see how it works
30
+
31
+ ```js
32
+ import {Form, TextField, ButtonPrimary} from '@telefonica/mistica';
33
+
34
+ const validateName = (name) => (/^\w+$/.test(name) ? '' : 'bad username');
35
+
36
+ const LoginForm = () => {
37
+ // {user, pass} contains field values for inputs named "user" and "pass"
38
+ const handleSubmit = ({user, pass}) =>
39
+ api.login({user, pass}).then(() => {
40
+ document.location.href = '/home';
41
+ });
42
+
43
+ return (
44
+ <Form onSubmit={handleSubmit}>
45
+ <TextField name="user" label="Username" validate={validateName} />
46
+ <TextField name="pass" label="Password" type="password" />
47
+ <ButtonPrimary submit>Log in</ButtonPrimary>
48
+ </Form>
49
+ );
50
+ };
51
+ ```
52
+
53
+ ### Important notes
54
+
55
+ - Submit button must include the `submit` prop
56
+ - :warning: Submit handler automatically prevents default submit event (calls to `event.preventDefault()`).
57
+ So, for now, you can't use this component to send a `POST` request to `action` attribute URL.
58
+ - Form fields are required by default. If a required field is empty it will be marked as error on submit or
59
+ blur. Add the `optional` prop to mark a field as optional.
60
+ - `Form`'s `onSubmit` prop is a `function` that receives an `object` whose keys are the names of the form
61
+ fields and the values are the values of the form fields. This function must return a promise.
62
+ - When the form is submitting (while the `onSubmit` promise is not resolved or rejected), all fields are
63
+ automatically disabled and a spinner is shown inside submit button.
64
+ - Form fields accept a `validate` prop that can be used to validate field values before submitting. This
65
+ validation is executed on blur or submit. Validation function must return a string with the error message or
66
+ empty string if succeeded.
67
+ - Form optionally accepts an object of `initialValues` e.g. `<Form initialValues={{email: prevEmail}}`
68
+ - You can also use FormField components outside a `<Form>` component but you will lose the magic: automatic
69
+ form validation, disable fields when sending, show spinner on submit button, etc.
70
+
71
+ ## Form fields
72
+
73
+ ### CreditCardFields
74
+
75
+ - Use it if you want to request credit card information
76
+ - This component will render 3 fields:
77
+ - `CreditCardNumberField`
78
+ - `CreditCardExpirationField`
79
+ - `CvvField`
80
+ - When used inside a `<Form>` component, these fields have built-in validations:
81
+ - Simple validation is performed in credit card number
82
+ - CVV length depends on card type
83
+ - Expiration date must be a future date
84
+
85
+ ### CreditCardNumberField
86
+
87
+ - To request a Credit Card number
88
+ - Use `acceptedCards` prop to set accepted cards. By default:
89
+ - `{americanExpress: true, visa: true, masterCard: true}`
90
+ - An icon will hint the card type based on the card number
91
+
92
+ ### CreditCardExpirationField
93
+
94
+ - To request a Credit Card expiration date
95
+ - Format as you write (MM/YY)
96
+
97
+ ### CvvField
98
+
99
+ - To request the Credit Card Verification value
100
+
101
+ ### DateField
102
+
103
+ - To select dates
104
+ - Uses device/browser native date picker
105
+
106
+ ### DecimalField
107
+
108
+ - Shows a numeric keypad in mobile devices
109
+ - Values restricted to decimal values
110
+ - Decimal separator characted (comma or dot) depends on context locale
111
+
112
+ ### IntegerField
113
+
114
+ - Shows a numeric keypad in mobile devices
115
+ - Values restricted to integer values
116
+
117
+ ### PasswordField
118
+
119
+ - Use this field to request a password
120
+ - Includes an "eye" icon to show/hide password
121
+ - Use the `autoComplete` prop to autocomplete to an existing password (`"current-password"`) or request a new
122
+ one (`"new-password"`)
123
+
124
+ ### EmailField
125
+
126
+ - Use this field to request an email address
127
+ - Has built-in email address validation (naive)
128
+ - Uses an email keypad on mobile
129
+ - Autocompletes to current email, to disable, set `autoComplete` to `"off"`
130
+
131
+ ### Select
132
+
133
+ Use this component to create a `Select`
134
+
135
+ ```js
136
+ const options = [
137
+ {value: 1, text: 'orange'},
138
+ {value: 2, text: 'apple'},
139
+ ];
140
+
141
+ //...
142
+
143
+ <Select options={options} />;
144
+ ```
145
+
146
+ ### PhoneNumberField
147
+
148
+ To enter phone numbers
149
+
150
+ - Uses Google's `libphonenumber` library to format numbers as you type (uses `locale` from theme context to
151
+ format numbers accordingly)
152
+
153
+ ### IbanField
154
+
155
+ To enter bank accounts using the IBAN format
156
+
157
+ - Formats the IBAN number as you type
158
+ - Validates the number using the checksum
159
+
160
+ ## DoubleField
161
+
162
+ Use this component to place two fields at the same row
163
+
164
+ ```js
165
+ <DoubleField>
166
+ <TextField name="foo" label="Foo" />
167
+ <TextField name="bar" label="Bar" />
168
+ </DoubleField>
169
+ ```
170
+
171
+ ## useForm Hook
172
+
173
+ With `useForm` you can access the form context. See `form-context.tsx`.
174
+
175
+ This allows you to implement advanced form logic. See form stories for examples.
176
+
177
+ Please open an issue if your use case is not covered or you need additional examples.
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="152" viewBox="-1 -1 302 152">
2
+ <rect y="0" width="300" height="150" fill="pink" />
3
+ <rect y="32" x="16" width="calc(300 - 32)" height="calc(150 - 64)" fill="lightgray" stroke="black" />
4
+ <text x="130" y="20">32px</text>
5
+ <text x="0" y="80" >16px</text>
6
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="243" viewBox="-1 -1 362 242">
2
+ <rect x="0" y="0" height="240" width="360" fill="pink" stroke="black"/>
3
+ <rect x="48" y="0" height="240" width="calc(360 - 96)" fill="lightgray" stroke="black"/>
4
+ <rect x="69.5" y="0" height="60" width="105.5" stroke="black" fill="rgba(255,0,0,0.3)"/>
5
+ <rect x="205.5" y="0" height="60" width="82" stroke="black" fill="rgba(0,0,255,0.3)"/>
6
+ <text x="78" y="20">Left</text>
7
+ <text x="214" y="20">Right</text>
8
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="243" viewBox="-1 -1 362 242">
2
+ <rect x="0" y="0" height="240" width="360" fill="pink" stroke="black"/>
3
+ <rect x="48" y="0" height="240" width="calc(360 - 96)" fill="lightgray" stroke="black"/>
4
+ <rect x="48" y="0" height="60" width="128" stroke="black" fill="rgba(255,0,0,0.3)"/>
5
+ <rect x="184" y="0" height="60" width="128" stroke="black" fill="rgba(0,0,255,0.3)"/>
6
+ <text x="56" y="20">Left</text>
7
+ <text x="192" y="20">Right</text>
8
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="243" viewBox="-1 -1 362 242">
2
+ <rect x="0" y="0" height="240" width="360" fill="pink" stroke="black"/>
3
+ <rect x="48" y="0" height="240" width="calc(360 - 96)" fill="lightgray" stroke="black"/>
4
+ <rect x="48" y="0" height="60" width="174" stroke="black" fill="rgba(255,0,0,0.3)"/>
5
+ <rect x="230" y="0" height="60" width="82" stroke="black" fill="rgba(0,0,255,0.3)"/>
6
+ <text x="56" y="20">Left</text>
7
+ <text x="238" y="20">Right</text>
8
+ </svg>
@@ -0,0 +1,16 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="243" viewBox="-1 -1 362 242">
2
+ <rect x="0" y="0" height="240" width="360" fill="pink" stroke="black"/>
3
+ <rect x="48" y="0" height="240" width="calc(360 - 96)" fill="lightgray" stroke="black"/>
4
+ <rect x="48" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
5
+ <rect x="70.3" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
6
+ <rect x="92.6" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
7
+ <rect x="114.9" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
8
+ <rect x="137.2" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
9
+ <rect x="159.5" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
10
+ <rect x="181.8" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
11
+ <rect x="204.1" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
12
+ <rect x="226.4" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
13
+ <rect x="248.7" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
14
+ <rect x="271" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
15
+ <rect x="293.3" y="0" height="240" width="18" fill="rgba(0,0,128,0.3)"/>
16
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="163" viewBox="-1 -1 102 162">
2
+ <rect x="0" y="0" height="160" width="100" fill="pink" stroke="black"/>
3
+ <rect x="8" y="0" height="160" width="calc(100 - 16)" fill="lightgray" stroke="black"/>
4
+
5
+ <rect x="8" y="0" height="60" width="calc(100 - 16)" fill="rgba(255,0,0,0.3)" stroke="black"/>
6
+ <rect x="8" y="60" height="60" width="calc(100 - 16)" fill="rgba(0,0,255,0.3)" stroke="black"/>
7
+ <text x="16" y="20">Left</text>
8
+ <text x="16" y="80">Right</text>
9
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="163" viewBox="-1 -1 102 162">
2
+ <rect x="0" y="0" height="160" width="100" fill="pink" stroke="black"/>
3
+ <rect x="8" y="0" height="160" width="calc(100 - 16)" fill="lightgray" stroke="black"/>
4
+
5
+ <rect x="8" y="0" height="60" width="calc(100 - 16)" fill="rgba(255,0,0,0.3)" stroke="black"/>
6
+ <rect x="8" y="60" height="60" width="calc(100 - 16)" fill="rgba(0,0,255,0.3)" stroke="black"/>
7
+ <text x="16" y="20">Left</text>
8
+ <text x="16" y="80">Right</text>
9
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="163" viewBox="-1 -1 102 162">
2
+ <rect x="0" y="0" height="160" width="100" fill="pink" stroke="black"/>
3
+ <rect x="8" y="0" height="160" width="calc(100 - 16)" fill="lightgray" stroke="black"/>
4
+
5
+ <rect x="8" y="0" height="60" width="calc(100 - 16)" fill="rgba(255,0,0,0.3)" stroke="black"/>
6
+ <rect x="8" y="60" height="60" width="calc(100 - 16)" fill="rgba(0,0,255,0.3)" stroke="black"/>
7
+ <text x="16" y="20">Left</text>
8
+ <text x="16" y="80">Right</text>
9
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="163" viewBox="-1 -1 102 162">
2
+ <rect x="0" y="0" height="160" width="100" fill="pink" stroke="black"/>
3
+ <rect x="8" y="0" height="160" width="calc(100 - 16)" fill="lightgray" stroke="black"/>
4
+ <rect x="8" y="0" height="160" width="calc(100 - 16)" fill="rgba(0,0,128,0.3)" stroke="black"/>
5
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="243" viewBox="-1 -1 162 242">
2
+ <rect x="0" y="0" height="240" width="160" fill="pink" stroke="black"/>
3
+ <rect x="12" y="0" height="240" width="calc(160 - 24)" fill="lightgray" stroke="black"/>
4
+ <rect x="12" y="0" height="60" width="calc(160 - 24)" fill="rgba(255,0,0,0.3)" stroke="black"/>
5
+ <rect x="12" y="60" height="60" width="calc(160 - 24)" fill="rgba(0,0,255,0.3)" stroke="black"/>
6
+ <text x="20" y="20">Left</text>
7
+ <text x="20" y="80">Right</text>
8
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="243" viewBox="-1 -1 162 242">
2
+ <rect x="0" y="0" height="240" width="160" fill="pink" stroke="black"/>
3
+ <rect x="12" y="0" height="240" width="calc(160 - 24)" fill="lightgray" stroke="black"/>
4
+ <rect x="12" y="0" height="60" width="calc(160 - 24)" fill="rgba(255,0,0,0.3)" stroke="black"/>
5
+ <rect x="12" y="60" height="60" width="calc(160 - 24)" fill="rgba(0,0,255,0.3)" stroke="black"/>
6
+ <text x="20" y="20">Left</text>
7
+ <text x="20" y="80">Right</text>
8
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="243" viewBox="-1 -1 162 242">
2
+ <rect x="0" y="0" height="240" width="160" fill="pink" stroke="black"/>
3
+ <rect x="12" y="0" height="240" width="calc(160 - 24)" fill="lightgray" stroke="black"/>
4
+ <rect x="12" y="0" height="60" width="calc(160 - 24)" fill="rgba(255,0,0,0.3)" stroke="black"/>
5
+ <rect x="12" y="60" height="60" width="calc(160 - 24)" fill="rgba(0,0,255,0.3)" stroke="black"/>
6
+ <text x="20" y="20">Left</text>
7
+ <text x="20" y="80">Right</text>
8
+ </svg>