@orangesk/orange-design-system 2.2.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/build/components/Accordion/style.css +1 -1
  2. package/build/components/Accordion/style.css.map +1 -1
  3. package/build/components/Card/style.css +1 -1
  4. package/build/components/Card/style.css.map +1 -1
  5. package/build/components/Carousel/style.css +1 -1
  6. package/build/components/Carousel/style.css.map +1 -1
  7. package/build/components/CarouselHero/style.css +1 -1
  8. package/build/components/CarouselHero/style.css.map +1 -1
  9. package/build/components/Cover/style.css +1 -1
  10. package/build/components/Cover/style.css.map +1 -1
  11. package/build/components/FeatureAccordion/style.css +1 -1
  12. package/build/components/FeatureAccordion/style.css.map +1 -1
  13. package/build/components/Footer/style.css +1 -1
  14. package/build/components/Footer/style.css.map +1 -1
  15. package/build/components/Grid/style.css +1 -1
  16. package/build/components/Grid/style.css.map +1 -1
  17. package/build/components/IconList/style.css +1 -1
  18. package/build/components/IconList/style.css.map +1 -1
  19. package/build/components/Link/style.css +1 -1
  20. package/build/components/Link/style.css.map +1 -1
  21. package/build/components/Megamenu/style.css +1 -1
  22. package/build/components/Megamenu/style.css.map +1 -1
  23. package/build/components/PromoBanner/style.css +1 -1
  24. package/build/components/PromoBanner/style.css.map +1 -1
  25. package/build/components/Timeline/style.css +2 -0
  26. package/build/components/Timeline/style.css.map +1 -0
  27. package/build/components/index.js +1 -1
  28. package/build/components/index.js.map +1 -1
  29. package/build/components/tsconfig.tsbuildinfo +1 -1
  30. package/build/components/types/index.d.ts +30 -2
  31. package/build/components/types/src/components/FeatureAccordion/FeatureAccordion.d.ts +3 -0
  32. package/build/components/types/src/components/FeatureAccordion/FeatureAccordion.static.d.ts +0 -3
  33. package/build/components/types/src/components/FeatureAccordion/FeatureAccordionItem.d.ts +2 -1
  34. package/build/components/types/src/components/Timeline/Timeline.d.ts +13 -0
  35. package/build/components/types/src/components/Timeline/index.d.ts +2 -0
  36. package/build/components/types/src/components/index.d.ts +2 -1
  37. package/build/lib/base.css +1 -1
  38. package/build/lib/base.css.map +1 -1
  39. package/build/lib/components.css +1 -1
  40. package/build/lib/components.css.map +1 -1
  41. package/build/lib/footer.css +1 -1
  42. package/build/lib/footer.css.map +1 -1
  43. package/build/lib/megamenu.css +1 -1
  44. package/build/lib/megamenu.css.map +1 -1
  45. package/build/lib/scripts.js +1 -1
  46. package/build/lib/scripts.js.map +1 -1
  47. package/build/lib/style.css +1 -1
  48. package/build/lib/style.css.map +1 -1
  49. package/build/search-index.json +7 -3
  50. package/build/sprite.svg +1 -1
  51. package/package.json +8 -8
  52. package/src/assets/icons/communication-settings.svg +5 -0
  53. package/src/assets/icons/cookies.svg +4 -0
  54. package/src/assets/icons/device-mobile-package.svg +6 -0
  55. package/src/assets/icons/identity-protection.svg +4 -0
  56. package/src/assets/icons/pictogram-disney--dark.svg +5 -14
  57. package/src/assets/icons/pictogram-disney.svg +5 -9
  58. package/src/assets/icons/pictogram-tariffs--dark.svg +4 -8
  59. package/src/assets/icons/pictogram-tariffs.svg +4 -8
  60. package/src/components/Accordion/styles/mixins.scss +2 -4
  61. package/src/components/Card/styles/mixins.scss +2 -0
  62. package/src/components/Carousel/styles/mixins.scss +0 -1
  63. package/src/components/CarouselHero/styles/mixins.scss +0 -2
  64. package/src/components/Cover/styles/mixins.scss +2 -0
  65. package/src/components/FeatureAccordion/FeatureAccordion.static.ts +3 -71
  66. package/src/components/FeatureAccordion/FeatureAccordion.tsx +23 -59
  67. package/src/components/FeatureAccordion/FeatureAccordionItem.tsx +9 -14
  68. package/src/components/FeatureAccordion/styles/mixins.scss +67 -27
  69. package/src/components/FeatureAccordion/tests/FeatureAccordion.unit.test.jsx +9 -0
  70. package/src/components/Grid/styles/mixins.scss +34 -2
  71. package/src/components/IconList/styles/mixins.scss +2 -1
  72. package/src/components/Link/styles/style.scss +8 -0
  73. package/src/components/PromoBanner/styles/mixins.scss +8 -0
  74. package/src/components/PromoBanner/styles/style.scss +1 -0
  75. package/src/components/Timeline/Timeline.tsx +60 -0
  76. package/src/components/Timeline/index.ts +2 -0
  77. package/src/components/Timeline/styles/config.scss +25 -0
  78. package/src/components/Timeline/styles/mixins.scss +102 -0
  79. package/src/components/Timeline/styles/style.scss +60 -0
  80. package/src/components/Timeline/tests/Timeline.conformance.test.jsx +29 -0
  81. package/src/components/Timeline/tests/Timeline.unit.test.jsx +89 -0
  82. package/src/components/index.ts +2 -0
  83. package/src/styles/typography/mixins.scss +3 -1
