diff --git a/.storybook/css/fonts/vivo-type-bold.woff2 b/.storybook/css/fonts/vivo-type-bold.woff2 index 368c1a3af2..89244bdf7d 100644 Binary files a/.storybook/css/fonts/vivo-type-bold.woff2 and b/.storybook/css/fonts/vivo-type-bold.woff2 differ diff --git a/.storybook/css/fonts/vivo-type-light.woff2 b/.storybook/css/fonts/vivo-type-light.woff2 index 5c7ba4e7f9..b668ad0c64 100644 Binary files a/.storybook/css/fonts/vivo-type-light.woff2 and b/.storybook/css/fonts/vivo-type-light.woff2 differ diff --git a/.storybook/css/fonts/vivo-type-medium.woff2 b/.storybook/css/fonts/vivo-type-medium.woff2 new file mode 100644 index 0000000000..d87f998c74 Binary files /dev/null and b/.storybook/css/fonts/vivo-type-medium.woff2 differ diff --git a/.storybook/css/fonts/vivo-type-regular.woff2 b/.storybook/css/fonts/vivo-type-regular.woff2 index 9ad164df14..f56c280c61 100644 Binary files a/.storybook/css/fonts/vivo-type-regular.woff2 and b/.storybook/css/fonts/vivo-type-regular.woff2 differ diff --git a/.storybook/css/vivo-font.css b/.storybook/css/vivo-font.css index 714f602cbd..10043d0480 100644 --- a/.storybook/css/vivo-font.css +++ b/.storybook/css/vivo-font.css @@ -19,7 +19,7 @@ font-family: 'Vivo Type'; font-style: normal; font-weight: 500; - src: url('./fonts/vivo-type-bold.woff2') format('woff2'); + src: url('./fonts/vivo-type-medium.woff2') format('woff2'); } /* Bold */ diff --git a/.yarn/cache/cubic-bezier-npm-0.1.2-e7baa5c16d-db21ebda82.zip b/.yarn/cache/cubic-bezier-npm-0.1.2-e7baa5c16d-db21ebda82.zip new file mode 100644 index 0000000000..87cd6d7402 Binary files /dev/null and b/.yarn/cache/cubic-bezier-npm-0.1.2-e7baa5c16d-db21ebda82.zip differ diff --git a/CHANGELOG.md b/CHANGELOG.md index d20495aba0..1dc11bdcdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# [16.5.0](https://github.com/Telefonica/mistica-web/compare/v16.4.0...v16.5.0) (2024-11-18) + + +### Features + +* **Accordion, BoxedAccordion:** allow detail and right content in header ([#1290](https://github.com/Telefonica/mistica-web/issues/1290)) ([087c486](https://github.com/Telefonica/mistica-web/commit/087c4866757733339e51ed9de54b844fecf7aed5)) +* **HorizontalMosaic, VerticalMosaic:** allow passing gridMode information to each item ([#1289](https://github.com/Telefonica/mistica-web/issues/1289)) ([bb8852c](https://github.com/Telefonica/mistica-web/commit/bb8852c439cb33b2ae7c877a2ac32760ec29180c)) +* **MainNavigationBar:** add menu ([#1280](https://github.com/Telefonica/mistica-web/issues/1280)) ([3973ead](https://github.com/Telefonica/mistica-web/commit/3973ead1ebef7f613b1aebd3c18306fc88999de0)) +* **vivo-type:** added medium weight ([#1291](https://github.com/Telefonica/mistica-web/issues/1291)) ([8a38d2c](https://github.com/Telefonica/mistica-web/commit/8a38d2c1c16a17b931f96c75b400d7ba8c036a93)) + # [16.4.0](https://github.com/Telefonica/mistica-web/compare/v16.3.1...v16.4.0) (2024-11-04) diff --git a/css/vivo-new.css b/css/vivo-new.css index 2d7c67e48c..ef685c7702 100644 --- a/css/vivo-new.css +++ b/css/vivo-new.css @@ -200,13 +200,13 @@ --mistica-line-height-4: 1.5rem; --mistica-font-size-5: 1.25rem; --mistica-line-height-5: 1.5rem; - --mistica-font-weight-5: 400; + --mistica-font-weight-5: 500; --mistica-font-size-6: 1.5rem; --mistica-line-height-6: 2rem; - --mistica-font-weight-6: 400; + --mistica-font-weight-6: 500; --mistica-font-size-7: 1.75rem; --mistica-line-height-7: 2rem; - --mistica-font-weight-7: 400; + --mistica-font-weight-7: 500; --mistica-font-size-8: 2rem; --mistica-line-height-8: 2.5rem; --mistica-font-weight-8: 400; @@ -218,18 +218,18 @@ --mistica-font-weight-10: 400; --mistica-font-size-cardTitle: 1.25rem; --mistica-line-height-cardTitle: 1.5rem; - --mistica-font-weight-cardTitle: 400; - --mistica-font-weight-button: 400; + --mistica-font-weight-cardTitle: 500; + --mistica-font-weight-button: 500; --mistica-font-size-tabsLabel: 1.125rem; --mistica-line-height-tabsLabel: 1.5rem; - --mistica-font-weight-tabsLabel: 400; - --mistica-font-weight-link: 400; - --mistica-font-weight-title1: 400; - --mistica-font-weight-title2: 400; + --mistica-font-weight-tabsLabel: 500; + --mistica-font-weight-link: 500; + --mistica-font-weight-title1: 500; + --mistica-font-weight-title2: 500; --mistica-font-size-title3: 1.125rem; --mistica-line-height-title3: 1.5rem; - --mistica-font-weight-title3: 400; - --mistica-font-weight-indicator: 400; + --mistica-font-weight-title3: 500; + --mistica-font-weight-indicator: 500; --mistica-font-weight-navigationBar: 400; } diff --git a/package.json b/package.json index 92decd251f..a76f1faea1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@telefonica/mistica", - "version": "16.4.0", + "version": "16.5.0", "license": "MIT", "repository": { "type": "git", @@ -151,6 +151,7 @@ "@vanilla-extract/dynamic": "^2.1.1", "@vanilla-extract/sprinkles": "^1.6.2", "classnames": "^2.3.1", + "cubic-bezier": "^0.1.2", "lottie-react": "^2.4.0", "moment": "^2.29.1", "react-autosuggest": "^10.1.0", diff --git a/packages/generate-design-tokens/.yarn/cache/@telefonica-prettier-config-npm-2.0.0-44dbed316e-b7fe4ee936.zip b/packages/generate-design-tokens/.yarn/cache/@telefonica-prettier-config-npm-2.0.0-44dbed316e-b7fe4ee936.zip new file mode 100644 index 0000000000..75caa3a116 Binary files /dev/null and b/packages/generate-design-tokens/.yarn/cache/@telefonica-prettier-config-npm-2.0.0-44dbed316e-b7fe4ee936.zip differ diff --git a/packages/generate-design-tokens/.yarn/cache/prettier-npm-3.3.3-e811f023f3-bc86043548.zip b/packages/generate-design-tokens/.yarn/cache/prettier-npm-3.3.3-e811f023f3-bc86043548.zip new file mode 100644 index 0000000000..b14018ab51 Binary files /dev/null and b/packages/generate-design-tokens/.yarn/cache/prettier-npm-3.3.3-e811f023f3-bc86043548.zip differ diff --git a/playroom/snippets.tsx b/playroom/snippets.tsx index 0739704307..5acaae3e67 100644 --- a/playroom/snippets.tsx +++ b/playroom/snippets.tsx @@ -2478,100 +2478,102 @@ const exampleScreens: Array = [ setState("isSheetOpen", false); }} > - - - - Summary of your order - } - description="Products may be shipped separately depending on availability." - /> - + {({ modalTitleId }) => ( + + - - - - - } - title="iPhone 14 Pro" - subtitle="Color: Green" - description="Capacity: 256 GB" - right={ -
- 1.379 € - 1.379 € -
- } - /> - - } - title="AirPods 3ª gen." - subtitle="Color: White" - right={ -
- 200 € -
- } - /> -
-
+ Summary of your order + } + description="Products may be shipped separately depending on availability." + /> + + + + + + + } + title="iPhone 14 Pro" + subtitle="Color: Green" + description="Capacity: 256 GB" + right={ +
+ 1.379 € + 1.379 € +
+ } + /> + + } + title="AirPods 3ª gen." + subtitle="Color: White" + right={ +
+ 200 € +
+ } + /> +
+
+ +
+ + + Subtotal + 1.369 € + + + Promoción 7% descuento + -100 € + + + Shipping costs + 0 € + + -
- - - Subtotal - 1.369 € - - - Promoción 7% descuento - -100 € - - - Shipping costs - 0 € - - - - - - Total - 1.269 € - - * All taxes included + + + Total + 1.269 € + + * All taxes included +
-
-
+ + )} )} @@ -2584,33 +2586,278 @@ const navigationBarSnippets = [ group: 'NavigationBar', name: 'MainNavigationBar', code: ` - ({ - title, - onPress: () => setState("index", idx), - }))} - selectedIndex={getState("index", 0)} - right={ - - {}} - aria-label="shopping cart with 2 items" - > - - - - - {}} aria-label="Open profile"> - - {isDesktopOrBigger && "María López Serrano"} - - - } -/>`, + setState("index", 0), + }, + { + title: "Account", + onPress: () => setState("index", 1), + }, + { + title: "Explore", + onPress: () => setState("index", 2), + }, + { + title: "Support", + onPress: () => setState("index", 3), + }, + ]} + selectedIndex={getState("index", 0)} + right={ + + {}} + aria-label="shopping cart with 2 items" + > + + + + + {}} aria-label="Open profile"> + + {isDesktopOrBigger && "María López Serrano"} + + + } + />`, + }, + { + group: 'NavigationBar', + name: 'MainNavigationBar with menu', + code: ` + setState("index", 0), + title: "Start", + menu: { + columns: [ + { + title: "Start 1", + items: [ + { + title: "item 1", + onPress: () => {}, + }, + { + title: "item 2", + href: "https://www.google.com/", + }, + { + title: "item 3", + to: "#", + }, + ], + }, + ], + }, + }, + { + onPress: () => setState("index", 1), + title: "Account", + menu: { + columns: [ + { + title: "Account 1", + items: [ + { + title: "item 1", + onPress: () => {}, + }, + ], + }, + ], + }, + }, + { + onPress: () => setState("index", 2), + title: "Explore", + menu: { + columns: [ + { + title: "Explore 1", + items: [ + { + title: "item 1", + onPress: () => {}, + }, + { + title: "item 2", + href: "https://www.google.com/", + }, + { + title: "item 3", + to: "#", + }, + ], + }, + ], + }, + }, + ]} + selectedIndex={getState("index", 0)} + />`, + }, + { + group: 'NavigationBar', + name: 'MainNavigationBar with large menu', + code: ` + setState("index", 0), + title: "Start", + menu: { + columns: [ + { + title: "Start 1", + items: [ + { + title: "item 1", + onPress: () => {}, + }, + { + title: "item 2", + href: "https://www.google.com/", + }, + { + title: "item 3", + to: "#", + }, + ], + }, + { + title: "Start 2", + items: [ + { + title: "item 1", + onPress: () => {}, + }, + { + title: "item 2", + href: "https://www.google.com/", + }, + { + title: "item 3", + to: "#", + }, + ], + }, + ], + }, + }, + { + onPress: () => setState("index", 1), + title: "Account", + menu: { + columns: [ + { + title: "Account 1", + items: [ + { + title: "item 1", + onPress: () => {}, + }, + ], + }, + ], + }, + }, + { + onPress: () => setState("index", 2), + title: "Explore", + menu: { + content: ({ closeMenu }) => ( + + Custom content + + Close menu + + ), + }, + }, + { + onPress: () => setState("index", 3), + title: "Support", + menu: { + content: isDesktopOrBigger ? ( + + {Array.from({ length: 3 }, (_, index) => ( + + + Contenidos + + {[ + "Destacados", + "Todo fútbol", + "#0", + "Cine", + "Oferta comercial", + "Mi Movistar", + "Movistar Cloud", + ].map((title, index) => ( + {}} + style={{ color: colors.textPrimary }} + > + {title} + + ))} + + + + ))} + + + Oferta} + title="Movistar Plus+" + onPress={() => {}} + description="Contrata solo TV por 9,99 €" + backgroundImage="${imagePlaceholder}" + /> + + + ) : ( + + {Array.from({ length: 3 }, (_, index) => ( + + Title + + + {}} /> + {}} /> + {}} /> + {}} /> + + + + ))} + + Oferta} + title="Movistar Plus+" + aspectRatio="1:1" + onPress={() => {}} + description="Contrata solo TV por 9,99 €" + backgroundImage="${imagePlaceholder}" + /> + + ), + }, + }, + ]} + selectedIndex={getState("index", 0)} + />`, }, { group: 'NavigationBar', @@ -2980,14 +3227,13 @@ const alertSnippets = [ setState("isSheetOpen", false); }} > - - - - - + {({ modalTitleId }) => ( + + + + + + )} )}`, }, @@ -3897,6 +4143,24 @@ const ratingSnippets: Array = [ }, ]; +const meterSnippets: Array = [ + { + group: 'Meter', + name: 'Meter Linear', + code: '', + }, + { + group: 'Meter', + name: 'Meter Angular', + code: '', + }, + { + group: 'Meter', + name: 'Meter Circular', + code: '', + }, +]; + export default [ ...buttonSnippets, ...formSnippets, @@ -3943,6 +4207,7 @@ export default [ ...sliderSnippets, ...cardSnippets, ...exampleScreens, + ...meterSnippets, { group: 'Progress', name: 'Stepper', diff --git a/src/__private_stories__/skin-components-story.tsx b/src/__private_stories__/skin-components-story.tsx index 0d1feef45c..4a07528dda 100644 --- a/src/__private_stories__/skin-components-story.tsx +++ b/src/__private_stories__/skin-components-story.tsx @@ -51,6 +51,7 @@ import { Placeholder, NegativeBox, IconInvoicePlanFileRegular, + Meter, } from '..'; import avatarImg from '../__stories__/images/avatar.jpg'; import usingVrImg from '../__stories__/images/using-vr.jpg'; @@ -315,6 +316,28 @@ export const Default: StoryComponent = ({variant}) => { steps={['First', 'Second', 'Third', 'Fourth', 'Fifth']} /> + {/** Meter */} + + + + + + {/** TextLink */} {}}>This is a text link diff --git a/src/__screenshot_tests__/__image_snapshots__/button-screenshot-test-tsx-buttons-link-button-with-chevron-and-big-font-size-in-vivo-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/button-screenshot-test-tsx-buttons-link-button-with-chevron-and-big-font-size-in-vivo-1-snap.png index 13f430503b..19429f5e73 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/button-screenshot-test-tsx-buttons-link-button-with-chevron-and-big-font-size-in-vivo-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/button-screenshot-test-tsx-buttons-link-button-with-chevron-and-big-font-size-in-vivo-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/button-screenshot-test-tsx-buttons-link-button-with-chevron-in-vivo-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/button-screenshot-test-tsx-buttons-link-button-with-chevron-in-vivo-1-snap.png index 889e93b9b9..3b0cfb0577 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/button-screenshot-test-tsx-buttons-link-button-with-chevron-in-vivo-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/button-screenshot-test-tsx-buttons-link-button-with-chevron-in-vivo-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/carousel-screenshot-test-tsx-carousel-mobile-in-vivo-new-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/carousel-screenshot-test-tsx-carousel-mobile-in-vivo-new-1-snap.png index eaab3c4087..a4e49fb1ca 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/carousel-screenshot-test-tsx-carousel-mobile-in-vivo-new-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/carousel-screenshot-test-tsx-carousel-mobile-in-vivo-new-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/carousel-screenshot-test-tsx-carousel-mobile-in-vivo-new-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/carousel-screenshot-test-tsx-carousel-mobile-in-vivo-new-2-snap.png index cc84d22bbe..09c78a5f2e 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/carousel-screenshot-test-tsx-carousel-mobile-in-vivo-new-2-snap.png and b/src/__screenshot_tests__/__image_snapshots__/carousel-screenshot-test-tsx-carousel-mobile-in-vivo-new-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-false-disabled-false-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-false-disabled-false-1-snap.png index 6381b030cb..e271daf34e 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-false-disabled-false-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-false-disabled-false-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-false-disabled-true-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-false-disabled-true-1-snap.png index bbb08be9bc..2763776250 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-false-disabled-true-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-false-disabled-true-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-true-disabled-false-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-true-disabled-false-1-snap.png index 890a2e3865..0cc20df814 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-true-disabled-false-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-0-max-4-default-value-0-removable-true-disabled-false-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-false-disabled-false-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-false-disabled-false-1-snap.png index dcd0747d0b..e17efbe710 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-false-disabled-false-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-false-disabled-false-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-false-disabled-true-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-false-disabled-true-1-snap.png index 85de44187a..021ed2429d 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-false-disabled-true-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-false-disabled-true-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-true-disabled-true-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-true-disabled-true-1-snap.png index f1baea479c..df86ad95cb 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-true-disabled-true-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/counter-screenshot-test-tsx-counter-min-3-max-4-default-value-3-removable-true-disabled-true-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/feedback-screenshot-test-tsx-success-feedback-screen-appears-properly-with-vivo-new-skin-on-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/feedback-screenshot-test-tsx-success-feedback-screen-appears-properly-with-vivo-new-skin-on-desktop-1-snap.png index 086efbcf60..60026b6eaf 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/feedback-screenshot-test-tsx-success-feedback-screen-appears-properly-with-vivo-new-skin-on-desktop-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/feedback-screenshot-test-tsx-success-feedback-screen-appears-properly-with-vivo-new-skin-on-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/feedback-screenshot-test-tsx-success-feedback-screen-appears-properly-with-vivo-new-skin-on-mobile-ios-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/feedback-screenshot-test-tsx-success-feedback-screen-appears-properly-with-vivo-new-skin-on-mobile-ios-1-snap.png index 9a37b8e240..bf6f05bd01 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/feedback-screenshot-test-tsx-success-feedback-screen-appears-properly-with-vivo-new-skin-on-mobile-ios-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/feedback-screenshot-test-tsx-success-feedback-screen-appears-properly-with-vivo-new-skin-on-mobile-ios-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-0-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-0-1-snap.png new file mode 100644 index 0000000000..b821f456a7 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-0-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-100-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-100-1-snap.png new file mode 100644 index 0000000000..e9c3b1be08 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-100-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-20-20-20-20-0-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-20-20-20-20-0-1-snap.png new file mode 100644 index 0000000000..4aeedb633f Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-20-20-20-20-0-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-33-33-1-snap.png new file mode 100644 index 0000000000..54ff5ecdf3 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-angular-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-0-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-0-1-snap.png new file mode 100644 index 0000000000..dbc29a2116 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-0-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-100-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-100-1-snap.png new file mode 100644 index 0000000000..010c50f2c1 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-100-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-20-20-20-20-0-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-20-20-20-20-0-1-snap.png new file mode 100644 index 0000000000..22bd931cc1 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-20-20-20-20-0-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-33-33-1-snap.png new file mode 100644 index 0000000000..a4240b7d65 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-circular-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-0-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-0-1-snap.png new file mode 100644 index 0000000000..b5ef63caa4 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-0-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-100-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-100-1-snap.png new file mode 100644 index 0000000000..e870eb2965 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-100-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-20-20-20-20-0-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-20-20-20-20-0-1-snap.png new file mode 100644 index 0000000000..fa9f6be23e Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-20-20-20-20-0-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-33-33-1-snap.png new file mode 100644 index 0000000000..2313ac1c1b Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-default-linear-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-angular-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-angular-33-33-1-snap.png new file mode 100644 index 0000000000..7b599e3aa0 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-angular-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-circular-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-circular-33-33-1-snap.png new file mode 100644 index 0000000000..2e772fd4f8 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-circular-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-linear-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-linear-33-33-1-snap.png new file mode 100644 index 0000000000..3d946a3433 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-inverse-linear-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-angular-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-angular-33-33-1-snap.png new file mode 100644 index 0000000000..d1360aad72 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-angular-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-circular-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-circular-33-33-1-snap.png new file mode 100644 index 0000000000..ecd87d59ae Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-circular-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-linear-33-33-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-linear-33-33-1-snap.png new file mode 100644 index 0000000000..2d7067ee7b Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/meter-screenshot-test-tsx-meter-media-linear-33-33-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-inverse-with-large-menu-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-inverse-with-large-menu-in-desktop-1-snap.png new file mode 100644 index 0000000000..aafd7f2020 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-inverse-with-large-menu-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-inverse-with-small-menu-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-inverse-with-small-menu-in-desktop-1-snap.png new file mode 100644 index 0000000000..50dfa6d59f Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-inverse-with-small-menu-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-1-snap.png new file mode 100644 index 0000000000..920046b835 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-2-snap.png new file mode 100644 index 0000000000..4fc1fa999c Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-3-snap.png new file mode 100644 index 0000000000..acae5014aa Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-custom-content-in-desktop-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-1-snap.png new file mode 100644 index 0000000000..f9859c263f Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-2-snap.png new file mode 100644 index 0000000000..d7d6f827b3 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-3-snap.png new file mode 100644 index 0000000000..02590d3be7 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-large-menu-and-default-content-in-desktop-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-1-snap.png new file mode 100644 index 0000000000..14a114c887 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-2-snap.png new file mode 100644 index 0000000000..3fe86cb96d Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-3-snap.png new file mode 100644 index 0000000000..f4b7bfcc0f Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-4-snap.png new file mode 100644 index 0000000000..44fbc84a4d Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-custom-content-in-mobile-ios-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-1-snap.png new file mode 100644 index 0000000000..569adf6b43 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-2-snap.png new file mode 100644 index 0000000000..3fe86cb96d Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-3-snap.png new file mode 100644 index 0000000000..3f4a56de1d Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-4-snap.png new file mode 100644 index 0000000000..44fbc84a4d Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-menu-and-default-content-in-mobile-ios-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-1-snap.png new file mode 100644 index 0000000000..dc011a1074 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-2-snap.png new file mode 100644 index 0000000000..eb52819bf6 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-3-snap.png new file mode 100644 index 0000000000..02590d3be7 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-custom-content-in-desktop-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-1-snap.png new file mode 100644 index 0000000000..8988bfb7ef Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-2-snap.png new file mode 100644 index 0000000000..2276be60bf Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-3-snap.png new file mode 100644 index 0000000000..02590d3be7 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/navigation-bar-screenshot-test-tsx-main-navigation-bar-with-small-menu-and-default-content-in-desktop-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-3-snap.png index cea6117e8a..328721ec6c 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-alternative-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-alternative-3-snap.png index aac9ddf92d..dc7af795ab 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-alternative-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-alternative-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-dark-mode-3-snap.png index f9029ca56b..547f931dcd 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-3-snap.png index 0f83c2e424..121cda6250 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-4-snap.png index 16f2decc76..265406cca0 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-4-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-and-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-and-dark-mode-3-snap.png index b1d918593f..300f21e405 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-and-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-blau-inverse-and-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-3-snap.png index c95e6ddf3b..9a41ce9a65 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-alternative-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-alternative-1-snap.png index 9265f6c059..b1f983738e 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-alternative-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-alternative-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-alternative-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-alternative-3-snap.png index 6e1f26c7c2..afd286ad98 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-alternative-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-alternative-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-dark-mode-3-snap.png index f2f358d650..0329236296 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-1-snap.png index f1591598a5..747ced21d1 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-3-snap.png index f57528c0a8..8272268c78 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-and-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-and-dark-mode-3-snap.png index d27b9d3e10..13abe38cfb 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-and-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-movistar-inverse-and-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-3-snap.png index 123e528efb..39fa3e5ebd 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-alternative-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-alternative-3-snap.png index bd0620f440..4406fd9594 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-alternative-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-alternative-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-dark-mode-3-snap.png index e6101adf93..ff207a137b 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-inverse-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-inverse-3-snap.png index 80be1de25e..878b9a4a90 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-inverse-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-inverse-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-inverse-and-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-inverse-and-dark-mode-3-snap.png index 0dfc2e7b9e..2757b91404 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-inverse-and-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-inverse-and-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-3-snap.png index 70917892ca..23fb830047 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-alternative-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-alternative-3-snap.png index 0344b1c610..bbeadc1c64 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-alternative-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-alternative-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-dark-mode-3-snap.png index fcc8074840..498cfecbfa 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-2-snap.png index cf63ba861e..b1882a61aa 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-2-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-3-snap.png index 3d96d2e61d..35ba39d8cb 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-4-snap.png index 0ad09a9ba2..0f9cae6f11 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-4-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-and-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-and-dark-mode-3-snap.png index 5c6f62c07d..0217ab0496 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-and-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-o-2-new-inverse-and-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-3-snap.png index fc100da15a..fe41d1ae9f 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-alternative-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-alternative-3-snap.png index bede1f6607..4898c28c32 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-alternative-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-alternative-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-dark-mode-3-snap.png index 12937e374e..81f27687fd 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-inverse-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-inverse-3-snap.png index 0a4d326dc4..95eea61457 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-inverse-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-inverse-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-inverse-and-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-inverse-and-dark-mode-3-snap.png index 7a3e407290..2ec005423a 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-inverse-and-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-telefonica-inverse-and-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-3-snap.png index cb5d48e407..f983c3794d 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-alternative-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-alternative-3-snap.png index 0bcfdc8d25..cb90bd393a 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-alternative-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-alternative-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-dark-mode-3-snap.png index 6125055bb9..297e140381 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-inverse-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-inverse-3-snap.png index c4a0b1a1fc..8aa6178d95 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-inverse-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-inverse-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-inverse-and-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-inverse-and-dark-mode-3-snap.png index c5c579c041..e1bbcacd8d 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-inverse-and-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-tu-inverse-and-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-1-snap.png index 14c594da53..23acc486d6 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-2-snap.png index 08b610a9db..63044ffdcc 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-2-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-3-snap.png index 74119eadd0..78a37dd9c1 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-4-snap.png index c70bbac2d9..f0eb1eced3 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-4-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-1-snap.png index 12a21ea7cd..7dd1b7b3b4 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-2-snap.png index 43b64d4164..4f0e63507b 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-2-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-3-snap.png index c905125369..68aed81f5a 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-4-snap.png index a2c2a0759a..ba80bad9b1 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-4-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-alternative-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-1-snap.png index 3212c0deaf..0f56ed8c97 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-2-snap.png index f02f9812f8..f4395cd2d2 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-2-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-3-snap.png index 3d8309abf8..046f9724ad 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-4-snap.png index 4342f4e778..5ccdb83f4b 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-4-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-dark-mode-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-1-snap.png index d5e91548ca..4a46b37795 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-2-snap.png index 2aa1dc9e0e..608335c998 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-2-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-3-snap.png index 5adcb18c89..30f599a46e 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-4-snap.png index 8abd3df38c..7c2b40eef3 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-4-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-1-snap.png index 3a892cb459..e14504ddc9 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-2-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-2-snap.png index c9d887db9f..fdb6d9bb36 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-2-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-2-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-3-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-3-snap.png index 420f10209f..0a50dbf381 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-3-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-3-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-4-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-4-snap.png index 96b4c692e5..d2a8a04823 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-4-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-skin-components-screenshot-test-tsx-components-in-vivo-new-inverse-and-dark-mode-4-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-text-preset-vars-screenshot-test-tsx-text-presets-as-css-vars-in-vivo-new-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-text-preset-vars-screenshot-test-tsx-text-presets-as-css-vars-in-vivo-new-desktop-1-snap.png index 885efdc7c0..e0d409e2e8 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-text-preset-vars-screenshot-test-tsx-text-presets-as-css-vars-in-vivo-new-desktop-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-text-preset-vars-screenshot-test-tsx-text-presets-as-css-vars-in-vivo-new-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/private-text-preset-vars-screenshot-test-tsx-text-presets-as-css-vars-in-vivo-new-mobile-ios-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/private-text-preset-vars-screenshot-test-tsx-text-presets-as-css-vars-in-vivo-new-mobile-ios-1-snap.png index d68bf19184..9855ce0aa9 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/private-text-preset-vars-screenshot-test-tsx-text-presets-as-css-vars-in-vivo-new-mobile-ios-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/private-text-preset-vars-screenshot-test-tsx-text-presets-as-css-vars-in-vivo-new-mobile-ios-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-desktop-1-snap.png index 4cdcb27583..18d6eb8040 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-desktop-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-large-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-large-desktop-1-snap.png new file mode 100644 index 0000000000..b2fc4393a2 Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-large-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-mobile-ios-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-mobile-ios-1-snap.png index 38589dd0d8..58ad8723bd 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-mobile-ios-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-sheet-in-mobile-ios-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/success-feedback-screenshot-test-tsx-success-feedback-component-appears-properly-with-vivo-new-skin-on-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/success-feedback-screenshot-test-tsx-success-feedback-component-appears-properly-with-vivo-new-skin-on-desktop-1-snap.png index 93825e35c7..7a065a17f2 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/success-feedback-screenshot-test-tsx-success-feedback-component-appears-properly-with-vivo-new-skin-on-desktop-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/success-feedback-screenshot-test-tsx-success-feedback-component-appears-properly-with-vivo-new-skin-on-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/success-feedback-screenshot-test-tsx-success-feedback-component-appears-properly-with-vivo-new-skin-on-mobile-ios-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/success-feedback-screenshot-test-tsx-success-feedback-component-appears-properly-with-vivo-new-skin-on-mobile-ios-1-snap.png index e665ba133e..0820759478 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/success-feedback-screenshot-test-tsx-success-feedback-component-appears-properly-with-vivo-new-skin-on-mobile-ios-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/success-feedback-screenshot-test-tsx-success-feedback-component-appears-properly-with-vivo-new-skin-on-mobile-ios-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/tooltip-screenshot-test-tsx-tooltip-arrow-appears-properly-in-vivo-new-skin-when-target-is-close-to-viewport-edges-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/tooltip-screenshot-test-tsx-tooltip-arrow-appears-properly-in-vivo-new-skin-when-target-is-close-to-viewport-edges-1-snap.png index bed16462ef..de2d7f2e76 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/tooltip-screenshot-test-tsx-tooltip-arrow-appears-properly-in-vivo-new-skin-when-target-is-close-to-viewport-edges-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/tooltip-screenshot-test-tsx-tooltip-arrow-appears-properly-in-vivo-new-skin-when-target-is-close-to-viewport-edges-1-snap.png differ diff --git a/src/__screenshot_tests__/meter-screenshot-test.tsx b/src/__screenshot_tests__/meter-screenshot-test.tsx new file mode 100644 index 0000000000..e8cd4117ac --- /dev/null +++ b/src/__screenshot_tests__/meter-screenshot-test.tsx @@ -0,0 +1,44 @@ +import {openStoryPage, screen} from '../test-utils'; + +test.each` + values | type | themeVariant + ${[0]} | ${'linear'} | ${'default'} + ${[0]} | ${'circular'} | ${'default'} + ${[0]} | ${'angular'} | ${'default'} + ${[100]} | ${'linear'} | ${'default'} + ${[100]} | ${'circular'} | ${'default'} + ${[100]} | ${'angular'} | ${'default'} + ${[33, 33]} | ${'linear'} | ${'default'} + ${[33, 33]} | ${'circular'} | ${'default'} + ${[33, 33]} | ${'angular'} | ${'default'} + ${[33, 33]} | ${'linear'} | ${'inverse'} + ${[33, 33]} | ${'circular'} | ${'inverse'} + ${[33, 33]} | ${'angular'} | ${'inverse'} + ${[33, 33]} | ${'linear'} | ${'media'} + ${[33, 33]} | ${'circular'} | ${'media'} + ${[33, 33]} | ${'angular'} | ${'media'} + ${[20, 20, 20, 20, 0]} | ${'linear'} | ${'default'} + ${[20, 20, 20, 20, 0]} | ${'circular'} | ${'default'} + ${[20, 20, 20, 20, 0]} | ${'angular'} | ${'default'} +`('Meter $themeVariant $type $values', async ({themeVariant, values, type}) => { + await openStoryPage({ + id: 'components-data-visualizations-meter--meter-story', + args: { + themeVariant, + width: 200, + type, + valuesCount: values.length, + ...values.reduce( + (acc: Array, value: number, index: number) => ({ + ...acc, + [`value${index + 1}`]: value, + }), + {} + ), + }, + }); + + const stepper = await screen.findByTestId('Meter'); + const image = await stepper.screenshot(); + expect(image).toMatchImageSnapshot(); +}); diff --git a/src/__screenshot_tests__/navigation-bar-screenshot-test.tsx b/src/__screenshot_tests__/navigation-bar-screenshot-test.tsx index a79bc5cd75..0a6a0f9074 100644 --- a/src/__screenshot_tests__/navigation-bar-screenshot-test.tsx +++ b/src/__screenshot_tests__/navigation-bar-screenshot-test.tsx @@ -164,3 +164,67 @@ test.each(DEVICES)('MainNavigationBar without sections (%s)', async (device) => expect(image).toMatchImageSnapshot(); }); + +test.each` + menuType | content + ${'large'} | ${'default'} + ${'large'} | ${'custom'} + ${'small'} | ${'default'} + ${'small'} | ${'custom'} +`('MainNavigationBar with $menuType menu and $content content in DESKTOP', async ({menuType, content}) => { + const page = await openStoryPage({ + id: 'components-navigation-bars-mainnavigationbar--default', + device: 'DESKTOP', + args: {sections: true, desktopLargeMenu: menuType === 'large', menu: content}, + }); + + // first section opened + await page.click(await screen.findByRole('button', {name: 'Start'})); + expect(await page.screenshot()).toMatchImageSnapshot(); + + // second section opened + await page.click(await screen.findByRole('button', {name: 'Account'})); + expect(await page.screenshot()).toMatchImageSnapshot(); + + // close menu with ESC key + await page.keyboard.press('Escape'); + expect(await page.screenshot()).toMatchImageSnapshot(); +}); + +test.each(['default', 'custom'])('MainNavigationBar with menu and %s content in MOBILE_IOS', async (menu) => { + const page = await openStoryPage({ + id: 'components-navigation-bars-mainnavigationbar--default', + device: 'MOBILE_IOS', + args: {sections: true, menu}, + }); + + await page.click(await screen.findByRole('button', {name: 'Abrir menú de navegación'})); + + // open first section + await page.click(await screen.findByRole('button', {name: 'Start'})); + expect(await page.screenshot()).toMatchImageSnapshot(); + + // go back + await page.click(await screen.findByRole('button', {name: 'Atrás'})); + expect(await page.screenshot()).toMatchImageSnapshot(); + + // open second section + await page.click(await screen.findByRole('button', {name: 'Account'})); + expect(await page.screenshot()).toMatchImageSnapshot(); + + // close menu + await page.click(await screen.findByRole('button', {name: 'Cerrar menú de navegación'})); + expect(await page.screenshot()).toMatchImageSnapshot(); +}); + +test.each(['large', 'small'])('MainNavigationBar inverse with %s menu in DESKTOP', async (menuType) => { + const page = await openStoryPage({ + id: 'components-navigation-bars-mainnavigationbar--default', + device: 'DESKTOP', + args: {sections: true, desktopLargeMenu: menuType === 'large', menu: 'default', variant: 'inverse'}, + }); + + // first section opened + await page.click(await screen.findByRole('button', {name: 'Start'})); + expect(await page.screenshot()).toMatchImageSnapshot({failureThreshold: 0.00001}); +}); diff --git a/src/__screenshot_tests__/sheet-screenshot-test.tsx b/src/__screenshot_tests__/sheet-screenshot-test.tsx index c111790c3a..447a20f85c 100644 --- a/src/__screenshot_tests__/sheet-screenshot-test.tsx +++ b/src/__screenshot_tests__/sheet-screenshot-test.tsx @@ -3,7 +3,7 @@ import {openStoryPage, screen} from '../test-utils'; const TESTABLE_DEVICES = ['MOBILE_IOS', 'DESKTOP'] as const; const TESTABLE_DEVICES_WITH_LARGE_DESKTOP = [...TESTABLE_DEVICES, 'LARGE_DESKTOP'] as const; -test.each(TESTABLE_DEVICES)('Sheet in %s', async (device) => { +test.each(TESTABLE_DEVICES_WITH_LARGE_DESKTOP)('Sheet in %s', async (device) => { const page = await openStoryPage({ id: 'components-modals-sheet--default', device, diff --git a/src/__stories__/main-navigation-bar-story.tsx b/src/__stories__/main-navigation-bar-story.tsx index b570b2197c..1d632883fe 100644 --- a/src/__stories__/main-navigation-bar-story.tsx +++ b/src/__stories__/main-navigation-bar-story.tsx @@ -7,6 +7,8 @@ import { NavigationBarAction, NavigationBarActionGroup, Placeholder, + Stack, + Text3, useScreenSize, } from '..'; import avatarImg from './images/avatar.jpg'; @@ -21,7 +23,7 @@ export default { }, }; -const sectionTitles = ['Start', 'Account', 'Explore', 'Support']; +const sectionTitles = ['Start', 'Account', 'Explore', 'Support'] as const; type Args = { variant: Variant; @@ -29,20 +31,75 @@ type Args = { burgerMenuExtra: boolean; large: boolean; sections: boolean; + menu: 'undefined' | 'default' | 'custom'; + desktopLargeMenu: boolean; }; -export const Default: StoryComponent = ({variant, border, burgerMenuExtra, large, sections}) => { +export const Default: StoryComponent = ({ + variant, + border, + burgerMenuExtra, + large, + sections, + menu, + desktopLargeMenu, +}) => { const [selectedIndex, setSelectedIndex] = React.useState(0); const {isDesktopOrBigger} = useScreenSize(); + + const sectionDefaultMenuItemsCount = { + Start: 3, + Account: 1, + Explore: 2, + Support: 3, + }; + return ( : undefined} + desktopLargeMenu={desktopLargeMenu} sections={ sections - ? sectionTitles.map((title, idx) => ({title, onPress: () => setSelectedIndex(idx)})) + ? sectionTitles.map((title, idx) => ({ + title, + onPress: () => setSelectedIndex(idx), + menu: + menu === 'undefined' + ? undefined + : menu === 'default' + ? { + title: `${title} menu`, + columns: Array.from( + {length: desktopLargeMenu ? 2 : 1}, + (_, columnIndex) => ({ + title: `${title} ${columnIndex + 1}`, + items: Array.from( + {length: sectionDefaultMenuItemsCount[title]}, + (_, index) => ({ + title: `item ${index + 1}`, + onPress: () => {}, + }) + ), + }) + ), + } + : { + content: ( + + {title} menu + {Array.from( + {length: sectionDefaultMenuItemsCount[title]}, + (_, index) => ( + + ) + )} + + ), + }, + })) : undefined } selectedIndex={selectedIndex} @@ -71,6 +128,8 @@ Default.args = { burgerMenuExtra: false, large: false, sections: true, + menu: 'undefined', + desktopLargeMenu: false, }; Default.argTypes = { @@ -78,4 +137,10 @@ Default.argTypes = { options: ['default', 'inverse', 'alternative'], control: {type: 'select'}, }, + menu: { + options: ['undefined', 'default', 'custom'], + control: {type: 'select'}, + if: {arg: 'sections'}, + }, + desktopLargeMenu: {if: {arg: 'sections'}}, }; diff --git a/src/__stories__/meter-story.tsx b/src/__stories__/meter-story.tsx new file mode 100644 index 0000000000..e594847306 --- /dev/null +++ b/src/__stories__/meter-story.tsx @@ -0,0 +1,127 @@ +import * as React from 'react'; +import {Box, Meter, ResponsiveLayout} from '..'; +import beachImg from './images/beach.jpg'; + +import type {MeterType} from '../meter'; + +export default { + title: 'Components/Data Visualizations/Meter', + argTypes: { + type: { + options: ['angular', 'circular', 'linear'] as Array, + control: {type: 'select'}, + }, + themeVariant: { + options: ['default', 'inverse', 'media'], + control: {type: 'select'}, + }, + valuesCount: { + control: {type: 'range', min: 1, max: 8, step: 1}, + }, + fullWidth: { + control: {type: 'boolean'}, + }, + width: { + if: {arg: 'fullWidth', eq: false}, + control: {type: 'range', min: 64, max: 600, step: 1}, + }, + value1: { + control: {type: 'range', min: 0, max: 100, step: 1}, + }, + value2: { + control: {type: 'range', min: 0, max: 100, step: 1}, + }, + value3: { + control: {type: 'range', min: 0, max: 100, step: 1}, + }, + value4: { + control: {type: 'range', min: 0, max: 100, step: 1}, + }, + value5: { + control: {type: 'range', min: 0, max: 100, step: 1}, + }, + value6: { + control: {type: 'range', min: 0, max: 100, step: 1}, + }, + value7: { + control: {type: 'range', min: 0, max: 100, step: 1}, + }, + value8: { + control: {type: 'range', min: 0, max: 100, step: 1}, + }, + }, + parameters: { + fullScreen: true, + }, +}; + +type MeterStoryArgs = { + type: MeterType; + reverse: boolean; + ariaLabel: string; + themeVariant: 'default' | 'inverse' | 'media'; + fullWidth: boolean; + width: number; + valuesCount: number; + value1: number; + value2: number; + value3: number; + value4: number; + value5: number; + value6: number; + value7: number; + value8: number; +}; + +export const MeterStory: StoryComponent = ({ + type, + reverse, + themeVariant, + valuesCount, + fullWidth, + width, + ariaLabel, + ...valuesArgs +}) => { + const values = Object.values(valuesArgs).slice(0, valuesCount); + return ( +
+ + + + + +
+ ); +}; + +MeterStory.storyName = 'Meter'; +MeterStory.args = { + type: 'angular', + reverse: false, + ariaLabel: 'Meter example', + themeVariant: 'default', + fullWidth: false, + width: 400, + valuesCount: 8, + value1: 10, + value2: 10, + value3: 10, + value4: 10, + value5: 10, + value6: 10, + value7: 10, + value8: 10, +}; diff --git a/src/__stories__/sheet-story.tsx b/src/__stories__/sheet-story.tsx index 69e1ab37ab..c7be171902 100644 --- a/src/__stories__/sheet-story.tsx +++ b/src/__stories__/sheet-story.tsx @@ -6,7 +6,7 @@ import { ButtonPrimary, Inline, Placeholder, - ResponsiveLayout, + SheetBody, showSheet, Stack, Text2, @@ -45,7 +45,10 @@ export const Default: StoryComponent = () => { description="Check Sheet component docs for more info." asset={} buttonLink={ - + See docs } @@ -58,11 +61,13 @@ export const Default: StoryComponent = () => { setOpen(false); }} > - - - - - + {({modalTitleId}) => ( + + + + + + )} )} diff --git a/src/__tests__/main-navigation-bar-test.tsx b/src/__tests__/main-navigation-bar-test.tsx new file mode 100644 index 0000000000..12f131f428 --- /dev/null +++ b/src/__tests__/main-navigation-bar-test.tsx @@ -0,0 +1,155 @@ +import * as React from 'react'; +import {makeTheme} from './test-utils'; +import {render, screen, waitFor} from '@testing-library/react'; +import ThemeContextProvider from '../theme-context-provider'; +import {MainNavigationBar} from '../navigation-bar'; +import userEvent from '@testing-library/user-event'; +import {act} from 'react-dom/test-utils'; +import {ButtonPrimary} from '../button'; + +test('MainNavigationBar section with interaction is accessible', async () => { + const firstSectionOnPressSpy = jest.fn(); + + render( + + {}}, + {title: 'item 1-2', href: '#'}, + {title: 'item 1-3', to: '/'}, + ], + }, + ], + }, + }, + // Section without custom interaction + { + title: 'section 2', + menu: { + columns: [ + { + title: 'column 2', + items: [{title: 'item 2-1', onPress: () => {}}], + }, + ], + }, + }, + ]} + /> + + ); + + const firstSectionButton = await screen.findByRole('button', {name: 'section 1'}); + + // Section buttons that control menu should not have aria-expanded + const firstSectionMenuButton = await screen.findByRole('button', { + name: 'section 1, Abrir submenú', + expanded: false, + }); + + // Menu is initially closed, no section should be visible + expect(screen.queryByText('item 1-1')).not.toBeInTheDocument(); + expect(screen.queryByText('item 2-1')).not.toBeInTheDocument(); + + // Focus arrow in order for it to appear in the screen + await act(async () => { + firstSectionMenuButton.focus(); + }); + + await userEvent.click(firstSectionMenuButton); + + // First section should be visible, while second one shouldn't + expect(screen.getByRole('button', {name: 'item 1-1'})).toBeInTheDocument(); + expect(screen.getByRole('link', {name: /item 1-2/})).toBeInTheDocument(); + expect(screen.getByRole('link', {name: /item 1-3/})).toBeInTheDocument(); + expect(screen.queryByRole('button', {name: 'item 2-1'})).not.toBeInTheDocument(); + + // Remove mouse hover from section in order to close the menu + await userEvent.unhover(firstSectionButton); + + // Section onPress shouldn't have been called + expect(firstSectionOnPressSpy).toHaveBeenCalledTimes(0); + + // Click in the section's tab + await userEvent.click(firstSectionButton); + expect(firstSectionOnPressSpy).toHaveBeenCalledTimes(1); + + // The second section has no custom interaction, it should control the menu when pressed + const secondSectionButton = await screen.findByRole('button', { + name: 'section 2, Abrir submenú', + expanded: false, + }); + + // Open second section's menu + await userEvent.hover(secondSectionButton); + + await waitFor(() => { + expect(firstSectionMenuButton).toHaveAttribute('aria-expanded', 'false'); + expect(secondSectionButton).toHaveAttribute('aria-expanded', 'true'); + + // Second section should be visible, while first one shouldn't + expect(screen.getByText('item 2-1')).toBeInTheDocument(); + expect(screen.queryByText('item 1-1')).not.toBeInTheDocument(); + }); + + // Close the menu with ESC key + await userEvent.keyboard('{Escape}'); + + await waitFor(() => { + expect(firstSectionMenuButton).toHaveAttribute('aria-expanded', 'false'); + expect(secondSectionButton).toHaveAttribute('aria-expanded', 'false'); + + // Buttons that open the menu should have aria-haspopup + expect(firstSectionMenuButton).toHaveAttribute('aria-haspopup', 'true'); + expect(secondSectionButton).toHaveAttribute('aria-haspopup', 'true'); + + // Menu is closed, no section should be visible + expect(screen.queryByText('item 1-1')).not.toBeInTheDocument(); + expect(screen.queryByText('item 2-1')).not.toBeInTheDocument(); + }); +}); + +test('MainNavigationBar menu closeMenu callback closes the menu', async () => { + render( + + ( + Close menu + ), + }, + }, + ]} + /> + + ); + + // Open the menu + const sectionButton = await screen.findByRole('button', {name: 'section 1, Abrir submenú'}); + await userEvent.hover(sectionButton); + + await waitFor(() => { + expect(sectionButton).toHaveAttribute('aria-expanded', 'true'); + }); + + // Close the menu with the closeMenu callback + const closeButton = await screen.findByRole('button', {name: 'Close menu'}); + await userEvent.click(closeButton); + + await waitFor(() => { + expect(sectionButton).toHaveAttribute('aria-expanded', 'false'); + expect(screen.queryByText('Close menu')).not.toBeInTheDocument(); + }); +}); diff --git a/src/__tests__/meter-test.tsx b/src/__tests__/meter-test.tsx new file mode 100644 index 0000000000..0148d0bffd --- /dev/null +++ b/src/__tests__/meter-test.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import {screen, render} from '@testing-library/react'; +import ThemeContextProvider from '../theme-context-provider'; +import {makeTheme} from './test-utils'; +import Meter from '../meter'; + +test('Meter custom label', () => { + render( + + + + ); + + const meter = screen.getByRole('meter', {name: 'Patata'}); + expect(meter).toBeInTheDocument(); +}); + +test('Meter default label', () => { + render( + + + + ); + + const expectedLabel = + 'Indicador de progreso con 3 secciones, total 60% de 100%. Sección 1: 10%. Sección 2: 20%. Sección 3: 30%'; + + const meter = screen.getByRole('meter', {name: expectedLabel}); + expect(meter).toBeInTheDocument(); +}); diff --git a/src/__tests__/testid-test.tsx b/src/__tests__/testid-test.tsx index 277a1e5db7..63c981c76c 100644 --- a/src/__tests__/testid-test.tsx +++ b/src/__tests__/testid-test.tsx @@ -4,15 +4,24 @@ import {screen, render, within} from '@testing-library/react'; import { ButtonPrimary, ButtonSecondary, + Callout, DataCard, DateField, + Hero, + Image, + HighlightedCard, IconShopRegular, + Meter, Placeholder, SearchField, Stack, SuccessFeedbackScreen, TextField, ThemeContextProvider, + Tag, + CoverHero, + Header, + MainSectionHeader, } from '..'; import {makeTheme} from './test-utils'; @@ -100,6 +109,15 @@ test('Cards test ids', () => { ); }); +test('HighlightedCard test ids', () => { + checkTestIds(, [ + { + componentName: 'HighlightedCard', + internalTestIds: ['title', 'description', 'image'], + }, + ]); +}); + test('FeedbackScreen test ids', () => { checkTestIds( { ] ); }); + +test('Callout test ids', () => { + checkTestIds( + } onClose={() => {}} />, + [ + { + componentName: 'Callout', + internalTestIds: ['title', 'description', 'asset', 'closeButton'], + }, + ] + ); +}); + +test('Hero test ids', () => { + checkTestIds( + } + headline={tag} + pretitle="pretitle" + title="title" + description="description" + button={button} + desktopMediaPosition="right" + extra={} + />, + [ + { + componentName: 'Hero', + internalTestIds: ['headline', 'pretitle', 'title', 'description', 'slot'], + }, + ] + ); +}); + +test('CoverHero test ids', () => { + checkTestIds( + tag} + pretitle="pretitle" + title="title" + description="description" + button={button} + extra={} + sideExtra={} + />, + [ + { + componentName: 'CoverHero', + internalTestIds: ['headline', 'pretitle', 'title', 'description', 'slot', 'sideSlot'], + }, + ] + ); +}); + +test('Header test ids', () => { + checkTestIds( +
tag} + pretitle="pretitle" + title="title" + description="description" + />, + [ + { + componentName: 'Header', + internalTestIds: ['headline', 'pretitle', 'title', 'description'], + }, + ] + ); +}); + +test('MainSectionHeader test ids', () => { + checkTestIds( + Action} + />, + [ + { + componentName: 'MainSectionHeader', + internalTestIds: ['title', 'description'], + }, + ] + ); +}); + +test('Meter test ids', () => { + checkTestIds(, [ + { + componentName: 'Meter', + internalTestIds: [], + }, + ]); +}); diff --git a/src/callout.tsx b/src/callout.tsx index 98d4709920..f0bf975044 100644 --- a/src/callout.tsx +++ b/src/callout.tsx @@ -63,15 +63,24 @@ const Callout = ({ {...getPrefixedDataAttributes(dataAttributes, 'Callout')} > - {asset && {asset}} + {asset && ( + + {asset} + + )}
- + {title} - + {description} @@ -93,6 +102,7 @@ const Callout = ({ {onClose && (
( const textShadow = hasMedia ? '0 0 15px rgba(0, 0, 0, 0.4)' : undefined; const pretitleContent = pretitle ? ( - + {pretitle} ) : undefined; const titleContent = ( - + {title} ); const mainContent = (
- {headline && {headline}} + {headline && ( + + {headline} + + )} {/** using flex instead of nested Stacks, this way we can rearrange texts so the DOM structure makes more sense for screen reader users */}
@@ -160,13 +178,14 @@ const CoverHero = React.forwardRef( truncate={descriptionLinesMax} color={hasMedia ? vars.colors.textPrimary : vars.colors.textSecondary} textShadow={textShadow} + dataAttributes={{testid: 'description'}} > {description}
)}
- {extra} + {extra &&
{extra}
}
); @@ -208,7 +227,11 @@ const CoverHero = React.forwardRef( template="8+4" collapseBreakpoint="mobile" left={mainContent} - right={
{sideExtra}
} + right={ +
+ {sideExtra} +
+ } /> )} : undefined; + const image = imageUrl ? ( + + ) : undefined; const buttons: ButtonGroupProps = { ...(button?.type === ButtonPrimary ? {primaryButton: button} : {secondaryButton: button}), @@ -92,13 +94,21 @@ const EmptyState = ({ largeImageUrl ? styles.contentVariants.largeImage : styles.contentVariants.default } > - {image ?? (asset &&
{asset}
)} + {image ?? + (asset && ( +
+ {asset} +
+ ))} - {title} + + {title} + {description} @@ -115,6 +125,7 @@ const EmptyState = ({ width="100%" >
diff --git a/src/header.tsx b/src/header.tsx index a875fa7ea7..1efbf329a0 100644 --- a/src/header.tsx +++ b/src/header.tsx @@ -51,42 +51,53 @@ export const Header = ({ dataAttributes, small = false, }: HeaderProps): JSX.Element => { - const renderRichText = (richText: RichText, baseProps: Omit) => { - if (typeof richText === 'string') { - return ( - - {richText} - - ); + const renderPretitle = () => { + if (!pretitle) { + return null; } - const {text, ...textProps} = richText; + const baseTextProps = { + regular: true, + color: vars.colors.textPrimary, + as: pretitleAs, + dataAttributes: {testid: 'pretitle'}, + } as const; + + if (typeof pretitle === 'string') { + return {pretitle}; + } + const {text, ...textProps} = pretitle; return ( - - {richText.text} + + {text} ); }; - const pretitleContent = pretitle - ? renderRichText(pretitle, {color: vars.colors.textPrimary, as: pretitleAs}) - : undefined; + const pretitleContent = renderPretitle(); const titleContent = title ? ( small ? ( - {title} + + {title} + ) : ( - {title} + + {title} + ) ) : undefined; return ( - + {(title || pretitle || description) && ( {/** using flex instead of nested Stacks, this way we can rearrange texts so the DOM structure makes more sense for screen reader users */}
{headline && ( -
+
{headline}
)} @@ -118,11 +129,19 @@ export const Header = ({ {description && (
{small ? ( - + {description} ) : ( - + {description} )} @@ -140,6 +159,7 @@ type MainSectionHeaderProps = { titleAs?: HeadingType; description?: string; button?: RendersNullableElement | RendersNullableElement; + dataAttributes?: DataAttributes; }; export const MainSectionHeader = ({ @@ -147,12 +167,23 @@ export const MainSectionHeader = ({ titleAs = 'h1', description, button, + dataAttributes, }: MainSectionHeaderProps): JSX.Element => { return ( - + - {title && {title}} - {description && {description}} + {title && ( + + {title} + + )} + {description && {description}} {button} @@ -197,7 +228,7 @@ export const HeaderLayout = ({ useSetOverscrollColor(isInverse ? {topColor: vars.colors.backgroundBrandTop} : {}); return ( -
+
{ - const titleContent = title ? {title} : undefined; + const titleContent = title ? ( + + {title} + + ) : undefined; const pretitleContent = pretitle ? ( - + {pretitle} ) : undefined; @@ -91,7 +95,7 @@ const HeroContent = ({
- {headline && headline} + {headline &&
{headline}
} {/** using flex instead of nested Stacks, this way we can rearrange texts so the DOM structure makes more sense for screen reader users */}
@@ -120,12 +124,13 @@ const HeroContent = ({ regular color={skinVars.colors.textSecondary} truncate={descriptionLinesMax} + dataAttributes={{testid: 'description'}} > {description} )} - {extra &&
{extra}
} + {extra &&
{extra}
}
{(button || buttonLink) && (
@@ -182,7 +187,7 @@ const Hero = React.forwardRef(
( return (
((props, ref) => { const content = ( @@ -94,6 +98,7 @@ const Content = React.forwardRef((props, ref) => { weight={textPresets.cardTitle.weight} as={titleAs} hyphens="auto" + dataAttributes={{testid: 'title'}} > {title} @@ -105,6 +110,7 @@ const Content = React.forwardRef((props, ref) => { truncate={descriptionLinesMax} as="p" hyphens="auto" + dataAttributes={{testid: 'description'}} > {description} @@ -119,6 +125,7 @@ const Content = React.forwardRef((props, ref) => {
{imageUrl && (
number = bezier(0.75, 0, 0.27, 1, ANIMATION_EPSILON); + +const clamp = (n: number, min: number, max: number) => Math.min(Math.max(n, min), max); + +/** + * Calculate the start and end segment values for each segment of the meter + */ +const calculateSegments = ( + currentValues: Array, + targetValues: Array, + time: number, + reverse: boolean +): Array => { + const segments: Array = []; + + let startValue = 0; + let endValue = 0; + for (let i = 0; i < currentValues.length; i++) { + startValue += currentValues[i]; + endValue += targetValues[i]; + + // each segment has an accumulated delay time. The last segment has no delay + const delay = ANIMATION_DELAY_MS * (reverse ? i : currentValues.length - 1 - i); + const animationTime = clamp((time - delay) / ANIMATION_DURATION_MS, 0, 1); + + const t = clamp(timingFunction(animationTime), 0, 1); + const start = segments.at(-1)?.end || 0; + const end = clamp(startValue + (endValue - startValue) * t, 0, 1 - SMALL_VALUE_THRESHOLD); + segments.push({start, end}); + } + return segments; +}; + +const createPath = ({ + x1, + y1, + x2, + y2, + radius, + clockwise = 1, + largeArchFlag = 0, +}: { + x1: number; + y1: number; + x2: number; + y2: number; + radius: number; + clockwise?: 0 | 1 | boolean; + largeArchFlag?: 0 | 1 | boolean; +}): string => { + const xAxisRotation = 0; + if (radius) { + // https://www.nan.fyi/svg-paths/arcs + return `M ${x1} ${y1} A ${radius} ${radius} ${xAxisRotation} ${+largeArchFlag} ${+clockwise} ${x2} ${y2}`; + } else { + // https://www.nan.fyi/svg-paths/lines + return `M ${x1} ${y1} L ${x2} ${y2}`; + } +}; + +type MeterProps = { + type?: MeterType; + /** Position of the meter. 0 is at the start, 100 is at the end. The sum of the values must not exceed 100. */ + values: Array; + width?: number | string; + colors?: Array; + reverse?: boolean; + dataAttributes?: DataAttributes; + 'aria-hidden'?: boolean | 'true' | 'false'; + 'aria-label'?: string; + 'aria-labelledby'?: string; +}; + +const MeterComponent = ({ + type = TYPE_ANGULAR, + width: widthProp = '100%', + colors, + values: valuesProp, + reverse = false, + dataAttributes, + 'aria-hidden': ariaHidden = false, + 'aria-label': ariaLabel, + 'aria-labelledby': ariaLabelledBy, +}: MeterProps): JSX.Element => { + const {borderRadii, t} = useTheme(); + const {ref: containerRef, width: containerWidth} = useElementDimensions(); + const hasRoundLineCaps = parseInt(borderRadii.bar) !== 0; + const themeVariant = useThemeVariant(); + const isOverMedia = themeVariant === 'media'; + const isInverse = themeVariant === 'inverse'; + const segmentColors = colors || (isInverse || isOverMedia ? DEFAULT_COLORS_INVERSE : DEFAULT_COLORS); + const [width, setWidth] = React.useState(typeof widthProp === 'number' ? widthProp : 0); + const scaleFactor = width === 0 ? 1 : VIEW_BOX_WIDTH / width; + const lineCapRadiusPx = hasRoundLineCaps ? STROKE_WIDTH_PX / 2 : 0; + const lineCapRadius = lineCapRadiusPx * scaleFactor; + const strokeWidth = STROKE_WIDTH_PX * scaleFactor; + const radius = type === TYPE_LINEAR ? 0 : CENTER_X - strokeWidth / 2; + const separation = SEPARATION_PX * scaleFactor; + + const id = React.useId(); + const markerCurrentId = `marker-current-${id}`; + const markerStartId = `marker-start-${id}`; + const maskLastSegmentId = `mask-last-segment-${id}`; + const maskBarTrackId = `mask-bar-track-${id}`; + + const shouldAnimate = React.useMemo(() => { + return ( + window.matchMedia(`(prefers-reduced-motion: reduce)`).matches !== true && + !isRunningAcceptanceTest() + ); + }, []); + + const maxValue = + type === TYPE_LINEAR + ? VIEW_BOX_WIDTH - lineCapRadius * 2 + : type === TYPE_CIRCULAR + ? Math.PI * 2 + : Math.PI; + + const segmentSeparation = + type === TYPE_LINEAR ? separation / VIEW_BOX_WIDTH : separation / radius / maxValue; + + const height = + type === TYPE_LINEAR ? STROKE_WIDTH_PX : type === TYPE_CIRCULAR ? width : width / 2 + lineCapRadiusPx; + + const viewBoxHeight = + type === TYPE_LINEAR + ? strokeWidth + : type === TYPE_CIRCULAR + ? VIEW_BOX_WIDTH + : CENTER_X + lineCapRadius; + + const trackbarColor = isOverMedia + ? vars.colors.inverse + : isInverse + ? vars.colors.barTrackInverse + : vars.colors.barTrack; + + // scale values to the range [0, 1] + const values = React.useMemo(() => { + return valuesProp.map((v) => v / MAX_SEGMENT_VALUE); + }, [valuesProp]); + + // the animation starts with these values + const initialValuesRef = React.useRef>( + Array.from({length: values.length}, () => (reverse ? 1 : 0)) + ); + + const [segments, setSegments] = React.useState>(() => { + return values.map(() => ({start: 0, end: 0})); + }); + + // this is to know which are the first and last visible segments, which have special treatments + let firstNonZeroIndex = -1; + let lastNonZeroIndex = -1; + for (let i = 0; i < segments.length; i++) { + if (segments[i].end - segments[i].start > SMALL_VALUE_THRESHOLD) { + if (firstNonZeroIndex < 0) { + firstNonZeroIndex = i; + } + lastNonZeroIndex = i; + } + } + + const lastSegment: Segment | undefined = segments.at(-1); + + React.useEffect(() => { + if (typeof widthProp === 'number') { + setWidth(widthProp); + } else { + setWidth(containerWidth); + } + }, [widthProp, containerWidth]); + + React.useEffect(() => { + let raf: number; + const start = performance.now(); + const end = start + ANIMATION_DURATION_MS + ANIMATION_DELAY_MS * (values.length - 1); + let currentSegments: Array = []; + const animate = () => { + const now = performance.now(); + currentSegments = calculateSegments(initialValuesRef.current, values, now - start, reverse); + if (shouldAnimate && now < end) { + raf = requestAnimationFrame(animate); // request next frame + } else { + currentSegments = calculateSegments(initialValuesRef.current, values, end - start, reverse); // set the final values + initialValuesRef.current = values; + } + setSegments(currentSegments); + }; + animate(); + return () => { + cancelAnimationFrame(raf); + // animation was cancelled, snapshot current values + initialValuesRef.current = currentSegments.map((s) => s.end - s.start); + }; + }, [radius, values, type, reverse, shouldAnimate]); + + const getX = React.useCallback( + (value: number) => + type === TYPE_LINEAR + ? lineCapRadius + maxValue * value + : CENTER_X - radius * Math.cos(value * maxValue), + [lineCapRadius, maxValue, radius, type] + ); + + const getY = React.useCallback( + (value: number) => + type === TYPE_LINEAR ? strokeWidth / 2 : CENTER_Y - radius * Math.sin(value * maxValue), + [maxValue, radius, strokeWidth, type] + ); + + const getColor = (index: number) => segmentColors[index % segmentColors.length]; + + const totalPercent = Math.round((lastSegment?.end || 0) * 100); + + const valueText = + t(meterTotalLabel, values.length, totalPercent) + + ' ' + + values.map((v, i) => `${t(meterSectionLabel, i + 1, Math.round(v * 100))}`).join('. '); + + return ( +
+ +
+ ); +}; + +/** + * This wrapper is to force a remount when some specific props change + */ +const Meter = (props: MeterProps): JSX.Element => { + return ; +}; + +export default Meter; diff --git a/src/navigation-bar.css.ts b/src/navigation-bar.css.ts index 7064f89452..6acfa945ab 100644 --- a/src/navigation-bar.css.ts +++ b/src/navigation-bar.css.ts @@ -2,11 +2,15 @@ import {style, styleVariants} from '@vanilla-extract/css'; import {sprinkles} from './sprinkles.css'; import {NAVBAR_HEIGHT_DESKTOP, NAVBAR_HEIGHT_DESKTOP_LARGE, NAVBAR_HEIGHT_MOBILE} from './theme'; import * as mq from './media-queries.css'; -import {vars as colorVars} from './skins/skin-contract.css'; +import {vars} from './skins/skin-contract.css'; const NAVBAR_ZINDEX = 25; -const BURGER_MENU_ANIMATION_DURATION_MS = 300; +export const DESKTOP_SMALL_MENU_WIDTH = 184; + +export const BURGER_MENU_ANIMATION_DURATION_MS = 300; +export const DESKTOP_MENU_ANIMATION_DURATION_MS = 400; +const DESKTOP_MENU_CONTENT_ANIMATION_DURATION_MS = 800; export const burgerIconContainer = style([ sprinkles({ @@ -96,12 +100,12 @@ const navbarBase = style([ ]); export const navbarBorderColorVariants = styleVariants({ - default: [navbarBase, {borderColor: colorVars.colors.divider}], + default: [navbarBase, {borderColor: vars.colors.divider}], noBorder: [navbarBase, {borderColor: 'transparent'}], menuOpen: [ navbarBase, { - borderColor: colorVars.colors.divider, + borderColor: vars.colors.divider, '@media': { [mq.tabletOrSmaller]: { @@ -112,6 +116,63 @@ export const navbarBorderColorVariants = styleVariants({ ], }); +export const desktopMenuFirstSection = style({}); +export const desktopMenuLastSection = style({}); + +export const desktopMenuSectionContainer = style([ + sprinkles({position: 'relative', display: 'flex'}), + { + '::after': { + content: '', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + }, + + selectors: { + // Add extra width on the left/right of interactive area so that we cover the space between sections + [`&:not(${desktopMenuFirstSection}):after`]: { + left: -16, + }, + [`&:not(${desktopMenuLastSection}):after`]: { + right: -16, + }, + }, + }, +]); + +export const desktopMenuSectionWithArrowWrapper = sprinkles({ + position: 'relative', +}); + +export const desktopMenuSectionArrowContainer = style([ + sprinkles({ + position: 'absolute', + top: 0, + bottom: 0, + display: 'flex', + alignItems: 'center', + }), + { + // Avoid element from affecting hover status of the section + zIndex: -1, + right: -8, + }, +]); + +export const desktopMenuSectionArrow = style([ + sprinkles({ + border: 'none', + background: 'transparent', + padding: 0, + }), + { + transition: `opacity 0.1s`, + }, +]); + export const section = style([ sprinkles({ height: NAVBAR_HEIGHT_DESKTOP, @@ -120,57 +181,63 @@ export const section = style([ paddingX: 8, border: 'none', background: 'transparent', + position: 'relative', }), { + zIndex: 1, borderBottom: `2px solid transparent`, transition: 'border-color 300ms ease-in-out', }, ]); export const selectedSectionVariantes = styleVariants({ - default: {borderColor: colorVars.colors.controlActivated}, - inverse: {borderColor: colorVars.colors.inverse}, + default: {borderColor: vars.colors.controlActivated}, + inverse: {borderColor: vars.colors.inverse}, }); export const textWrapperVariants = styleVariants({ default: { - color: colorVars.colors.textPrimary, + color: vars.colors.textPrimary, '@media': { [mq.supportsHover]: { ':hover': { - color: colorVars.colors.textSecondary, + color: vars.colors.textSecondary, }, }, }, }, inverse: { - color: colorVars.colors.textPrimaryInverse, + color: vars.colors.textPrimaryInverse, '@media': { [mq.supportsHover]: { ':hover': { - color: colorVars.colors.textSecondaryInverse, + color: vars.colors.textSecondaryInverse, }, }, }, }, }); -export const navigationBarContent = style({ - alignItems: 'center', - width: '100%', - display: 'flex', - height: NAVBAR_HEIGHT_DESKTOP, - '@media': { - [mq.tabletOrSmaller]: { - height: NAVBAR_HEIGHT_MOBILE - borderWidth, - }, - [mq.desktopOrBigger]: { - ':last-child': { - height: NAVBAR_HEIGHT_DESKTOP - borderWidth, +export const navigationBarContent = style([ + sprinkles({ + alignItems: 'center', + width: '100%', + display: 'flex', + }), + { + height: NAVBAR_HEIGHT_DESKTOP, + '@media': { + [mq.tabletOrSmaller]: { + height: NAVBAR_HEIGHT_MOBILE - borderWidth, + }, + [mq.desktopOrBigger]: { + ':last-child': { + height: NAVBAR_HEIGHT_DESKTOP - borderWidth, + }, }, }, }, -}); +]); export const navigationBarAction = sprinkles({ border: 'none', @@ -186,18 +253,38 @@ export const desktopOnly = style({ }, }); -export const navigationBarContentRight = style({ - display: 'flex', - flex: 1, - alignItems: 'center', - justifyContent: 'flex-end', - paddingLeft: 136, - '@media': { - [mq.tabletOrSmaller]: { - paddingLeft: 24, +export const navigationBarContentRight = style([ + sprinkles({ + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + }), + { + height: NAVBAR_HEIGHT_DESKTOP, + '@media': { + [mq.tabletOrSmaller]: { + paddingLeft: 24, + flex: 1, + height: NAVBAR_HEIGHT_MOBILE - borderWidth, + }, + [mq.desktopOrBigger]: { + ':last-child': { + height: NAVBAR_HEIGHT_DESKTOP - borderWidth, + }, + }, }, }, -}); +]); + +export const navigationBarContentRightExpanded = style([ + navigationBarContentRight, + sprinkles({ + flex: 1, + }), + { + paddingLeft: 136, + }, +]); const spacerMobile = style({ '@media': { @@ -221,34 +308,49 @@ export const spacerLarge = style([ spacerMobile, ]); -export const burgerMenuTransition = styleVariants({ - entering: { - transform: 'translate(0vw)', - }, - entered: { - transform: 'translate(0vw)', - }, - exiting: { +export const burgerMenuTransition = { + enter: style({ transform: 'translate(-100vw)', - }, - exited: { + }), + enterActive: style({ + transform: 'translate(0)', + transition: `transform ${BURGER_MENU_ANIMATION_DURATION_MS}ms ease-out`, + '@media': { + ['(prefers-reduced-motion)']: { + transition: 'none', + }, + }, + }), + exit: style({ + transform: 'translate(0)', + }), + exitActive: style({ transform: 'translate(-100vw)', - }, - unmounted: {}, -}); + transition: `transform ${BURGER_MENU_ANIMATION_DURATION_MS}ms ease-out`, + '@media': { + ['(prefers-reduced-motion)']: { + transition: 'none', + }, + }, + }), +}; -export const mainNavbarContent = style({ +export const mainNavbarContent = sprinkles({ display: 'flex', alignItems: 'center', }); +export const mainNavBarSectionsContainer = style([ + sprinkles({display: 'flex', flex: 1}), + {minWidth: 'fit-content'}, +]); + export const logoContainer = style([ sprinkles({ display: 'flex', justifyContent: 'center', }), { - marginRight: 48, '@media': { [mq.tabletOrSmaller]: { marginRight: 0, @@ -259,6 +361,7 @@ export const logoContainer = style([ export const burgerMenuButton = style({ marginRight: 24, + width: 'fit-content', '@media': { [mq.desktopOrBigger]: { display: 'none', @@ -266,41 +369,58 @@ export const burgerMenuButton = style({ }, }); -export const burgerMenu = style([ +export const burgerMenu = sprinkles({ + position: 'fixed', + top: NAVBAR_HEIGHT_MOBILE, + left: 0, + right: 0, + bottom: 0, + background: vars.colors.background, +}); + +export const burgerMenuContainer = sprinkles({ + height: '100%', + position: 'relative', +}); + +export const burgerMenuContentContainer = style([ sprinkles({ - position: 'fixed', - top: NAVBAR_HEIGHT_MOBILE, - left: 0, - right: 0, - background: colorVars.colors.background, + overflowY: 'auto', + width: '100%', + height: '100%', + position: 'absolute', + top: 0, }), { - height: `calc(100vh - ${NAVBAR_HEIGHT_MOBILE}px)`, - overflowY: 'auto', transition: `transform ${BURGER_MENU_ANIMATION_DURATION_MS}ms ease-out`, + '@media': { + ['(prefers-reduced-motion)']: { + transition: 'none', + }, + }, }, ]); export const iconButtonVariants = styleVariants({ default: [ - sprinkles({color: colorVars.colors.neutralHigh}), + sprinkles({color: vars.colors.neutralHigh}), { '@media': { [mq.supportsHover]: { ':hover': { - color: colorVars.colors.neutralMedium, + color: vars.colors.neutralMedium, }, }, }, }, ], inverse: [ - sprinkles({color: colorVars.colors.inverse}), + sprinkles({color: vars.colors.inverse}), { '@media': { [mq.supportsHover]: { ':hover': { - color: colorVars.colors.inverse, + color: vars.colors.inverse, }, }, }, @@ -313,3 +433,97 @@ export const lineHeightFix = style({ // use display inline and other components like Badge use inline-block. lineHeight: 0, }); + +export const mainNavigationBarContentWrapper = style([ + sprinkles({width: '100%'}), + { + transition: `clip-path ${DESKTOP_MENU_ANIMATION_DURATION_MS}ms cubic-bezier(0.65, 0, 0.35, 1)`, + '@media': { + ['(prefers-reduced-motion)']: { + transition: 'none', + }, + }, + }, +]); + +export const desktopMenuWrapper = sprinkles({ + position: 'absolute', + left: 0, + right: 0, +}); + +export const desktopMenuContainer = style([ + sprinkles({ + position: 'fixed', + left: 0, + right: 0, + }), + { + zIndex: NAVBAR_ZINDEX, + }, +]); + +export const desktopMenuBackgroundContainer = style([ + sprinkles({ + background: vars.colors.backgroundContainer, + position: 'absolute', + left: 0, + right: 0, + }), + { + transition: `height ${DESKTOP_MENU_ANIMATION_DURATION_MS}ms cubic-bezier(0.65, 0, 0.35, 1)`, + boxShadow: '0px 2px 4px rgba(0,0,0,0.2)', + '@media': { + ['(prefers-reduced-motion)']: { + transition: 'none', + }, + }, + }, +]); + +export const desktopSmallMenuContainer = style([ + sprinkles({ + background: vars.colors.backgroundContainer, + position: 'fixed', + paddingY: 40, + paddingX: 24, + overflowY: 'auto', + }), + { + zIndex: NAVBAR_ZINDEX, + borderRadius: `0 0 ${vars.borderRadii.popup} ${vars.borderRadii.popup}`, + width: DESKTOP_SMALL_MENU_WIDTH, + boxShadow: '0px 2px 4px rgba(0,0,0,0.2)', + }, +]); + +export const desktopMenu = style([ + sprinkles({ + paddingY: 40, + position: 'relative', + }), + { + transform: 'translateY(-16px)', + opacity: 0, + '@media': { + ['(prefers-reduced-motion)']: { + transition: 'none', + }, + }, + }, +]); + +export const desktopMenuContentFadeIn = style({ + transform: 'translateY(0)', + opacity: 1, + transition: `opacity ${DESKTOP_MENU_CONTENT_ANIMATION_DURATION_MS}ms cubic-bezier(0.33, 1, 0.68, 1), transform ${DESKTOP_MENU_CONTENT_ANIMATION_DURATION_MS}ms cubic-bezier(0.33, 1, 0.68, 1)`, + '@media': { + ['(prefers-reduced-motion)']: { + transition: 'none', + }, + }, +}); + +export const desktopMenuColumnItem = style({ + color: vars.colors.textPrimary, +}); diff --git a/src/navigation-bar.tsx b/src/navigation-bar.tsx index 709a71b4c0..5fc78f82f1 100644 --- a/src/navigation-bar.tsx +++ b/src/navigation-bar.tsx @@ -1,8 +1,8 @@ 'use client'; import * as React from 'react'; -import {Transition} from 'react-transition-group'; +import {CSSTransition} from 'react-transition-group'; import classnames from 'classnames'; -import ResponsiveLayout from './responsive-layout'; +import ResponsiveLayout, {ResetResponsiveLayout} from './responsive-layout'; import Inline from './inline'; import Touchable, {BaseTouchable} from './touchable'; import {Text2, Text3} from './text'; @@ -11,7 +11,6 @@ import IconMenuRegular from './generated/mistica-icons/icon-menu-regular'; import IconCloseRegular from './generated/mistica-icons/icon-close-regular'; import IconChevronLeftRegular from './generated/mistica-icons/icon-chevron-left-regular'; import {IconButton} from './icon-button'; -import NegativeBox from './negative-box'; import {Row, RowList} from './list'; import {ThemeVariant, useIsInverseOrMediaVariant} from './theme-variant-context'; import FocusTrap from './focus-trap'; @@ -21,15 +20,35 @@ import {useSetModalState} from './modal-context-provider'; import {Logo} from './logo'; import {vars} from './skins/skin-contract.css'; import * as styles from './navigation-bar.css'; -import {getPrefixedDataAttributes} from './utils/dom'; +import {cancelEvent, getPrefixedDataAttributes} from './utils/dom'; import Stack from './stack'; import Box from './box'; import {isRunningAcceptanceTest} from './utils/platform'; import * as tokens from './text-tokens'; +import {NAVBAR_HEIGHT_DESKTOP, NAVBAR_HEIGHT_DESKTOP_LARGE} from './theme'; +import TextLink from './text-link'; +import {Title1, Title3} from './title'; +import {ButtonLink} from './button'; +import {Grid, GridItem} from './grid'; +import {DOWN, ESC, UP} from './utils/keys'; +import {debounce, isEqual} from './utils/helpers'; +import NegativeBox from './negative-box'; +import type {ExclusifyUnion} from './utils/utility-types'; import type {Variant} from './theme-variant-context'; import type {TouchableProps} from './touchable'; -import type {DataAttributes, HeadingType} from './utils/types'; +import type {DataAttributes, HeadingType, IconProps} from './utils/types'; + +const MAIN_NAVIGATION_BAR_MENU_DEBOUNCE_TIME = 120; + +const MenuSectionArrow = ({size = 24, color = vars.colors.neutralHigh, style, className}: IconProps) => ( + + + +); const BurgerMenuIcon = ({isOpen}: {isOpen: boolean}) => { return ( @@ -44,14 +63,12 @@ const BurgerMenuIcon = ({isOpen}: {isOpen: boolean}) => { ); }; -const BURGER_MENU_ANIMATION_DURATION_MS = 300; - type HeaderProps = { children: React.ReactNode; topFixed?: boolean; variant?: Variant; withBorder?: boolean; - isMenuOpen?: boolean; + isBurgerMenuOpen?: boolean; dataAttributes?: DataAttributes; isBottomRow?: boolean; }; @@ -60,7 +77,7 @@ const Header = ({ children, topFixed, withBorder, - isMenuOpen, + isBurgerMenuOpen, variant = 'default', dataAttributes, }: HeaderProps) => { @@ -69,7 +86,7 @@ const Header = ({ const getBorderClass = () => { const inverse = variant === 'inverse' && !isDarkMode; if (inverse || !withBorder) return styles.navbarBorderColorVariants.noBorder; - if (isMenuOpen) return styles.navbarBorderColorVariants.menuOpen; + if (isBurgerMenuOpen) return styles.navbarBorderColorVariants.menuOpen; return styles.navbarBorderColorVariants.default; }; @@ -98,27 +115,152 @@ type NavigationBarContentContainerProps = { right?: React.ReactNode; children?: React.ReactNode; desktopOnly?: boolean; + expandRightContent?: boolean; }; -const NavigationBarContentContainer = ({ +const NavigationBarContentContainer = React.forwardRef( + ({right, children, desktopOnly, expandRightContent}, ref) => { + return ( +
+ {children} + {right && ( +
+ {right} +
+ )} +
+ ); + } +); + +interface NavigationBarCommonProps { + variant?: Variant; + onBack?: () => void; + title?: string; + titleAs?: HeadingType; + right?: React.ReactElement; + withBorder?: boolean; + children?: undefined; +} + +interface NavigationBarTopFixedProps extends NavigationBarCommonProps { + topFixed?: true; + paddingX?: undefined; +} + +interface NavigationBarNotFixedProps extends NavigationBarCommonProps { + topFixed: false; + paddingX?: number; +} + +type NavigationBarProps = NavigationBarTopFixedProps | NavigationBarNotFixedProps; + +export const NavigationBar = ({ + onBack, + title, + titleAs, right, - children, - desktopOnly, -}: NavigationBarContentContainerProps) => { + variant = 'default', + topFixed = true, + paddingX = 0, + withBorder = true, +}: NavigationBarProps): JSX.Element => { + const {texts, t} = useTheme(); + const content = ( + + + {onBack && ( + + )} + + {title} + + + + ); return ( -
- {children} - {right &&
{right}
} -
+ +
+ {topFixed ? ( + {content} + ) : ( +
+ {content} +
+ )} +
+ {topFixed &&
} + ); }; -type MainNavigationBarSection = - | {href: string; to?: undefined; onPress?: undefined; title: string} - | {to: string; href?: undefined; onPress?: undefined; title: string} - | {onPress: () => void; to?: undefined; href?: undefined; title: string}; +type InteractiveProps = ExclusifyUnion<{href: string} | {to: string} | {onPress: () => void}>; +type MaybeInteractiveProps = ExclusifyUnion<{href?: string} | {to?: string} | {onPress?: () => void}>; + +type SectionItem = {title: string} & InteractiveProps; + +type SectionColumn = { + title: string; + items: ReadonlyArray; +}; + +type SectionMenu = ExclusifyUnion< + | {columns: ReadonlyArray} + // Content prop can receive a function as value with the closeMenu callback as parameter. + // In this way, custom content can also force the menu to close programmatically. + | {content?: React.ReactElement | ((props: {closeMenu: () => void}) => React.ReactElement)} +>; -type MainNavigationBarPropsBase = { +const getInteractivePropsWithCloseMenu = (interactiveProps: InteractiveProps, closeMenu: () => void) => { + if ( + interactiveProps.href === undefined && + interactiveProps.onPress === undefined && + interactiveProps.to === undefined + ) { + return {onPress: closeMenu}; + } + + return interactiveProps.onPress + ? { + onPress: () => { + interactiveProps.onPress(); + closeMenu(); + }, + } + : {...interactiveProps, onNavigate: () => closeMenu()}; +}; + +type MainNavigationBarSection = { + title: string; + menu?: SectionMenu; +} & MaybeInteractiveProps; + +type MainNavigationBarProps = { sections?: ReadonlyArray; selectedIndex?: number; right?: React.ReactElement; @@ -129,11 +271,1055 @@ type MainNavigationBarPropsBase = { withBorder?: boolean; burgerMenuExtra?: React.ReactNode; large?: boolean; + desktopLargeMenu?: boolean; +}; + +type MainNavigationBarMenuStatus = 'opening' | 'opened' | 'closing' | 'closed'; +type MainNavigationBarMenuAction = 'open' | 'finishOpen' | 'close' | 'finishClose'; + +const mainNavigationBurgerMenuTranstions: Record< + MainNavigationBarMenuStatus, + Partial> +> = { + opening: { + close: 'closing', + finishOpen: 'opened', + }, + opened: { + close: 'closing', + }, + closing: { + open: 'opening', + finishClose: 'closed', + }, + closed: { + open: 'opening', + }, +}; + +const burgerMenuReducer = (state: MainNavigationBarMenuStatus, action: MainNavigationBarMenuAction) => { + return mainNavigationBurgerMenuTranstions[state][action] || state; +}; + +const MainNavigationBarBurgerSection = ({ + section, + closeSubMenu, + closeMenu, +}: { + section: MainNavigationBarSection; + closeSubMenu: () => void; + closeMenu: () => void; +}) => { + const {texts, t} = useTheme(); + + const {title, menu, ...interactiveProps} = section; + + const columns = menu?.columns || []; + const customContent = menu?.content; + const hasCustomInteraction = + interactiveProps.href !== undefined || + interactiveProps.onPress !== undefined || + interactiveProps.to !== undefined; + + return ( + + + + + + {texts.mainNavigationBarSectionSeeAll || + t(tokens.mainNavigationBarSectionSeeAll)} + + ) : undefined + } + > + {title} + + + + {customContent ? ( + + {typeof customContent === 'function' ? customContent({closeMenu}) : customContent} + + ) : ( + columns.map((column, columnIndex) => ( + + {column.title} + + + {column.items.map( + ({title: itemTitle, ...itemInteractiveProps}, itemIndex) => ( + + ) + )} + + + + )) + )} + + + ); +}; + +const MainNavigationBarBurgerMenu = ({ + sections, + extra, + closeMenu, + open, + id, + disableFocusTrap, + setDisableFocusTrap, +}: { + sections: ReadonlyArray; + extra: React.ReactNode; + closeMenu: () => void; + open: boolean; + id: string; + disableFocusTrap: boolean; + setDisableFocusTrap: (value: boolean) => void; +}) => { + const {isDarkMode, texts, t} = useTheme(); + const [openedSection, setOpenedSection] = React.useState(-1); + const [isSubMenuOpen, setIsSubMenuOpen] = React.useState(false); + const [subMenuStatus, dispatch] = React.useReducer(burgerMenuReducer, 'closed'); + const menuRef = React.useRef(null); + + const shadowAlpha = isDarkMode ? 1 : 0.2; + const menuAnimationDuration = isRunningAcceptanceTest() ? 0 : styles.BURGER_MENU_ANIMATION_DURATION_MS; + + React.useEffect(() => { + let id: NodeJS.Timeout; + + // menu starts opening or closing + if (isSubMenuOpen) { + dispatch('open'); + id = setTimeout(() => dispatch('finishOpen'), menuAnimationDuration); + } else { + dispatch('close'); + id = setTimeout(() => dispatch('finishClose'), menuAnimationDuration); + } + + return () => clearTimeout(id); + }, [isSubMenuOpen, menuAnimationDuration]); + + const sectionContainerRef = React.useRef(null); + + React.useEffect(() => { + // Make screen reader focus on back button when opening any section's menu + if (subMenuStatus === 'opening') { + const sectionBackButtonElement = sectionContainerRef.current?.querySelector( + `button[aria-label="${texts.backNavigationBar || t(tokens.backNavigationBar)}"]` + ); + + sectionBackButtonElement?.focus(); + } + }, [subMenuStatus, t, texts]); + + return ( + + + setDisableFocusTrap(false)} + onExiting={() => setDisableFocusTrap(true)} + onExited={() => { + setIsSubMenuOpen(false); + setOpenedSection(-1); + }} + classNames={styles.burgerMenuTransition} + in={open} + nodeRef={menuRef} + timeout={menuAnimationDuration} + mountOnEnter + unmountOnExit + > + + + + + ); +}; + +const mainNavigationDesktopMenuTranstions: Record< + MainNavigationBarMenuStatus, + Partial> +> = { + opening: { + close: 'closing', + finishOpen: 'opened', + }, + opened: { + close: 'closing', + }, + closing: { + // If a section was opened while the menu was closing, the menu should be considered as + // already open. This is useful for example to avoid the new content's fade-in animation + open: 'opened', + finishClose: 'closed', + }, + closed: { + open: 'opening', + }, +}; + +const desktopMenuReducer = (state: MainNavigationBarMenuStatus, action: MainNavigationBarMenuAction) => { + return mainNavigationDesktopMenuTranstions[state][action] || state; +}; + +type MainNavigationBarDesktopMenuState = { + isMenuOpen: boolean; + openedSection: number; + menuHeight: string; + menuStatus: MainNavigationBarMenuStatus; + openSectionMenu: (index: number) => void; + closeMenu: () => void; + setMenuHeight: (height: string) => void; + setIsMenuHovered: (value: boolean) => void; + setFocusedItem: (item?: {column: number; index: number}) => void; + debouncedOpenSectionMenu: (index: number) => void; + cancelDebouncedOpenSectionMenu: (index: number) => void; +}; + +const MainNavigationBarDesktopMenuContext = React.createContext({ + isMenuOpen: false, + openedSection: -1, + menuHeight: '0px', + menuStatus: 'closed', + openSectionMenu: () => {}, + closeMenu: () => {}, + setMenuHeight: () => {}, + setIsMenuHovered: () => {}, + setFocusedItem: () => {}, + debouncedOpenSectionMenu: () => {}, + cancelDebouncedOpenSectionMenu: () => {}, +}); + +const MainNavigationBarDesktopMenuContextProvider = ({ + children, + sections, + isLargeMenu, +}: { + children: React.ReactNode; + sections?: ReadonlyArray; + isLargeMenu?: boolean; +}): JSX.Element => { + const {isTabletOrSmaller} = useScreenSize(); + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const [menuHeight, setMenuHeight] = React.useState('0px'); + const [menuStatus, dispatch] = React.useReducer(desktopMenuReducer, 'closed'); + const [debouncedOpenSectionIndex, setDebouncedOpenSectionIndex] = React.useState(-1); + + // Item that is currently focused inside a section. This state is used to handle pressing + // up/down arrows to navigate through the items of a section. + const [focusedItem, setFocusedItem] = React.useState<{column: number; index: number} | undefined>(); + + // State that indicated whether the menu container has been hovered + const [isMenuHovered, setIsMenuHovered] = React.useState(false); + + // State that indicates whether the current rendered section has been hovered or its arrow button is focused + const [isSectionHovered, setIsSectionHovered] = React.useState(false); + + // Section that is currently being rendered + const [openedSection, setOpenedSection] = React.useState(-1); + + // Callback used when a section has been hovered or it's focused arrow has been pressed while it's closed + const openSectionMenu = React.useCallback( + (index: number) => { + setDebouncedOpenSectionIndex(-1); + if (sections?.[index]?.menu) { + setIsSectionHovered(true); + setOpenedSection(index); + } else { + // If the section has no menu, close the current opened one + setIsMenuHovered(false); + setIsSectionHovered(false); + } + }, + [sections] + ); + + const debouncedOpenSectionMenu = React.useMemo( + () => debounce(openSectionMenu, MAIN_NAVIGATION_BAR_MENU_DEBOUNCE_TIME), + [openSectionMenu] + ); + + const closeMenu = React.useCallback(() => { + setIsMenuHovered(false); + setIsSectionHovered(false); + debouncedOpenSectionMenu.cancel(); + setDebouncedOpenSectionIndex(-1); + }, [debouncedOpenSectionMenu]); + + // Close menu when viewport is too small + React.useEffect(() => { + if (isTabletOrSmaller) { + closeMenu(); + } + }, [isTabletOrSmaller, closeMenu]); + + React.useEffect(() => { + if (!isSectionHovered && !isMenuHovered) { + setIsMenuOpen(false); + setMenuHeight('0px'); + } else { + setIsMenuOpen(true); + } + }, [isMenuHovered, isSectionHovered]); + + React.useEffect(() => { + const menuAnimationDuration = + isRunningAcceptanceTest() || !isLargeMenu ? 0 : styles.DESKTOP_MENU_ANIMATION_DURATION_MS; + + let id: NodeJS.Timeout; + + // menu starts opening or closing + if (!isMenuOpen) { + dispatch('close'); + id = setTimeout(() => dispatch('finishClose'), menuAnimationDuration); + } else { + dispatch('open'); + id = setTimeout(() => dispatch('finishOpen'), menuAnimationDuration); + } + + return () => clearTimeout(id); + }, [isMenuOpen, isLargeMenu]); + + React.useEffect(() => { + // reset openedSection when the menu has been closed + if (menuStatus === 'closed') { + setOpenedSection(-1); + } + }, [menuStatus]); + + const focusItem = React.useCallback( + (item: {column: number; index: number} | undefined) => { + if (!isEqual(focusedItem, item)) { + setFocusedItem(item); + } + }, + [focusedItem] + ); + + React.useEffect(() => { + // Find all the items of the section and focus the next (or previous) element + const focusNextItem = (reverse?: boolean) => { + if (focusedItem) { + const itemsContainer = document.querySelector('[data-navigation-bar-menu-items]'); + const itemsList = Array.from(itemsContainer?.querySelectorAll('a,button') || []); + + const currentIndex = itemsList.findIndex((el) => + el.hasAttribute( + `data-navigation-bar-menu-item-${focusedItem.column}-${focusedItem.index}` + ) + ); + + const nextIndex = reverse ? currentIndex - 1 : currentIndex + 1; + (itemsList[(nextIndex + itemsList.length) % itemsList.length] as HTMLElement).focus(); + } + }; + + const handleKeyDown = (e: KeyboardEvent) => { + switch (e.key) { + case DOWN: + if (focusedItem) { + cancelEvent(e); + focusNextItem(); + } + break; + + case UP: + if (focusedItem) { + cancelEvent(e); + focusNextItem(true); + } + break; + + case ESC: + closeMenu(); + break; + + default: + // Do nothing + } + }; + // Close menu when ESC key is pressed + document.addEventListener('keydown', handleKeyDown, false); + return () => { + document.removeEventListener('keydown', handleKeyDown, false); + }; + }, [closeMenu, focusedItem]); + + React.useEffect(() => { + // Restore focusedItem when opened section changes (or when the menu is closed) + setFocusedItem(undefined); + }, [openedSection]); + + return ( + { + setDebouncedOpenSectionIndex(index); + debouncedOpenSectionMenu(index); + }, + cancelDebouncedOpenSectionMenu: (index: number) => { + if (index === debouncedOpenSectionIndex) { + debouncedOpenSectionMenu.cancel(); + setDebouncedOpenSectionIndex(-1); + } + }, + closeMenu, + setMenuHeight, + setIsMenuHovered, + setFocusedItem: focusItem, + }} + > + {children} + + ); +}; + +export const useMainNavigationBarDesktopMenuState = (): MainNavigationBarDesktopMenuState => + React.useContext(MainNavigationBarDesktopMenuContext); + +const MainNavigationBarDesktopMenuSectionColumn = ({ + column, + columnIndex, +}: { + column: SectionColumn; + columnIndex: number; +}) => { + const {setFocusedItem, closeMenu} = useMainNavigationBarDesktopMenuState(); + + return ( + + + {column.title} + + + + {column.items.map(({title, ...touchableProps}, itemIdx) => ( + // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions +
setFocusedItem({column: columnIndex, index: itemIdx})} + onBlur={() => setFocusedItem(undefined)} + role="listitem" + > + + {title} + +
+ ))} +
+
+ ); +}; + +const MainNavigationBarDesktopMenuContent = ({ + section, + index, + isLargeNavigationBar, +}: { + section: MainNavigationBarSection; + index: number; + isLargeNavigationBar: boolean; +}): JSX.Element => { + const menuRef = React.useRef(null); + const [isMenuContentScrollable, setIsMenuContentScrollable] = React.useState(false); + + const menuAnimationDuration = isRunningAcceptanceTest() ? 0 : styles.DESKTOP_MENU_ANIMATION_DURATION_MS; + const topSpace = isLargeNavigationBar ? NAVBAR_HEIGHT_DESKTOP_LARGE : NAVBAR_HEIGHT_DESKTOP; + const bottomSpace = 40; + + const {menuStatus, isMenuOpen, openedSection, closeMenu, setIsMenuHovered, setMenuHeight} = + useMainNavigationBarDesktopMenuState(); + + React.useEffect(() => { + // Scroll to top of the content if the opened section changed + if (menuRef.current && isMenuOpen) { + menuRef.current.scrollTop = 0; + } + + // Disable scroll in menu content until height's animation is finished to avoid + // showing the scrollbar while the menu's container is changing it's height + setIsMenuContentScrollable(false); + if (isMenuOpen) { + const id = setTimeout(() => setIsMenuContentScrollable(true), menuAnimationDuration); + return () => clearTimeout(id); + } + }, [isMenuOpen, openedSection, menuAnimationDuration]); + + const [isContentVisible, setIsContentVisible] = React.useState(true); + + React.useEffect(() => { + if (openedSection === index) { + // If menu is opening, trigger the fade-in effect for current section + if (menuStatus === 'opening') { + setIsContentVisible(false); + const id = requestAnimationFrame(() => setIsContentVisible(true)); + return () => cancelAnimationFrame(id); + } else { + setIsContentVisible(true); + } + } + }, [menuStatus, openedSection, index]); + + React.useEffect(() => { + // disable scroll when menu is closing to avoid showing the scrollbar + if (menuStatus === 'closing') { + setIsMenuContentScrollable(false); + } + }, [menuStatus]); + + const columns = section.menu?.columns || []; + const customContent = section?.menu?.content; + + return ( +
+ + {openedSection === index && ( + +
setIsMenuHovered(true)} + onMouseLeave={() => setIsMenuHovered(false)} + style={{ + // disable pointer events when menu is closing + pointerEvents: + menuStatus === 'closed' || menuStatus === 'closing' ? 'none' : undefined, + top: topSpace, + maxHeight: `calc(100vh - ${topSpace}px - ${bottomSpace}px)`, + overflowY: isMenuContentScrollable ? 'auto' : 'hidden', + }} + > + +
{ + if (el && isMenuOpen) { + setMenuHeight( + `min(${el.scrollHeight}px, calc(100vh - ${topSpace}px - ${bottomSpace}px))` + ); + } + }} + > + {customContent ? ( + typeof customContent === 'function' ? ( + customContent({closeMenu}) + ) : ( + customContent + ) + ) : ( + + {columns.map((column, columnIdx) => ( + + + + ))} + + )} +
+
+
+
+ )} +
+
+ ); +}; + +// This is the menu's background panel. The menu content is rendered separately for each tab +// in order to make the section's content follow the natural focus order of elements +// when using the keyboard or a screen reader to navigate +const MainNavigationBarDesktopMenuBackground = ({ + isLargeNavigationBar, +}: { + isLargeNavigationBar: boolean; +}): JSX.Element => { + const topSpace = isLargeNavigationBar ? NAVBAR_HEIGHT_DESKTOP_LARGE : NAVBAR_HEIGHT_DESKTOP; + const {menuHeight} = useMainNavigationBarDesktopMenuState(); + + return ( +
+
+
+
+
+ ); +}; + +const MainNavigationBarDesktopSmallMenu = ({ + section, + isLargeNavigationBar, + leftPosition, + index, +}: { + section: MainNavigationBarSection; + isLargeNavigationBar: boolean; + leftPosition: number; + index: number; +}): JSX.Element => { + const topSpace = isLargeNavigationBar ? NAVBAR_HEIGHT_DESKTOP_LARGE : NAVBAR_HEIGHT_DESKTOP; + const bottomSpace = 40; + + const columns = section.menu?.columns || []; + const customContent = section?.menu?.content; + + const {openedSection, menuStatus, setIsMenuHovered, closeMenu} = useMainNavigationBarDesktopMenuState(); + + return ( +
+ {index === openedSection && ( + +
setIsMenuHovered(true)} + onMouseLeave={() => setIsMenuHovered(false)} + style={{ + // disable pointer events when menu is closing + pointerEvents: + menuStatus === 'closed' || menuStatus === 'closing' ? 'none' : undefined, + top: topSpace, + left: leftPosition, + maxHeight: `calc(100vh - ${topSpace}px - ${bottomSpace}px)`, + }} + > + {customContent ? ( + typeof customContent === 'function' ? ( + customContent({closeMenu}) + ) : ( + customContent + ) + ) : ( + + {columns.map((column, columnIdx) => ( + + ))} + + )} +
+
+ )} +
+ ); +}; + +const MainNavigationBarDesktopSection = ({ + section, + index, + selectedIndex, + isFirstSection, + isLastSection, + navigationBarRef, + variant, + isLargeNavigationBar, + desktopLargeMenu, +}: { + section: MainNavigationBarSection; + index: number; + selectedIndex?: number; + isFirstSection: boolean; + isLastSection: boolean; + navigationBarRef: React.RefObject; + variant?: Variant; + isLargeNavigationBar: boolean; + desktopLargeMenu?: boolean; +}): JSX.Element => { + const {texts, t} = useTheme(); + const {title, menu, ...touchableProps} = section; + const sectionRef = React.useRef(null); + const [smallMenuLeftPosition, setSmallMenuLeftPosition] = React.useState(0); + const [isMenuControlFocused, setIsMenuControlFocused] = React.useState(false); + const { + isMenuOpen, + openedSection, + openSectionMenu, + debouncedOpenSectionMenu, + cancelDebouncedOpenSectionMenu, + closeMenu, + } = useMainNavigationBarDesktopMenuState(); + + const hasCustomInteraction = + touchableProps.href !== undefined || + touchableProps.onPress !== undefined || + touchableProps.to !== undefined; + + const openCurrentSectionMenu = React.useCallback( + (withDebounce?: boolean) => { + // Align small menu to left border of the section if it fits. Otherwise, align it to the right border + const getSmallMenuLeftPosition = () => { + const {left, right} = sectionRef.current?.getBoundingClientRect() || {left: 0, right: 0}; + const maxLeftOffset = + (navigationBarRef.current?.getBoundingClientRect().right || 0) - + styles.DESKTOP_SMALL_MENU_WIDTH; + + return left <= maxLeftOffset ? left : right - styles.DESKTOP_SMALL_MENU_WIDTH; + }; + if (!desktopLargeMenu) { + setSmallMenuLeftPosition(getSmallMenuLeftPosition()); + } + + if (withDebounce) { + debouncedOpenSectionMenu(index); + } else { + openSectionMenu(index); + } + }, + [desktopLargeMenu, index, openSectionMenu, debouncedOpenSectionMenu, navigationBarRef] + ); + + React.useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + switch (e.key) { + // If arrow is focused and DOWN key is pressed, open the menu if it was closed + case DOWN: + if (isMenuControlFocused) { + cancelEvent(e); + openCurrentSectionMenu(); + } + break; + + // If arrow is focused and UP key is pressed, close the menu if it was opened + case UP: + if (isMenuControlFocused) { + cancelEvent(e); + closeMenu(); + } + break; + + default: + // Do nothing + } + }; + + document.addEventListener('keydown', handleKeyDown, false); + return () => { + document.removeEventListener('keydown', handleKeyDown, false); + }; + }, [index, isMenuControlFocused, openCurrentSectionMenu, closeMenu, menu, hasCustomInteraction]); + + const isSectionMenuOpen = isMenuOpen && openedSection === index; + + const menuButtonOnPress = React.useCallback(() => { + if (isSectionMenuOpen) { + closeMenu(); + } else { + openCurrentSectionMenu(); + } + }, [isSectionMenuOpen, openCurrentSectionMenu, closeMenu]); + + const getSectionInteractiveProps = React.useCallback( + (touchableProps: InteractiveProps) => { + // Open or close the menu when a section without interaction is pressed + if (!hasCustomInteraction) { + return { + onPress: menuButtonOnPress, + }; + } + + return touchableProps as InteractiveProps; + }, + [hasCustomInteraction, menuButtonOnPress] + ); + + return ( +
+
openCurrentSectionMenu(true)} + onMouseLeave={() => cancelDebouncedOpenSectionMenu(index)} + onFocus={() => { + if (menu && !hasCustomInteraction) setIsMenuControlFocused(true); + }} + onBlur={() => { + if (menu && !hasCustomInteraction) setIsMenuControlFocused(false); + }} + > + + + {title} + + +
+ {menu && ( + <> + {hasCustomInteraction && ( +
setIsMenuControlFocused(true)} + onBlur={() => setIsMenuControlFocused(false)} + > + { + if (isMenuControlFocused) { + menuButtonOnPress(); + } + }} + style={{ + pointerEvents: isMenuControlFocused ? 'auto' : 'none', + opacity: isMenuControlFocused ? 1 : 0, + // We are using the same chevron as in ButtonLink, and that svg has + // some extra space on the left that we want to ignore in this case + marginTop: -2, + }} + > + + +
+ )} + {desktopLargeMenu ? ( + + ) : ( + + )} + + )} +
+ ); +}; + +const MainNavigationBarDesktopSections = ({ + sections, + selectedIndex, + navigationBarRef, + variant, + isLargeNavigationBar, + hasRightContent, + desktopLargeMenu, +}: { + sections: ReadonlyArray; + selectedIndex?: number; + navigationBarRef: React.RefObject; + variant: Variant; + hasRightContent: boolean; + isLargeNavigationBar: boolean; + desktopLargeMenu: boolean; +}): JSX.Element => { + const {openSectionMenu, openedSection, closeMenu} = useMainNavigationBarDesktopMenuState(); + + return ( + // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions + + ); }; -type MainNavigationBarProps = MainNavigationBarPropsBase; +// It's not easy to coordinate the animation of the menu content height when switching between opened +// sections. This is because each section has it's own element where it displays the content. Instead, +// the contents of the sections are rendered without any animation, and we keep this wrapper around +// all of them, which "hides" the rendered smoothly by using animated clip-path +const MainNavigationBarContentWrapper = ({ + children, + isLargeNavigationBar, + desktopLargeMenu, +}: { + children: React.ReactNode; + isLargeNavigationBar: boolean; + desktopLargeMenu: boolean; +}): JSX.Element => { + const {menuHeight} = useMainNavigationBarDesktopMenuState(); + const topSpace = isLargeNavigationBar ? NAVBAR_HEIGHT_DESKTOP_LARGE : NAVBAR_HEIGHT_DESKTOP; -type MenuTransitionState = 'closed' | 'opening' | 'open' | 'closing'; + return ( +
+ {children} +
+ ); +}; export const MainNavigationBar = ({ sections = [], @@ -145,58 +1331,41 @@ export const MainNavigationBar = ({ burgerMenuExtra, logo, large = false, + desktopLargeMenu = false, }: MainNavigationBarProps): JSX.Element => { - const {texts, isDarkMode, t} = useTheme(); - const [isMenuOpen, setIsMenuOpen] = React.useState(false); - const [menuTransitionState, setMenuTransitionState] = React.useState('closed'); + const {texts, t} = useTheme(); const menuId = React.useId(); - const shadowAlpha = isDarkMode ? 1 : 0.2; const {isTabletOrSmaller} = useScreenSize(); - const setModalState = useSetModalState(); const logoElement = logo || ; + const hasBottomSections = large && sections.length > 0; - const renderDesktopSections = () => { - return ( - - ); - }; + const [isBurgerMenuOpen, setIsBurgerMenuOpen] = React.useState(false); + const [disableFocusTrap, setDisableFocusTrap] = React.useState(true); + const navigationBarRef = React.useRef(null); + const setModalState = useSetModalState(); - const hasBottomSections = large && sections.length > 0; + const desktopSections = ( + + ); const openMenu = () => { - setIsMenuOpen(true); + setIsBurgerMenuOpen(true); setModalState({isModalOpen: true}); }; const closeMenu = () => { - setIsMenuOpen(false); + setIsBurgerMenuOpen(false); setModalState({isModalOpen: false}); }; - const disableFocusTrap = menuTransitionState !== 'open'; - const showBurger = sections.length > 1; const mainNavBar = ( @@ -204,192 +1373,75 @@ export const MainNavigationBar = ({
- - -
+ {desktopLargeMenu && ( + + )} + + + {showBurger && ( - + )}
{logoElement}
- {!hasBottomSections && renderDesktopSections()} -
-
- {hasBottomSections && ( - - {renderDesktopSections()} + {!hasBottomSections && desktopSections} - )} -
+ {hasBottomSections && ( + + {desktopSections} + + )} + +
{topFixed &&
} ); - if (!isTabletOrSmaller) { - return mainNavBar; - } - return ( - <> - - {mainNavBar} - - {showBurger && ( - + + {!isTabletOrSmaller ? ( + mainNavBar + ) : ( + <> - { - setMenuTransitionState('opening'); - }} - onEntered={() => { - setMenuTransitionState('open'); - }} - onExiting={() => { - setMenuTransitionState('closing'); - }} - onExited={() => { - setMenuTransitionState('closed'); - }} - in={isMenuOpen} - timeout={isRunningAcceptanceTest() ? 0 : BURGER_MENU_ANIMATION_DURATION_MS} - unmountOnExit - > - {(burgerMenuState) => ( - <> - {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */} - - - )} - + {mainNavBar} - - )} - - ); -}; - -interface NavigationBarCommonProps { - variant?: Variant; - onBack?: () => void; - title?: string; - titleAs?: HeadingType; - right?: React.ReactElement; - withBorder?: boolean; - children?: undefined; -} - -interface NavigationBarTopFixedProps extends NavigationBarCommonProps { - topFixed?: true; - paddingX?: undefined; -} - -interface NavigationBarNotFixedProps extends NavigationBarCommonProps { - topFixed: false; - paddingX?: number; -} - -type NavigationBarProps = NavigationBarTopFixedProps | NavigationBarNotFixedProps; - -export const NavigationBar = ({ - onBack, - title, - titleAs, - right, - variant = 'default', - topFixed = true, - paddingX = 0, - withBorder = true, -}: NavigationBarProps): JSX.Element => { - const {texts, t} = useTheme(); - const content = ( - - - {onBack && ( - - )} - - {title} - - - - ); - return ( - -
- {topFixed ? ( - {content} - ) : ( -
- {content} -
- )} -
- {topFixed &&
} - + + )} + ); }; @@ -421,7 +1473,9 @@ export const FunnelNavigationBar = ({ > - {logo} + + {logo} +
diff --git a/src/package-version.tsx b/src/package-version.tsx index 9e8720d24b..6de0e68cc9 100644 --- a/src/package-version.tsx +++ b/src/package-version.tsx @@ -1,2 +1,2 @@ // DO NOT EDIT THIS FILE. It's autogenerated by set-version.js -export const PACKAGE_VERSION = '16.4.0' as string; +export const PACKAGE_VERSION = '16.5.0' as string; diff --git a/src/sheet-common.css.ts b/src/sheet-common.css.ts index a73845c1a5..e803eb6ae0 100644 --- a/src/sheet-common.css.ts +++ b/src/sheet-common.css.ts @@ -133,7 +133,7 @@ export const children = sprinkles({ flexDirection: 'column', }); -export const handleContainer = style([ +export const sheetTopDraggingArea = style([ sprinkles({ // Absolute positioned with a bigger size to increase the touchable area for dragging position: 'absolute', @@ -156,10 +156,35 @@ export const handleContainer = style([ }, ]); -export const handle = sprinkles({ +export const handleContainer = style([ + sprinkles({ + display: 'none', + }), + { + '@media': { + // Handle is rendered only in mobile version + [mq.tabletOrSmaller]: { + position: 'absolute', + top: 8, + width: '100%', + display: 'flex', + justifyContent: 'center', + }, + }, + }, +]); + +export const handleTouchable = style([ + sprinkles({ + width: 24, + height: 4, + }), +]); + +export const handleBar = sprinkles({ background: skinVars.colors.control, - width: 24, - height: 4, + width: '100%', + height: '100%', borderRadius: 2, }); diff --git a/src/sheet-common.tsx b/src/sheet-common.tsx index 3f4559ea29..cd5a71853a 100644 --- a/src/sheet-common.tsx +++ b/src/sheet-common.tsx @@ -26,6 +26,7 @@ import ButtonLayout from './button-layout'; import {safeAreaInsetBottom} from './utils/css'; import {MOBILE_SIDE_MARGIN, SMALL_DESKTOP_SIDE_MARGIN, TABLET_SIDE_MARGIN} from './responsive-layout.css'; import * as tokens from './text-tokens'; +import Touchable from './touchable'; import type {DataAttributes, RendersNullableElement} from './utils/types'; import type {ButtonLink, ButtonPrimary, ButtonSecondary} from './button'; @@ -240,9 +241,12 @@ const Sheet = React.forwardRef(({onClose, children, >
-
-
-
+ {/** + * Space rendered on the top part of the sheet on top of + * the content in order to be able to drag the sheet + */} +
+
(({onClose, children, style={{ paddingBottom: safeAreaInsetBottom, }} - tabIndex={-1} > {typeof children === 'function' ? children({closeModal, modalTitleId}) @@ -267,6 +270,19 @@ const Sheet = React.forwardRef(({onClose, children, bleedY />
+ {/** + * We put a button behind the top dragging area so that the sheet can + * be closed while navigating with the keyboard or with a screen reader. + */} +
+ +
+ +
diff --git a/src/skins/blau.tsx b/src/skins/blau.tsx index 159568f2f7..a9a79687b2 100644 --- a/src/skins/blau.tsx +++ b/src/skins/blau.tsx @@ -328,29 +328,29 @@ export const getBlauSkin: GetKnownSkin = () => { mediaSmall: '8px', }, textPresets: { - cardTitle: {weight: 'regular'}, button: {weight: 'medium'}, + cardTitle: {weight: 'regular'}, + indicator: {weight: 'medium'}, + link: {weight: 'medium'}, + navigationBar: {weight: 'medium'}, tabsLabel: { + lineHeight: {desktop: 24, mobile: 24}, + size: {desktop: 18, mobile: 16}, weight: 'medium', - size: {mobile: 16, desktop: 18}, - lineHeight: {mobile: 24, desktop: 24}, }, - link: {weight: 'medium'}, + text1: {lineHeight: {desktop: 20, mobile: 16}, size: {desktop: 14, mobile: 12}}, + text2: {lineHeight: {desktop: 24, mobile: 20}, size: {desktop: 16, mobile: 14}}, + text3: {lineHeight: {desktop: 24, mobile: 24}, size: {desktop: 18, mobile: 16}}, + text4: {lineHeight: {desktop: 28, mobile: 24}, size: {desktop: 20, mobile: 18}}, + text5: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'light'}, + text6: {lineHeight: {desktop: 40, mobile: 32}, size: {desktop: 32, mobile: 24}, weight: 'light'}, + text7: {lineHeight: {desktop: 48, mobile: 32}, size: {desktop: 40, mobile: 28}, weight: 'light'}, + text8: {lineHeight: {desktop: 56, mobile: 40}, size: {desktop: 48, mobile: 32}, weight: 'light'}, + text9: {lineHeight: {desktop: 64, mobile: 48}, size: {desktop: 56, mobile: 40}, weight: 'light'}, + text10: {lineHeight: {desktop: 72, mobile: 56}, size: {desktop: 64, mobile: 48}, weight: 'light'}, title1: {weight: 'medium'}, title2: {weight: 'light'}, - title3: {weight: 'light', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - indicator: {weight: 'medium'}, - navigationBar: {weight: 'medium'}, - text1: {size: {mobile: 12, desktop: 14}, lineHeight: {mobile: 16, desktop: 20}}, - text2: {size: {mobile: 14, desktop: 16}, lineHeight: {mobile: 20, desktop: 24}}, - text3: {size: {mobile: 16, desktop: 18}, lineHeight: {mobile: 24, desktop: 24}}, - text4: {size: {mobile: 18, desktop: 20}, lineHeight: {mobile: 24, desktop: 28}}, - text5: {weight: 'light', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - text6: {weight: 'light', size: {mobile: 24, desktop: 32}, lineHeight: {mobile: 32, desktop: 40}}, - text7: {weight: 'light', size: {mobile: 28, desktop: 40}, lineHeight: {mobile: 32, desktop: 48}}, - text8: {weight: 'light', size: {mobile: 32, desktop: 48}, lineHeight: {mobile: 40, desktop: 56}}, - text9: {weight: 'light', size: {mobile: 40, desktop: 56}, lineHeight: {mobile: 48, desktop: 64}}, - text10: {weight: 'light', size: {mobile: 48, desktop: 64}, lineHeight: {mobile: 56, desktop: 72}}, + title3: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'light'}, }, }; return skin; diff --git a/src/skins/movistar.tsx b/src/skins/movistar.tsx index 5571cd4430..ec358e32be 100644 --- a/src/skins/movistar.tsx +++ b/src/skins/movistar.tsx @@ -346,29 +346,29 @@ export const getMovistarSkin: GetKnownSkin = () => { mediaSmall: '8px', }, textPresets: { - cardTitle: {weight: 'bold'}, button: {weight: 'medium'}, + cardTitle: {weight: 'bold'}, + indicator: {weight: 'medium'}, + link: {weight: 'medium'}, + navigationBar: {weight: 'medium'}, tabsLabel: { + lineHeight: {desktop: 24, mobile: 24}, + size: {desktop: 18, mobile: 16}, weight: 'medium', - size: {mobile: 16, desktop: 18}, - lineHeight: {mobile: 24, desktop: 24}, }, - link: {weight: 'medium'}, + text1: {lineHeight: {desktop: 20, mobile: 16}, size: {desktop: 14, mobile: 12}}, + text2: {lineHeight: {desktop: 24, mobile: 20}, size: {desktop: 16, mobile: 14}}, + text3: {lineHeight: {desktop: 24, mobile: 24}, size: {desktop: 18, mobile: 16}}, + text4: {lineHeight: {desktop: 28, mobile: 24}, size: {desktop: 20, mobile: 18}}, + text5: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'bold'}, + text6: {lineHeight: {desktop: 40, mobile: 32}, size: {desktop: 32, mobile: 24}, weight: 'bold'}, + text7: {lineHeight: {desktop: 48, mobile: 32}, size: {desktop: 40, mobile: 28}, weight: 'bold'}, + text8: {lineHeight: {desktop: 56, mobile: 40}, size: {desktop: 48, mobile: 32}, weight: 'bold'}, + text9: {lineHeight: {desktop: 64, mobile: 48}, size: {desktop: 56, mobile: 40}, weight: 'bold'}, + text10: {lineHeight: {desktop: 72, mobile: 56}, size: {desktop: 64, mobile: 48}, weight: 'bold'}, title1: {weight: 'medium'}, title2: {weight: 'bold'}, - title3: {weight: 'bold', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - indicator: {weight: 'medium'}, - navigationBar: {weight: 'medium'}, - text1: {size: {mobile: 12, desktop: 14}, lineHeight: {mobile: 16, desktop: 20}}, - text2: {size: {mobile: 14, desktop: 16}, lineHeight: {mobile: 20, desktop: 24}}, - text3: {size: {mobile: 16, desktop: 18}, lineHeight: {mobile: 24, desktop: 24}}, - text4: {size: {mobile: 18, desktop: 20}, lineHeight: {mobile: 24, desktop: 28}}, - text5: {weight: 'bold', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - text6: {weight: 'bold', size: {mobile: 24, desktop: 32}, lineHeight: {mobile: 32, desktop: 40}}, - text7: {weight: 'bold', size: {mobile: 28, desktop: 40}, lineHeight: {mobile: 32, desktop: 48}}, - text8: {weight: 'bold', size: {mobile: 32, desktop: 48}, lineHeight: {mobile: 40, desktop: 56}}, - text9: {weight: 'bold', size: {mobile: 40, desktop: 56}, lineHeight: {mobile: 48, desktop: 64}}, - text10: {weight: 'bold', size: {mobile: 48, desktop: 64}, lineHeight: {mobile: 56, desktop: 72}}, + title3: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'bold'}, }, }; return skin; diff --git a/src/skins/o2-new.tsx b/src/skins/o2-new.tsx index 5a923a50f4..244bdb795a 100644 --- a/src/skins/o2-new.tsx +++ b/src/skins/o2-new.tsx @@ -336,29 +336,29 @@ export const getO2NewSkin: GetKnownSkin = () => { mediaSmall: '8px', }, textPresets: { - cardTitle: {weight: 'medium'}, button: {weight: 'medium'}, + cardTitle: {weight: 'medium'}, + indicator: {weight: 'medium'}, + link: {weight: 'medium'}, + navigationBar: {weight: 'medium'}, tabsLabel: { + lineHeight: {desktop: 24, mobile: 24}, + size: {desktop: 18, mobile: 16}, weight: 'medium', - size: {mobile: 16, desktop: 18}, - lineHeight: {mobile: 24, desktop: 24}, }, - link: {weight: 'medium'}, + text1: {lineHeight: {desktop: 20, mobile: 16}, size: {desktop: 14, mobile: 12}}, + text2: {lineHeight: {desktop: 24, mobile: 20}, size: {desktop: 16, mobile: 14}}, + text3: {lineHeight: {desktop: 24, mobile: 24}, size: {desktop: 18, mobile: 16}}, + text4: {lineHeight: {desktop: 28, mobile: 24}, size: {desktop: 20, mobile: 18}}, + text5: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'bold'}, + text6: {lineHeight: {desktop: 40, mobile: 32}, size: {desktop: 32, mobile: 24}, weight: 'bold'}, + text7: {lineHeight: {desktop: 48, mobile: 32}, size: {desktop: 40, mobile: 28}, weight: 'bold'}, + text8: {lineHeight: {desktop: 56, mobile: 40}, size: {desktop: 48, mobile: 32}, weight: 'bold'}, + text9: {lineHeight: {desktop: 64, mobile: 48}, size: {desktop: 56, mobile: 40}, weight: 'bold'}, + text10: {lineHeight: {desktop: 72, mobile: 56}, size: {desktop: 64, mobile: 48}, weight: 'bold'}, title1: {weight: 'medium'}, title2: {weight: 'bold'}, - title3: {weight: 'bold', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - indicator: {weight: 'medium'}, - navigationBar: {weight: 'medium'}, - text1: {size: {mobile: 12, desktop: 14}, lineHeight: {mobile: 16, desktop: 20}}, - text2: {size: {mobile: 14, desktop: 16}, lineHeight: {mobile: 20, desktop: 24}}, - text3: {size: {mobile: 16, desktop: 18}, lineHeight: {mobile: 24, desktop: 24}}, - text4: {size: {mobile: 18, desktop: 20}, lineHeight: {mobile: 24, desktop: 28}}, - text5: {weight: 'bold', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - text6: {weight: 'bold', size: {mobile: 24, desktop: 32}, lineHeight: {mobile: 32, desktop: 40}}, - text7: {weight: 'bold', size: {mobile: 28, desktop: 40}, lineHeight: {mobile: 32, desktop: 48}}, - text8: {weight: 'bold', size: {mobile: 32, desktop: 48}, lineHeight: {mobile: 40, desktop: 56}}, - text9: {weight: 'bold', size: {mobile: 40, desktop: 56}, lineHeight: {mobile: 48, desktop: 64}}, - text10: {weight: 'bold', size: {mobile: 48, desktop: 64}, lineHeight: {mobile: 56, desktop: 72}}, + title3: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'bold'}, }, }; return skin; diff --git a/src/skins/o2.tsx b/src/skins/o2.tsx index a57ee2f4ca..d41635e6c5 100644 --- a/src/skins/o2.tsx +++ b/src/skins/o2.tsx @@ -333,29 +333,29 @@ export const getO2Skin: GetKnownSkin = () => { mediaSmall: '8px', }, textPresets: { - cardTitle: {weight: 'regular'}, button: {weight: 'medium'}, + cardTitle: {weight: 'regular'}, + indicator: {weight: 'medium'}, + link: {weight: 'medium'}, + navigationBar: {weight: 'medium'}, tabsLabel: { + lineHeight: {desktop: 24, mobile: 24}, + size: {desktop: 18, mobile: 16}, weight: 'medium', - size: {mobile: 16, desktop: 18}, - lineHeight: {mobile: 24, desktop: 24}, }, - link: {weight: 'medium'}, + text1: {lineHeight: {desktop: 20, mobile: 16}, size: {desktop: 14, mobile: 12}}, + text2: {lineHeight: {desktop: 24, mobile: 20}, size: {desktop: 16, mobile: 14}}, + text3: {lineHeight: {desktop: 24, mobile: 24}, size: {desktop: 18, mobile: 16}}, + text4: {lineHeight: {desktop: 28, mobile: 24}, size: {desktop: 20, mobile: 18}}, + text5: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'light'}, + text6: {lineHeight: {desktop: 40, mobile: 32}, size: {desktop: 32, mobile: 24}, weight: 'light'}, + text7: {lineHeight: {desktop: 48, mobile: 32}, size: {desktop: 40, mobile: 28}, weight: 'light'}, + text8: {lineHeight: {desktop: 56, mobile: 40}, size: {desktop: 48, mobile: 32}, weight: 'light'}, + text9: {lineHeight: {desktop: 64, mobile: 48}, size: {desktop: 56, mobile: 40}, weight: 'light'}, + text10: {lineHeight: {desktop: 72, mobile: 56}, size: {desktop: 64, mobile: 48}, weight: 'light'}, title1: {weight: 'medium'}, title2: {weight: 'light'}, - title3: {weight: 'light', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - indicator: {weight: 'medium'}, - navigationBar: {weight: 'medium'}, - text1: {size: {mobile: 12, desktop: 14}, lineHeight: {mobile: 16, desktop: 20}}, - text2: {size: {mobile: 14, desktop: 16}, lineHeight: {mobile: 20, desktop: 24}}, - text3: {size: {mobile: 16, desktop: 18}, lineHeight: {mobile: 24, desktop: 24}}, - text4: {size: {mobile: 18, desktop: 20}, lineHeight: {mobile: 24, desktop: 28}}, - text5: {weight: 'light', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - text6: {weight: 'light', size: {mobile: 24, desktop: 32}, lineHeight: {mobile: 32, desktop: 40}}, - text7: {weight: 'light', size: {mobile: 28, desktop: 40}, lineHeight: {mobile: 32, desktop: 48}}, - text8: {weight: 'light', size: {mobile: 32, desktop: 48}, lineHeight: {mobile: 40, desktop: 56}}, - text9: {weight: 'light', size: {mobile: 40, desktop: 56}, lineHeight: {mobile: 48, desktop: 64}}, - text10: {weight: 'light', size: {mobile: 48, desktop: 64}, lineHeight: {mobile: 56, desktop: 72}}, + title3: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'light'}, }, }; return skin; diff --git a/src/skins/telefonica.tsx b/src/skins/telefonica.tsx index 95886f9e7c..67a6be97f0 100644 --- a/src/skins/telefonica.tsx +++ b/src/skins/telefonica.tsx @@ -327,56 +327,56 @@ export const getTelefonicaSkin: GetKnownSkin = () => { mediaSmall: '0px', }, textPresets: { - cardTitle: {weight: 'regular'}, button: {weight: 'medium'}, + cardTitle: {weight: 'regular'}, + indicator: {weight: 'medium'}, + link: {weight: 'medium'}, + navigationBar: {weight: 'medium'}, tabsLabel: { + lineHeight: {desktop: 24, mobile: 24}, + size: {desktop: 18, mobile: 16}, weight: 'medium', - size: {mobile: 16, desktop: 18}, - lineHeight: {mobile: 24, desktop: 24}, - }, - link: {weight: 'medium'}, - title1: {weight: 'medium'}, - title2: {weight: 'regular'}, - title3: { - weight: 'regular', - size: {mobile: 20, desktop: 28}, - lineHeight: {mobile: 24, desktop: 32}, }, - indicator: {weight: 'medium'}, - navigationBar: {weight: 'medium'}, - text1: {size: {mobile: 12, desktop: 14}, lineHeight: {mobile: 16, desktop: 20}}, - text2: {size: {mobile: 14, desktop: 16}, lineHeight: {mobile: 20, desktop: 24}}, - text3: {size: {mobile: 16, desktop: 18}, lineHeight: {mobile: 24, desktop: 24}}, - text4: {size: {mobile: 18, desktop: 20}, lineHeight: {mobile: 24, desktop: 28}}, + text1: {lineHeight: {desktop: 20, mobile: 16}, size: {desktop: 14, mobile: 12}}, + text2: {lineHeight: {desktop: 24, mobile: 20}, size: {desktop: 16, mobile: 14}}, + text3: {lineHeight: {desktop: 24, mobile: 24}, size: {desktop: 18, mobile: 16}}, + text4: {lineHeight: {desktop: 28, mobile: 24}, size: {desktop: 20, mobile: 18}}, text5: { + lineHeight: {desktop: 32, mobile: 24}, + size: {desktop: 28, mobile: 20}, weight: 'regular', - size: {mobile: 20, desktop: 28}, - lineHeight: {mobile: 24, desktop: 32}, }, text6: { + lineHeight: {desktop: 40, mobile: 32}, + size: {desktop: 32, mobile: 24}, weight: 'regular', - size: {mobile: 24, desktop: 32}, - lineHeight: {mobile: 32, desktop: 40}, }, text7: { + lineHeight: {desktop: 48, mobile: 32}, + size: {desktop: 40, mobile: 28}, weight: 'regular', - size: {mobile: 28, desktop: 40}, - lineHeight: {mobile: 32, desktop: 48}, }, text8: { + lineHeight: {desktop: 56, mobile: 40}, + size: {desktop: 48, mobile: 32}, weight: 'regular', - size: {mobile: 32, desktop: 48}, - lineHeight: {mobile: 40, desktop: 56}, }, text9: { + lineHeight: {desktop: 64, mobile: 48}, + size: {desktop: 56, mobile: 40}, weight: 'regular', - size: {mobile: 40, desktop: 56}, - lineHeight: {mobile: 48, desktop: 64}, }, text10: { + lineHeight: {desktop: 72, mobile: 56}, + size: {desktop: 64, mobile: 48}, + weight: 'regular', + }, + title1: {weight: 'medium'}, + title2: {weight: 'regular'}, + title3: { + lineHeight: {desktop: 32, mobile: 24}, + size: {desktop: 28, mobile: 20}, weight: 'regular', - size: {mobile: 48, desktop: 64}, - lineHeight: {mobile: 56, desktop: 72}, }, }, }; diff --git a/src/skins/tu.tsx b/src/skins/tu.tsx index 8e7f6301f6..eab302e4a0 100644 --- a/src/skins/tu.tsx +++ b/src/skins/tu.tsx @@ -331,36 +331,36 @@ export const getTuSkin: GetKnownSkin = () => { mediaSmall: '8px', }, textPresets: { - cardTitle: {weight: 'medium'}, button: {weight: 'medium'}, + cardTitle: {weight: 'medium'}, + indicator: {weight: 'medium'}, + link: {weight: 'medium'}, + navigationBar: {weight: 'medium'}, tabsLabel: { + lineHeight: {desktop: 24, mobile: 24}, + size: {desktop: 18, mobile: 16}, + weight: 'medium', + }, + text1: {lineHeight: {desktop: 20, mobile: 16}, size: {desktop: 14, mobile: 12}}, + text2: {lineHeight: {desktop: 24, mobile: 20}, size: {desktop: 16, mobile: 14}}, + text3: {lineHeight: {desktop: 24, mobile: 24}, size: {desktop: 18, mobile: 16}}, + text4: {lineHeight: {desktop: 28, mobile: 24}, size: {desktop: 20, mobile: 18}}, + text5: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'medium'}, + text6: {lineHeight: {desktop: 40, mobile: 32}, size: {desktop: 32, mobile: 24}, weight: 'medium'}, + text7: {lineHeight: {desktop: 48, mobile: 32}, size: {desktop: 40, mobile: 28}, weight: 'medium'}, + text8: {lineHeight: {desktop: 56, mobile: 40}, size: {desktop: 48, mobile: 32}, weight: 'medium'}, + text9: {lineHeight: {desktop: 64, mobile: 48}, size: {desktop: 56, mobile: 40}, weight: 'medium'}, + text10: { + lineHeight: {desktop: 72, mobile: 56}, + size: {desktop: 64, mobile: 48}, weight: 'medium', - size: {mobile: 16, desktop: 18}, - lineHeight: {mobile: 24, desktop: 24}, }, - link: {weight: 'medium'}, title1: {weight: 'medium'}, title2: {weight: 'medium'}, title3: { + lineHeight: {desktop: 32, mobile: 24}, + size: {desktop: 28, mobile: 20}, weight: 'medium', - size: {mobile: 20, desktop: 28}, - lineHeight: {mobile: 24, desktop: 32}, - }, - indicator: {weight: 'medium'}, - navigationBar: {weight: 'medium'}, - text1: {size: {mobile: 12, desktop: 14}, lineHeight: {mobile: 16, desktop: 20}}, - text2: {size: {mobile: 14, desktop: 16}, lineHeight: {mobile: 20, desktop: 24}}, - text3: {size: {mobile: 16, desktop: 18}, lineHeight: {mobile: 24, desktop: 24}}, - text4: {size: {mobile: 18, desktop: 20}, lineHeight: {mobile: 24, desktop: 28}}, - text5: {weight: 'medium', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - text6: {weight: 'medium', size: {mobile: 24, desktop: 32}, lineHeight: {mobile: 32, desktop: 40}}, - text7: {weight: 'medium', size: {mobile: 28, desktop: 40}, lineHeight: {mobile: 32, desktop: 48}}, - text8: {weight: 'medium', size: {mobile: 32, desktop: 48}, lineHeight: {mobile: 40, desktop: 56}}, - text9: {weight: 'medium', size: {mobile: 40, desktop: 56}, lineHeight: {mobile: 48, desktop: 64}}, - text10: { - weight: 'medium', - size: {mobile: 48, desktop: 64}, - lineHeight: {mobile: 56, desktop: 72}, }, }, }; diff --git a/src/skins/vivo-new.tsx b/src/skins/vivo-new.tsx index cc848354b7..9c5930c2d7 100644 --- a/src/skins/vivo-new.tsx +++ b/src/skins/vivo-new.tsx @@ -326,56 +326,44 @@ export const getVivoNewSkin: GetKnownSkin = () => { mediaSmall: '8px', }, textPresets: { - cardTitle: {weight: 'regular'}, - button: {weight: 'regular'}, - tabsLabel: { - weight: 'regular', - size: {mobile: 18, desktop: 18}, - lineHeight: {mobile: 24, desktop: 24}, - }, - link: {weight: 'regular'}, - title1: {weight: 'regular'}, - title2: {weight: 'regular'}, - title3: { - weight: 'regular', - size: {mobile: 18, desktop: 20}, - lineHeight: {mobile: 24, desktop: 28}, - }, - indicator: {weight: 'regular'}, + button: {weight: 'medium'}, + cardTitle: {weight: 'medium'}, + indicator: {weight: 'medium'}, + link: {weight: 'medium'}, navigationBar: {weight: 'regular'}, - text1: {size: {mobile: 12, desktop: 14}, lineHeight: {mobile: 16, desktop: 20}}, - text2: {size: {mobile: 14, desktop: 16}, lineHeight: {mobile: 20, desktop: 24}}, - text3: {size: {mobile: 16, desktop: 18}, lineHeight: {mobile: 24, desktop: 24}}, - text4: {size: {mobile: 18, desktop: 20}, lineHeight: {mobile: 24, desktop: 28}}, - text5: { - weight: 'regular', - size: {mobile: 20, desktop: 28}, - lineHeight: {mobile: 24, desktop: 32}, - }, - text6: { - weight: 'regular', - size: {mobile: 24, desktop: 32}, - lineHeight: {mobile: 32, desktop: 40}, - }, - text7: { - weight: 'regular', - size: {mobile: 28, desktop: 40}, - lineHeight: {mobile: 32, desktop: 48}, + tabsLabel: { + lineHeight: {desktop: 24, mobile: 24}, + size: {desktop: 18, mobile: 18}, + weight: 'medium', }, + text1: {lineHeight: {desktop: 20, mobile: 16}, size: {desktop: 14, mobile: 12}}, + text2: {lineHeight: {desktop: 24, mobile: 20}, size: {desktop: 16, mobile: 14}}, + text3: {lineHeight: {desktop: 24, mobile: 24}, size: {desktop: 18, mobile: 16}}, + text4: {lineHeight: {desktop: 28, mobile: 24}, size: {desktop: 20, mobile: 18}}, + text5: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'medium'}, + text6: {lineHeight: {desktop: 40, mobile: 32}, size: {desktop: 32, mobile: 24}, weight: 'medium'}, + text7: {lineHeight: {desktop: 48, mobile: 32}, size: {desktop: 40, mobile: 28}, weight: 'medium'}, text8: { + lineHeight: {desktop: 56, mobile: 40}, + size: {desktop: 48, mobile: 32}, weight: 'regular', - size: {mobile: 32, desktop: 48}, - lineHeight: {mobile: 40, desktop: 56}, }, text9: { + lineHeight: {desktop: 64, mobile: 48}, + size: {desktop: 56, mobile: 40}, weight: 'regular', - size: {mobile: 40, desktop: 56}, - lineHeight: {mobile: 48, desktop: 64}, }, text10: { + lineHeight: {desktop: 72, mobile: 56}, + size: {desktop: 64, mobile: 48}, weight: 'regular', - size: {mobile: 48, desktop: 64}, - lineHeight: {mobile: 56, desktop: 72}, + }, + title1: {weight: 'medium'}, + title2: {weight: 'medium'}, + title3: { + lineHeight: {desktop: 28, mobile: 24}, + size: {desktop: 20, mobile: 18}, + weight: 'medium', }, }, }; diff --git a/src/skins/vivo.tsx b/src/skins/vivo.tsx index 1ed353e217..ae64fb465b 100644 --- a/src/skins/vivo.tsx +++ b/src/skins/vivo.tsx @@ -326,29 +326,29 @@ export const getVivoSkin: GetKnownSkin = () => { mediaSmall: '8px', }, textPresets: { - cardTitle: {weight: 'regular'}, button: {weight: 'medium'}, + cardTitle: {weight: 'regular'}, + indicator: {weight: 'medium'}, + link: {weight: 'medium'}, + navigationBar: {weight: 'medium'}, tabsLabel: { + lineHeight: {desktop: 24, mobile: 24}, + size: {desktop: 18, mobile: 16}, weight: 'medium', - size: {mobile: 16, desktop: 18}, - lineHeight: {mobile: 24, desktop: 24}, }, - link: {weight: 'medium'}, + text1: {lineHeight: {desktop: 20, mobile: 16}, size: {desktop: 14, mobile: 12}}, + text2: {lineHeight: {desktop: 24, mobile: 20}, size: {desktop: 16, mobile: 14}}, + text3: {lineHeight: {desktop: 24, mobile: 24}, size: {desktop: 18, mobile: 16}}, + text4: {lineHeight: {desktop: 28, mobile: 24}, size: {desktop: 20, mobile: 18}}, + text5: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'light'}, + text6: {lineHeight: {desktop: 40, mobile: 32}, size: {desktop: 32, mobile: 24}, weight: 'light'}, + text7: {lineHeight: {desktop: 48, mobile: 32}, size: {desktop: 40, mobile: 28}, weight: 'light'}, + text8: {lineHeight: {desktop: 56, mobile: 40}, size: {desktop: 48, mobile: 32}, weight: 'light'}, + text9: {lineHeight: {desktop: 64, mobile: 48}, size: {desktop: 56, mobile: 40}, weight: 'light'}, + text10: {lineHeight: {desktop: 72, mobile: 56}, size: {desktop: 64, mobile: 48}, weight: 'light'}, title1: {weight: 'medium'}, title2: {weight: 'light'}, - title3: {weight: 'light', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - indicator: {weight: 'medium'}, - navigationBar: {weight: 'medium'}, - text1: {size: {mobile: 12, desktop: 14}, lineHeight: {mobile: 16, desktop: 20}}, - text2: {size: {mobile: 14, desktop: 16}, lineHeight: {mobile: 20, desktop: 24}}, - text3: {size: {mobile: 16, desktop: 18}, lineHeight: {mobile: 24, desktop: 24}}, - text4: {size: {mobile: 18, desktop: 20}, lineHeight: {mobile: 24, desktop: 28}}, - text5: {weight: 'light', size: {mobile: 20, desktop: 28}, lineHeight: {mobile: 24, desktop: 32}}, - text6: {weight: 'light', size: {mobile: 24, desktop: 32}, lineHeight: {mobile: 32, desktop: 40}}, - text7: {weight: 'light', size: {mobile: 28, desktop: 40}, lineHeight: {mobile: 32, desktop: 48}}, - text8: {weight: 'light', size: {mobile: 32, desktop: 48}, lineHeight: {mobile: 40, desktop: 56}}, - text9: {weight: 'light', size: {mobile: 40, desktop: 56}, lineHeight: {mobile: 48, desktop: 64}}, - text10: {weight: 'light', size: {mobile: 48, desktop: 64}, lineHeight: {mobile: 56, desktop: 72}}, + title3: {lineHeight: {desktop: 32, mobile: 24}, size: {desktop: 28, mobile: 20}, weight: 'light'}, }, }; return skin; diff --git a/src/text-tokens.tsx b/src/text-tokens.tsx index 1eeae056de..cbaec33f2f 100644 --- a/src/text-tokens.tsx +++ b/src/text-tokens.tsx @@ -32,6 +32,8 @@ export type Dictionary = { menuLabelSuffix: string; openNavigationMenu: string; closeNavigationMenu: string; + mainNavigationBarOpenSectionMenu: string; + mainNavigationBarSectionSeeAll: string; backNavigationBar: string; clearButton: string; carouselNextButton: string; @@ -291,6 +293,20 @@ export const closeNavigationMenu: TextToken = { pt: 'Fechar menu de navegação', }; +export const mainNavigationBarOpenSectionMenu: TextToken = { + es: 'Abrir submenú', + en: 'Open submenu', + de: 'Untermenü öffnen', + pt: 'Abrir submenu', +}; + +export const mainNavigationBarSectionSeeAll: TextToken = { + es: 'Ver todo', + en: 'See all', + de: 'Alle anzeigen', + pt: 'Ver tudo', +}; + export const backNavigationBar: TextToken = { es: 'Atrás', en: 'Back', @@ -556,3 +572,25 @@ export const ratingQuantitativeLabel: TextToken = { de: '1$s von 2$s', pt: '1$s de 2$s', }; + +/** + * 1$s: segments count + * 2$s: total percentage value + */ +export const meterTotalLabel: TextToken = { + es: 'Indicador de progreso con 1$s secciones, total 2$s% de 100%.', + en: 'Gauge chart 1$s segments, total 2$s% out of 100%.', + de: 'Fortschrittsanzeige mit 1$s Abschnitten, insgesamt 2$s% von 100%.', + pt: 'Indicador de progresso com 1$s seções, total 2$s% de 100%.', +}; + +/** + * 1$s: segment number + * 2$s: segment percentage value + */ +export const meterSectionLabel: TextToken = { + es: 'Sección 1$s: 2$s%', + en: 'Segment 1$s: 2$s%', + de: 'Abschnitt 1$s: 2$s%', + pt: 'Seção 1$s: 2$s%', +}; diff --git a/src/theme-context-provider.tsx b/src/theme-context-provider.tsx index cb76786ecd..30bcded897 100644 --- a/src/theme-context-provider.tsx +++ b/src/theme-context-provider.tsx @@ -133,8 +133,15 @@ const ThemeContextProvider = ({theme, children, as, withoutStyles = false}: Prop const language = localeToLanguage(theme.i18n.locale); const translate = React.useCallback( - (token: TextToken): string => { - return token[language] || token.en; + (token: TextToken, ...params: Array): string => { + const text = token[language] || token.en; + if (!params.length) { + return text; + } + // replace token parameters: 1$s, 2$s, 3$s, etc. + return text.replace(/\d+\$s/g, (substr) => { + return String(params[parseInt(substr) - 1] ?? substr); + }); }, [language] ); @@ -174,6 +181,7 @@ const ThemeContextProvider = ({theme, children, as, withoutStyles = false}: Prop ...sanitizeDimensions(theme.dimensions), }, textPresets, + borderRadii: theme.skin.borderRadii ?? defaultBorderRadiiConfig, Link: getMisticaLinkComponent(theme.Link), isDarkMode: isDarkModeEnabled, isIos: getPlatform(platformOverrides) === 'ios', diff --git a/src/theme.tsx b/src/theme.tsx index dc6d2e9147..6aa5361da1 100644 --- a/src/theme.tsx +++ b/src/theme.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import type {RegionCode} from './utils/region-code'; import type {Locale} from './utils/locale'; -import type {Colors, Skin, SkinName, TextPresetsConfig} from './skins/types'; +import type {BorderRadiiConfig, Colors, Skin, SkinName, TextPresetsConfig} from './skins/types'; import type {TrackingEvent} from './utils/types'; import type {Dictionary, TextToken} from './text-tokens'; @@ -162,11 +162,12 @@ export type Theme = { // TODO: rename this props to navigationBarHeight (or something similar) in next major dimensions: {headerMobileHeight: number; headerDesktopHeight: number}; colorValues: Colors; + borderRadii: BorderRadiiConfig; textPresets: TextPresetsConfig; Link: LinkComponent; isDarkMode: boolean; isIos: boolean; useHrefDecorator: () => (href: string) => string; - t: (token: TextToken) => string; + t: (token: TextToken, ...params: Array) => string; preventCopyInFormFields: boolean; }; diff --git a/src/utils/types.tsx b/src/utils/types.tsx index cf5a45dd32..d742c5d0f0 100644 --- a/src/utils/types.tsx +++ b/src/utils/types.tsx @@ -2,7 +2,10 @@ export type {RendersElement, RendersNullableElement} from './renders-element'; export type {TrackingEvent} from '@tef-novum/webview-bridge'; -export type DataAttributes = {[name: string]: string | number | boolean | undefined}; +export type DataAttributes = { + [name: string]: string | number | boolean | undefined; + testid?: string; +}; export type IconProps = { color?: string; diff --git a/yarn.lock b/yarn.lock index 15fc8821da..fc11ca58f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5543,6 +5543,7 @@ __metadata: classnames: ^2.3.1 cpx: ^1.5.0 cross-env: ^7.0.3 + cubic-bezier: ^0.1.2 detect-port: ^1.3.0 dpdm: ^3.8.0 es6-promise-pool: ^2.5.0 @@ -9479,6 +9480,13 @@ __metadata: languageName: node linkType: hard +"cubic-bezier@npm:^0.1.2": + version: 0.1.2 + resolution: "cubic-bezier@npm:0.1.2" + checksum: db21ebda82ab3662e1209dcff7612a3b265bb94e05892a609be01cf788ed681914ed9df8d277eb936012b4a58e5786846a8318b6e6bd0ec74087d6ad42566cc6 + languageName: node + linkType: hard + "cwd@npm:^0.10.0": version: 0.10.0 resolution: "cwd@npm:0.10.0"