@@ -1,9 +1,5 @@
1
- <svg width="61" height="60" viewBox="0 0 61 60" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <mask id="mask0_3153_368" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="61" height="60">
3
- <path d="M60.9375 0H0V60H60.9375V0Z" fill="white"/>
4
- </mask>
5
- <g mask="url(#mask0_3153_368)">
6
- <path d="M45.0009 52.5C45.0009 54.0532 43.7415 55.3123 42.1884 55.3125H18.2812C16.7279 55.3125 15.4688 54.0533 15.4688 52.5V51.0938H45.0009V52.5ZM45.0009 49.6865H15.4688V10.3115H45.0009V49.6865ZM42.1884 4.6875C43.7415 4.68769 45.0009 5.94682 45.0009 7.5V8.90625H15.4688V7.5C15.4688 5.9467 16.7279 4.6875 18.2812 4.6875H42.1884Z" fill="#DA8436"/>
7
- <path d="M33.5927 33.4381C30.8936 30.7332 28.3136 27.6002 29.5475 26.3652C32.6498 23.2568 32.8566 23.4989 29.7228 19.5941C26.582 15.6857 26.7082 16.3874 22.7752 20.401C20.707 22.6323 22.67 29.7684 29.9612 37.0658C37.2593 44.3632 44.5785 46.2437 46.6187 44.2615C50.8076 40.097 51.1371 40.3321 47.4249 37.3149C43.5234 34.1714 43.7513 34.3959 40.6595 37.4903C39.4257 38.7218 36.2954 36.1361 33.5927 33.4346V33.4381Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
8
- </g>
1
+ <svg width="64" height="63" viewBox="0 0 64 63" fill="none"
2
+ xmlns="http://www.w3.org/2000/svg">
3
+ <path d="M47.9845 55.2031C47.9845 56.834 46.6632 58.156 45.0337 58.1562H19.9507C18.321 58.1562 17 56.8341 17 55.2031V53.7266H47.9845V55.2031ZM47.9845 52.2489H17V10.9052H47.9845V52.2489ZM45.0337 5C46.6632 5.0002 47.9845 6.32229 47.9845 7.95312V9.42969H17V7.95312C17 6.32216 18.321 5 19.9507 5H45.0337Z" fill="#DA8436"/>
4
+ <path d="M28.3955 16.9315C29.3106 16.7289 30.0633 17.1272 30.6885 17.6636C31.2915 18.1809 31.9623 18.9853 32.7725 19.9943C33.5799 21.0011 34.2246 21.8033 34.6516 22.4624C35.073 23.1128 35.409 23.8066 35.3637 24.5819C35.3178 25.3658 34.8962 25.9905 34.4324 26.5332C33.9708 27.0731 33.2937 27.7204 32.5133 28.503C32.5044 28.5119 32.4993 28.5179 32.4938 28.545C32.4858 28.5855 32.479 28.6799 32.5153 28.8475C32.5918 29.1997 32.8178 29.6957 33.2254 30.3241C34.0282 31.5617 35.3405 33.0219 36.7377 34.4246C36.7439 34.4305 36.751 34.4359 36.7571 34.442C38.1641 35.8495 39.631 37.1732 40.8729 37.9827C41.5008 38.392 41.9966 38.6194 42.3483 38.6964C42.5163 38.7331 42.61 38.7259 42.6496 38.7179C42.6761 38.7126 42.6801 38.7079 42.6885 38.6995C43.4656 37.9211 44.1105 37.2441 44.6485 36.782C45.1896 36.3174 45.8133 35.8948 46.5963 35.8468C47.3718 35.7994 48.0664 36.1341 48.7182 36.5564C49.2135 36.8773 49.7883 37.3209 50.4692 37.8648L51.1864 38.4411L51.1895 38.4441C52.1357 39.2138 52.9199 39.8499 53.4324 40.4129C53.9576 40.99 54.4029 41.7113 54.2479 42.6288C54.1159 43.4096 53.5679 44.0935 52.9877 44.7247C52.3772 45.3887 51.4918 46.232 50.4211 47.2974L50.4129 47.3056C49.5955 48.1003 48.3873 48.3917 47.1137 48.3781C45.8155 48.3643 44.2904 48.0363 42.6403 47.4112C39.5407 46.2369 35.8701 43.9651 32.1977 40.458L31.4631 39.7392C27.5573 35.827 25.0365 31.9182 23.7735 28.6301C23.1431 26.9887 22.8118 25.4648 22.8033 24.1512C22.7948 22.8512 23.1056 21.6399 23.8965 20.7859L23.916 20.7644C24.907 19.7522 25.7243 18.8633 26.3535 18.2563C26.9605 17.6706 27.6259 17.1018 28.3955 16.9315ZM28.8483 18.9812C28.7232 19.009 28.4417 19.1586 27.8104 19.7677C27.2048 20.3521 26.495 21.1283 25.4344 22.2122C25.1405 22.5296 24.8952 23.1339 24.9016 24.1369C24.908 25.1265 25.1633 26.3943 25.7326 27.8765C26.8693 30.8359 29.2031 34.5046 32.9467 38.2544C36.6886 41.999 40.4006 44.3165 43.3832 45.4465C44.8776 46.0127 46.1533 46.2677 47.1362 46.2781C48.0173 46.2875 48.5518 46.1025 48.8412 45.8916L48.9508 45.7993C50.0729 44.683 50.8764 43.9194 51.4436 43.3024C52.0419 42.6517 52.1622 42.3794 52.1793 42.2791C52.1806 42.2715 52.1852 42.2639 52.166 42.2186C52.1375 42.1519 52.0637 42.0275 51.8811 41.8269C51.5003 41.4086 50.8668 40.8877 49.8658 40.0735C48.8275 39.2363 48.1245 38.6743 47.5778 38.3201C47.0225 37.9602 46.8063 37.9378 46.7244 37.9427C46.6502 37.9473 46.4686 37.9864 46.0143 38.3765C45.5573 38.769 45.0161 39.3399 44.1721 40.1853L44.1711 40.1863C43.5047 40.8519 42.6372 40.9087 41.8996 40.7472C41.1828 40.5902 40.4368 40.2047 39.7274 39.7423C38.3051 38.8151 36.7249 37.3767 35.3043 35.9576C35.294 35.9481 35.2825 35.9399 35.2725 35.9299C33.8457 34.4989 32.3971 32.9026 31.4662 31.4674C31.0053 30.7568 30.6197 30.0104 30.4641 29.2925C30.304 28.5535 30.3636 27.6854 31.0287 27.0192C31.8753 26.1703 32.4463 25.6257 32.8381 25.1674C33.2273 24.7119 33.2652 24.5318 33.2694 24.4588C33.2742 24.3772 33.251 24.1614 32.8903 23.6047C32.535 23.0564 31.9737 22.3519 31.1373 21.3088C30.3001 20.2663 29.7516 19.6252 29.3237 19.2581C29.1183 19.0819 28.9918 19.0146 28.9262 18.9904C28.8816 18.974 28.8683 18.9768 28.8483 18.9812Z" fill="white"/>
9
5
  </svg>
@@ -1,9 +1,5 @@
1
- <svg width="61" height="60" viewBox="0 0 61 60" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <mask id="mask0_3153_361" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="61" height="60">
3
- <path d="M60.9375 0H0V60H60.9375V0Z" fill="white"/>
4
- </mask>
5
- <g mask="url(#mask0_3153_361)">
6
- <path d="M45.0009 52.5C45.0009 54.0532 43.7415 55.3123 42.1884 55.3125H18.2812C16.7279 55.3125 15.4688 54.0533 15.4688 52.5V51.0938H45.0009V52.5ZM45.0009 49.6865H15.4688V10.3115H45.0009V49.6865ZM42.1884 4.6875C43.7415 4.68769 45.0009 5.94682 45.0009 7.5V8.90625H15.4688V7.5C15.4688 5.9467 16.7279 4.6875 18.2812 4.6875H42.1884Z" fill="#FFC48F"/>
7
- <path d="M33.5927 33.4381C30.8936 30.7332 28.3136 27.6002 29.5475 26.3652C32.6498 23.2568 32.8566 23.4989 29.7228 19.5941C26.582 15.6857 26.7082 16.3874 22.7752 20.401C20.707 22.6323 22.67 29.7684 29.9612 37.0658C37.2593 44.3632 44.5785 46.2437 46.6187 44.2615C50.8076 40.097 51.1371 40.3321 47.4249 37.3149C43.5234 34.1714 43.7513 34.3959 40.6595 37.4903C39.4257 38.7218 36.2954 36.1361 33.5927 33.4346V33.4381Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
8
- </g>
1
+ <svg width="64" height="63" viewBox="0 0 64 63" fill="none"
2
+ xmlns="http://www.w3.org/2000/svg">
3
+ <path d="M47.9845 55.2031C47.9845 56.834 46.6632 58.156 45.0337 58.1562H19.9507C18.321 58.1562 17 56.8341 17 55.2031V53.7266H47.9845V55.2031ZM47.9845 52.2489H17V10.9052H47.9845V52.2489ZM45.0337 5C46.6632 5.0002 47.9845 6.32229 47.9845 7.95312V9.42969H17V7.95312C17 6.32216 18.321 5 19.9507 5H45.0337Z" fill="#FFC48F"/>
4
+ <path d="M28.3954 16.9315C29.3106 16.7289 30.0632 17.1272 30.6884 17.6636C31.2915 18.1809 31.9623 18.9853 32.7725 19.9943C33.5798 21.0011 34.2245 21.8033 34.6516 22.4624C35.0729 23.1128 35.409 23.8066 35.3637 24.5819C35.3177 25.3658 34.8962 25.9905 34.4323 26.5332C33.9708 27.0731 33.2936 27.7204 32.5132 28.503C32.5043 28.5119 32.4993 28.5179 32.4938 28.545C32.4857 28.5855 32.479 28.6799 32.5153 28.8475C32.5917 29.1997 32.8178 29.6957 33.2253 30.3241C34.0281 31.5617 35.3405 33.0219 36.7376 34.4246C36.7439 34.4305 36.751 34.4359 36.7571 34.442C38.1641 35.8495 39.6309 37.1732 40.8729 37.9827C41.5008 38.392 41.9966 38.6194 42.3483 38.6964C42.5162 38.7331 42.6099 38.7259 42.6495 38.7179C42.6761 38.7126 42.68 38.7079 42.6885 38.6995C43.4655 37.9211 44.1104 37.2441 44.6485 36.782C45.1896 36.3174 45.8132 35.8948 46.5962 35.8468C47.3717 35.7994 48.0663 36.1341 48.7182 36.5564C49.2135 36.8773 49.7883 37.3209 50.4692 37.8648L51.1864 38.4411L51.1895 38.4441C52.1357 39.2138 52.9199 39.8499 53.4323 40.4129C53.9576 40.99 54.4028 41.7113 54.2479 42.6288C54.1159 43.4096 53.5679 44.0935 52.9876 44.7247C52.3771 45.3887 51.4918 46.232 50.421 47.2974L50.4128 47.3056C49.5955 48.1003 48.3873 48.3917 47.1137 48.3781C45.8155 48.3643 44.2903 48.0363 42.6403 47.4112C39.5407 46.2369 35.87 43.9651 32.1977 40.458L31.463 39.7392C27.5572 35.827 25.0364 31.9182 23.7735 28.6301C23.143 26.9887 22.8118 25.4648 22.8032 24.1512C22.7948 22.8512 23.1056 21.6399 23.8964 20.7859L23.9159 20.7644C24.907 19.7522 25.7243 18.8633 26.3534 18.2563C26.9604 17.6706 27.6259 17.1018 28.3954 16.9315ZM28.8483 18.9812C28.7231 19.009 28.4416 19.1586 27.8104 19.7677C27.2047 20.3521 26.495 21.1283 25.4344 22.2122C25.1404 22.5296 24.8951 23.1339 24.9016 24.1369C24.908 25.1265 25.1632 26.3943 25.7325 27.8765C26.8692 30.8359 29.2031 34.5046 32.9466 38.2544C36.6886 41.999 40.4006 44.3165 43.3831 45.4465C44.8776 46.0127 46.1532 46.2677 47.1362 46.2781C48.0173 46.2875 48.5517 46.1025 48.8411 45.8916L48.9507 45.7993C50.0728 44.683 50.8764 43.9194 51.4436 43.3024C52.0419 42.6517 52.1622 42.3794 52.1792 42.2791C52.1805 42.2715 52.1852 42.2639 52.1659 42.2186C52.1374 42.1519 52.0636 42.0275 51.8811 41.8269C51.5003 41.4086 50.8667 40.8877 49.8657 40.0735C48.8275 39.2363 48.1245 38.6743 47.5778 38.3201C47.0224 37.9602 46.8062 37.9378 46.7243 37.9427C46.6501 37.9473 46.4685 37.9864 46.0143 38.3765C45.5573 38.769 45.016 39.3399 44.1721 40.1853L44.171 40.1863C43.5047 40.8519 42.6371 40.9087 41.8995 40.7472C41.1828 40.5902 40.4367 40.2047 39.7274 39.7423C38.305 38.8151 36.7249 37.3767 35.3042 35.9576C35.294 35.9481 35.2824 35.9399 35.2725 35.9299C33.8456 34.4989 32.3971 32.9026 31.4661 31.4674C31.0052 30.7568 30.6197 30.0104 30.4641 29.2925C30.3039 28.5535 30.3635 27.6854 31.0286 27.0192C31.8753 26.1703 32.4463 25.6257 32.838 25.1674C33.2273 24.7119 33.2651 24.5318 33.2694 24.4588C33.2741 24.3772 33.251 24.1614 32.8903 23.6047C32.535 23.0564 31.9736 22.3519 31.1372 21.3088C30.3001 20.2663 29.7515 19.6252 29.3237 19.2581C29.1183 19.0819 28.9917 19.0146 28.9262 18.9904C28.8815 18.974 28.8682 18.9768 28.8483 18.9812Z" fill="black"/>
9
5
  </svg>
@@ -5,6 +5,7 @@
5
5
  @use "../../../styles/tokens/breakpoint";
6
6
  @use "../../../styles/tools/generate";
7
7
  @use "../../../styles/tools/convert";
8
+ @use "../../../styles/tools/layout";
8
9
  @use "../../../styles/typography/mixins" as typoMixins;
9
10
  @use "./config";
10
11
  @use "sass:math";
@@ -82,10 +83,7 @@
82
83
  @mixin body {
83
84
  margin-top: space.get();
84
85
  margin-bottom: space.get("large");
85
-
86
- p:last-child {
87
- margin-bottom: 0;
88
- }
86
+ @include layout.reset-last-child-margin-bottom;
89
87
  }
90
88
 
91
89
  @mixin icon {
@@ -1,5 +1,6 @@
1
1
  @use "./config";
2
2
  @use "../../../styles/tools/generate";
3
+ @use "../../../styles/tools/layout";
3
4
  @use "../../../styles/tools/convert";
4
5
  @use "../../../styles/tokens/space";
5
6
  @use "../../../styles/tokens/breakpoint";
@@ -37,6 +38,7 @@
37
38
 
38
39
  @mixin card-section($spacing) {
39
40
  @include card-spacing($spacing);
41
+ @include layout.reset-last-child-margin-bottom;
40
42
  }
41
43
 
42
44
  @mixin card-section-actions() {
@@ -18,7 +18,6 @@
18
18
  flex-direction: column;
19
19
  margin: 0 auto;
20
20
  position: relative;
21
- margin-bottom: space.get("large");
22
21
  }
23
22
 
24
23
  @mixin viewport-wrapper {
@@ -1,7 +1,6 @@
1
1
  @use "sass:map" as sass-map;
2
2
  @use "sass:math";
3
3
  @use "../../../styles/tokens/base";
4
- @use "../../../styles/tokens/space";
5
4
  @use "../../../styles/tools/convert";
6
5
  @use "../../../styles/tools/generate";
7
6
  @use "../../../styles/tokens/breakpoint";
@@ -14,7 +13,6 @@
14
13
  @mixin base {
15
14
  margin: 0 auto;
16
15
  position: relative;
17
- margin-bottom: space.get("large");
18
16
  background: var(--color-surface-primary);
19
17
  border-bottom: 1px solid var(--color-border-subtle);
20
18
  }
@@ -1,6 +1,7 @@
1
1
  @use "sass:map";
2
2
  @use "../../../styles/tokens/color";
3
3
  @use "../../../styles/tools/generate";
4
+ @use "../../../styles/tools/layout";
4
5
  @use "./config";
5
6
 
6
7
  @mixin base {
@@ -13,6 +14,7 @@
13
14
  transform: translate3d(0, 0, 0);
14
15
  z-index: 1;
15
16
  width: 100%;
17
+ @include layout.reset-last-child-margin-bottom;
16
18
  }
17
19
 
18
20
  @mixin content-size($size, $config: config.$sizes) {
@@ -3,13 +3,11 @@ import toggle from "../../scripts/modules/toggleUtil";
3
3
  interface FeatureAccordionConfig {
4
4
  bodiesSelector: string;
5
5
  buttonSelector: string;
6
- imageSelector: string;
7
6
  }
8
7
 
9
8
  const defaultConfig: FeatureAccordionConfig = {
10
9
  bodiesSelector: ".accordion__body",
11
10
  buttonSelector: "[data-feature-accordion-toggle]",
12
- imageSelector: "[data-feature-accordion-image]",
13
11
  };
14
12
 
15
13
  export default class FeatureAccordion {
@@ -18,7 +16,6 @@ export default class FeatureAccordion {
18
16
  private bodies: HTMLElement[] = [];
19
17
  private buttons: HTMLElement[] = [];
20
18
  private images: HTMLElement[] = [];
21
- private activeId: string | null = null;
22
19
 
23
20
  constructor(element: HTMLElement, config?: Partial<FeatureAccordionConfig>) {
24
21
  this.element = element;
@@ -35,8 +32,9 @@ export default class FeatureAccordion {
35
32
  this.buttons = Array.from(
36
33
  this.element.querySelectorAll(this.config.buttonSelector),
37
34
  );
38
-
39
- this.generateImagesFromDataAttributes();
35
+ this.images = Array.from(
36
+ this.element.querySelectorAll("[data-feature-accordion-image]"),
37
+ ) as HTMLElement[];
40
38
 
41
39
  this.setActive(0);
42
40
 
@@ -45,71 +43,6 @@ export default class FeatureAccordion {
45
43
  });
46
44
  }
47
45
 
48
- private generateImagesFromDataAttributes(): void {
49
- const desktopPreview = this.element.querySelector(
50
- ".feature-accordion__preview.show-md",
51
- );
52
-
53
- if (!desktopPreview) return;
54
-
55
- const existingImages = desktopPreview.querySelectorAll(
56
- this.config.imageSelector,
57
- );
58
-
59
- if (existingImages.length > 0) {
60
- this.images = Array.from(existingImages) as HTMLElement[];
61
- return;
62
- }
63
-
64
- this.images = [];
65
-
66
- this.buttons.forEach((button) => {
67
- const imageUrl = button.getAttribute("data-image-url");
68
- const imageAlt = button.getAttribute("data-image-alt") || "";
69
- const imageSrcSet = button.getAttribute("data-image-srcset");
70
-
71
- if (!imageUrl) return;
72
-
73
- const img = document.createElement("img");
74
- img.setAttribute("data-feature-accordion-image", "");
75
- img.src = imageUrl;
76
- img.alt = imageAlt;
77
- if (imageSrcSet) {
78
- img.srcset = imageSrcSet;
79
- }
80
-
81
- desktopPreview.appendChild(img);
82
- this.images.push(img);
83
-
84
- const bodyId = button.getAttribute("aria-controls");
85
- if (bodyId) {
86
- const body = document.getElementById(bodyId);
87
- if (body) {
88
- let mobilePreview = body.querySelector(
89
- ".feature-accordion__preview.hide-md",
90
- );
91
-
92
- if (!mobilePreview) {
93
- mobilePreview = document.createElement("div");
94
- mobilePreview.className = "feature-accordion__preview hide-md";
95
- body.appendChild(mobilePreview);
96
- }
97
-
98
- const mobileImg = document.createElement("img");
99
- mobileImg.setAttribute("data-feature-accordion-image", "");
100
- mobileImg.src = imageUrl;
101
- mobileImg.alt = imageAlt;
102
- mobileImg.className = "feature-accordion__image--mobile";
103
- if (imageSrcSet) {
104
- mobileImg.srcset = imageSrcSet;
105
- }
106
-
107
- mobilePreview.appendChild(mobileImg);
108
- }
109
- }
110
- });
111
- }
112
-
113
46
  private onClick = (e: Event): void => {
114
47
  const button = e.currentTarget as HTMLElement;
115
48
  const index = this.buttons.indexOf(button);
@@ -118,7 +51,6 @@ export default class FeatureAccordion {
118
51
 
119
52
  private setActive(index: number): void {
120
53
  if (index < 0 || index >= this.buttons.length) return;
121
- this.activeId = this.buttons[index].getAttribute("id");
122
54
 
123
55
  this.bodies.forEach((body) => {
124
56
  body.setAttribute("hidden", "");
@@ -4,8 +4,6 @@ import cx from "classnames";
4
4
  import React, { RefCallback, useMemo } from "react";
5
5
  import { useStatic } from "../../utils/hooks";
6
6
  import { Accordion } from "../Accordion/Accordion";
7
- import { Grid } from "../Grid/Grid";
8
- import { GridCol } from "../Grid/GridCol";
9
7
  import { Image } from "../Image";
10
8
  import FeatureAccordionStatic from "./FeatureAccordion.static";
11
9
 
@@ -19,6 +17,7 @@ export interface FeatureAccordionImageSrc {
19
17
  export interface FeatureAccordionImageResponsive {
20
18
  default: string;
21
19
  sm?: string;
20
+ md?: string;
22
21
  lg?: string;
23
22
  xl?: string;
24
23
  xxl?: string;
@@ -32,12 +31,21 @@ export type FeatureAccordionImage =
32
31
  interface AccordionProps {
33
32
  /** Additional CSS classes */
34
33
  className?: string;
34
+ /** Additional CSS classes for preview area */
35
+ previewClassName?: string;
35
36
  }
36
37
 
38
+ const getImageData = (props: Record<string, any>) => ({
39
+ id: props.id,
40
+ imageSrc: props.image || props.imageUrl,
41
+ imageAlt: props.imageAlt,
42
+ imageSrcSet: props.imageSrcSet,
43
+ });
44
+
37
45
  const FeatureAccordion = (
38
46
  props: AccordionProps & { children: React.ReactNode },
39
47
  ) => {
40
- const { className, children, ...other } = props;
48
+ const { className, previewClassName, children, ...other } = props;
41
49
  const [featureAccordionRef] = useStatic(FeatureAccordionStatic);
42
50
 
43
51
  const classes = cx(CLASS_ROOT, className);
@@ -50,73 +58,29 @@ const FeatureAccordion = (
50
58
  // Extract image data once to avoid duplication
51
59
  const childrenWithImageData = useMemo(
52
60
  () =>
53
- childrenArray.map((child) => ({
54
- child,
55
- id: child.props.id,
56
- imageSrc:
57
- child.props["data-image"] ||
58
- child.props.image ||
59
- child.props["data-image-url"] ||
60
- child.props.imageUrl,
61
- imageAlt: child.props["data-image-alt"] || child.props.imageAlt,
62
- imageSrcSet:
63
- child.props["data-image-srcset"] || child.props.imageSrcSet,
64
- imageUrl: child.props["data-image-url"] || child.props.imageUrl,
65
- })),
61
+ childrenArray.map((child) => ({ child, ...getImageData(child.props) })),
66
62
  [childrenArray],
67
63
  );
68
64
 
69
65
  return (
70
- <Grid
66
+ <div
71
67
  className={classes}
72
68
  data-feature-accordion
73
69
  ref={featureAccordionRef as RefCallback<HTMLDivElement>}
74
70
  {...other}
75
71
  >
76
- <GridCol
77
- size={{
78
- xs: 12,
79
- md: 6,
80
- }}
81
- className={`${CLASS_ROOT}__accordion`}
82
- >
72
+ <div className={`${CLASS_ROOT}__accordion`}>
83
73
  <Accordion>
84
- {childrenWithImageData.map(
85
- ({ child, id, imageSrc, imageAlt, imageSrcSet, imageUrl }) => {
86
- if (!imageSrc) return null;
74
+ {childrenWithImageData.map(({ child, imageSrc }) => {
75
+ if (!imageSrc) return null;
87
76
 
88
- return React.cloneElement(child, {
89
- children: (
90
- <>
91
- <div className={`${CLASS_ROOT}__content`}>
92
- {child.props.children}
93
- </div>
94
- <div className={cx(`${CLASS_ROOT}__preview`, "hide-md")}>
95
- <Image
96
- key={id}
97
- data-feature-accordion-image
98
- src={imageSrc}
99
- alt={imageAlt}
100
- srcSet={imageSrcSet}
101
- className={`${CLASS_ROOT}__image--mobile`}
102
- />
103
- </div>
104
- </>
105
- ),
106
- });
107
- },
108
- )}
77
+ return child;
78
+ })}
109
79
  </Accordion>
110
- </GridCol>
111
- <GridCol
112
- size={{
113
- xs: 12,
114
- md: 6,
115
- }}
116
- className={cx(`${CLASS_ROOT}__preview`, "show-md")}
117
- >
80
+ </div>
81
+ <div className={cx(`${CLASS_ROOT}__preview`, previewClassName)}>
118
82
  {childrenWithImageData.map(
119
- ({ id, imageSrc, imageAlt, imageSrcSet, imageUrl }, index) => {
83
+ ({ id, imageSrc, imageAlt, imageSrcSet }, index) => {
120
84
  if (!imageSrc) return null;
121
85
 
122
86
  return (
@@ -131,8 +95,8 @@ const FeatureAccordion = (
131
95
  );
132
96
  },
133
97
  )}
134
- </GridCol>
135
- </Grid>
98
+ </div>
99
+ </div>
136
100
  );
137
101
  };
138
102
 
@@ -3,11 +3,13 @@
3
3
  import cx from "classnames";
4
4
  import React from "react";
5
5
  import { AccordionItem, AccordionItemProps } from "../Accordion/AccordionItem";
6
+ import type { FeatureAccordionImage } from "./FeatureAccordion";
6
7
 
7
8
  const CLASS_ROOT = "feature-accordion__item";
9
+ const CLASS_CONTENT = "feature-accordion__content";
8
10
 
9
11
  interface FeatureAccordionItemProps extends AccordionItemProps {
10
- image?: string | object;
12
+ image?: string | FeatureAccordionImage;
11
13
  imageUrl?: string;
12
14
  imageAlt?: string;
13
15
  imageSrcSet?: string;
@@ -15,25 +17,18 @@ interface FeatureAccordionItemProps extends AccordionItemProps {
15
17
  }
16
18
 
17
19
  const FeatureAccordionItem: React.FC<FeatureAccordionItemProps> = ({
18
- image,
19
- imageUrl,
20
- imageAlt,
21
- imageSrcSet,
20
+ image: _image,
21
+ imageUrl: _imageUrl,
22
+ imageAlt: _imageAlt,
23
+ imageSrcSet: _imageSrcSet,
22
24
  className,
25
+ children,
23
26
  ...props
24
27
  }) => {
25
- const dataImageUrl = props["data-image-url"] || imageUrl;
26
- const dataImageAlt = props["data-image-alt"] || imageAlt;
27
- const dataImage = props["data-image"] || image;
28
- const dataImageSrcSet = props["data-image-srcset"] || imageSrcSet;
29
-
30
28
  return (
31
29
  <AccordionItem
32
30
  className={cx(CLASS_ROOT, className)}
33
- data-image-url={dataImageUrl}
34
- data-image-alt={dataImageAlt}
35
- data-image={dataImage}
36
- data-image-srcset={dataImageSrcSet}
31
+ children={<div className={CLASS_CONTENT}>{children}</div>}
37
32
  toggleAttribute="data-feature-accordion-toggle"
38
33
  {...props}
39
34
  />
@@ -1,48 +1,92 @@
1
- @use "sass:map" as sass-map;
2
1
  @use "../../../styles/tools/convert";
3
- @use "../../../styles/tools/generate";
4
2
  @use "../../../styles/tokens/space";
5
3
  @use "../../../styles/tokens/breakpoint";
6
4
 
5
+ $preview-width: convert.to-rem(640px);
6
+ $preview-height: convert.to-rem(480px);
7
+
8
+ @mixin desktop-layout {
9
+ @include breakpoint.get("xl") {
10
+ display: flex;
11
+ align-items: flex-start;
12
+ min-height: $preview-height;
13
+ }
14
+ }
15
+
7
16
  @mixin base {
8
17
  color: var(--color-text-default);
9
18
  background-color: var(--color-background-secondary);
10
- margin-left: 0 !important;
11
- margin-right: 0 !important;
19
+ width: 100%;
20
+ @include desktop-layout();
12
21
  }
13
22
 
14
23
  @mixin accordion {
15
- padding-left: 0 !important;
16
- padding-right: 0 !important;
24
+ width: 100%;
25
+
26
+ @include breakpoint.get("xl") {
27
+ flex: 1 1 0;
28
+ min-width: 0;
29
+ min-height: $preview-height;
30
+ display: flex;
31
+ flex-direction: column;
32
+ justify-content: center;
33
+ padding: convert.to-rem(40px) convert.to-rem(60px);
34
+ }
17
35
 
18
36
  .accordion {
19
- margin: convert.to-rem(87px) space.get("xlarge");
20
-
21
- @include breakpoint.get("md", "down") {
22
- margin: space.get("xlarge") space.get("large");
23
- }
24
-
25
- @include breakpoint.get("sm", "down") {
26
- margin: 0;
27
- }
37
+ width: 100%;
38
+ margin: 0;
28
39
  }
29
40
  }
30
41
 
31
42
  @mixin preview {
32
- display: flex;
33
- padding: 0px !important;
43
+ display: block;
44
+ justify-content: center;
45
+ overflow: hidden;
46
+ width: 100%;
47
+
48
+ @include breakpoint.get("xl") {
49
+ display: flex;
50
+ flex: 0 0 $preview-width;
51
+ width: $preview-width;
52
+ align-self: flex-start;
53
+ }
54
+
55
+ @include breakpoint.get("xl") {
56
+ align-items: stretch;
57
+ }
58
+
59
+ @include breakpoint.get("xl", "down") {
60
+ display: block;
61
+ height: auto;
62
+ }
34
63
 
35
64
  .img {
36
- margin-bottom: 0px;
65
+ margin-bottom: 0;
37
66
  width: 100%;
67
+
68
+ @include breakpoint.get("xl") {
69
+ width: 100%;
70
+ height: auto;
71
+ }
38
72
  }
39
73
 
40
74
  img {
75
+ display: block;
76
+ max-width: 100%;
41
77
  width: 100%;
42
- height: 100%;
43
- object-fit: cover;
44
- object-position: left center;
45
- margin: 0px !important;
78
+ object-fit: contain;
79
+ object-position: right center;
80
+ margin: 0 !important;
81
+
82
+ @include breakpoint.get("xl") {
83
+ height: auto;
84
+ }
85
+
86
+ @include breakpoint.get("xl", "down") {
87
+ height: auto;
88
+ width: 100%;
89
+ }
46
90
  }
47
91
  }
48
92
 
@@ -70,11 +114,7 @@
70
114
  border-top: 4px solid var(--color-border-accent);
71
115
  }
72
116
 
73
- .accordion__body {
74
- margin-bottom: 0;
75
- }
76
-
77
- @include breakpoint.get("sm", "down") {
117
+ @include breakpoint.get("lg", "down") {
78
118
  .accordion__header,
79
119
  .feature-accordion__content {
80
120
  padding-left: convert.to-rem(15px);
@@ -92,4 +92,13 @@ describe("FeatureAccordion", () => {
92
92
  const { container } = renderAccordion({ "data-testid": "fa" });
93
93
  expect(container.firstChild).toHaveAttribute("data-testid", "fa");
94
94
  });
95
+
96
+ it("applies previewClassName to preview area", () => {
97
+ const { container } = renderAccordion({
98
+ previewClassName: "align-self-middle--xl",
99
+ });
100
+ expect(container.querySelector(".feature-accordion__preview")).toHaveClass(
101
+ "align-self-middle--xl",
102
+ );
103
+ });
95
104
  });
@@ -1,12 +1,33 @@
1
1
  @use "sass:map";
2
2
  @use "sass:math";
3
3
 
4
+ @use "./../../Container/styles/config" as container;
4
5
  @use "./../../../styles/tools/generate";
5
6
  @use "./../../../styles/tools/layout";
6
7
  @use "./../../../styles/tokens/breakpoint";
7
8
  @use "./../../../styles/tokens/space";
8
9
  @use "./config";
9
10
 
11
+ @function safe-md-grid-gap($gap) {
12
+ @return min(
13
+ #{$gap},
14
+ calc(
15
+ (100vw - #{map.get(container.$container-widths, "md")}) / 2 +
16
+ #{container.$container-padding}
17
+ )
18
+ );
19
+ }
20
+
21
+ @function safe-md-negative-grid-margin($gap) {
22
+ @return max(
23
+ -#{$gap},
24
+ calc(
25
+ (#{map.get(container.$container-widths, "md")} - 100vw) / 2 -
26
+ #{container.$container-padding}
27
+ )
28
+ );
29
+ }
30
+
10
31
  @mixin grid-base() {
11
32
  display: flex;
12
33
  max-width: none;
@@ -39,7 +60,13 @@
39
60
  margin-right: -$gap !important;
40
61
  }
41
62
  } @else {
42
- @include breakpoint.get("md") {
63
+ // Clamp bleed only in md band where large gutters can exceed container side room.
64
+ @include breakpoint.get("md", "only") {
65
+ margin-left: safe-md-negative-grid-margin($gap) !important;
66
+ margin-right: safe-md-negative-grid-margin($gap) !important;
67
+ }
68
+
69
+ @include breakpoint.get("lg") {
43
70
  margin-left: -$gap !important;
44
71
  margin-right: -$gap !important;
45
72
  }
@@ -107,7 +134,12 @@
107
134
  padding-left: $gap !important;
108
135
  padding-right: $gap !important;
109
136
  } @else {
110
- @include breakpoint.get("md") {
137
+ @include breakpoint.get("md", "only") {
138
+ padding-left: safe-md-grid-gap($gap) !important;
139
+ padding-right: safe-md-grid-gap($gap) !important;
140
+ }
141
+
142
+ @include breakpoint.get("lg") {
111
143
  padding-left: $gap !important;
112
144
  padding-right: $gap !important;
113
145
  }
@@ -1,11 +1,13 @@
1
1
  @use "../../../styles/tokens/space";
2
2
  @use "../../../styles/tools/convert";
3
3
  @use "../../../styles/typography/mixins" as typoMixins;
4
+ @use "../../../styles/tools/layout";
4
5
  @use "./config";
5
6
 
6
7
  @mixin base() {
7
8
  @include typoMixins.list-unstyled;
8
9
  @include typoMixins.text-readable;
10
+ @include layout.reset-last-child-margin-bottom;
9
11
 
10
12
  margin: 0 0 space.get("large") 0;
11
13
  padding: 0;
@@ -25,7 +27,6 @@
25
27
 
26
28
  @mixin content() {
27
29
  flex: 1 0 1px;
28
- margin-top: convert.to-rem(2px);
29
30
  }
30
31
 
31
32
  @mixin content-text() {
@@ -46,4 +46,12 @@
46
46
  .link__icon-right {
47
47
  @include mixins.icon-right;
48
48
  }
49
+
50
+ a:has(.link__icon-left),
51
+ .link:has(.link__icon-left),
52
+ a:has(.link__icon-right),
53
+ .link:has(.link__icon-right) {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ }
49
57
  }