@orangesk/orange-design-system 2.0.0-beta.7 → 2.0.0-beta.9

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 (67) hide show
  1. package/build/components/index.js +4 -4
  2. package/build/components/index.js.map +1 -1
  3. package/build/components/tsconfig.tsbuildinfo +1 -1
  4. package/build/components/types/index.d.ts +12 -8
  5. package/build/components/types/src/components/AnchorNavigation/AnchorNavigation.d.ts +1 -1
  6. package/build/components/types/src/components/AnchorNavigation/AnchorNavigation.static.d.ts +19 -17
  7. package/build/components/types/src/components/Button/Button.d.ts +1 -0
  8. package/build/components/types/src/components/Card/Card.d.ts +2 -1
  9. package/build/components/types/src/components/Carousel/Carousel.d.ts +4 -0
  10. package/build/components/types/src/components/Carousel/Carousel.static.d.ts +1 -0
  11. package/build/components/types/src/components/Carousel/constants.d.ts +2 -0
  12. package/build/components/types/src/components/Megamenu/constants.d.ts +2 -0
  13. package/build/components/types/src/components/Pill/Pill.d.ts +1 -1
  14. package/build/components/types/src/components/PromoBanner/PromoBanner.d.ts +3 -5
  15. package/build/components/types/src/scripts/index.d.ts +5 -0
  16. package/build/lib/after-components.css +1 -1
  17. package/build/lib/after-components.css.map +1 -1
  18. package/build/lib/before-components.css +1 -1
  19. package/build/lib/before-components.css.map +1 -1
  20. package/build/lib/components.css +1 -1
  21. package/build/lib/components.css.map +1 -1
  22. package/build/lib/megamenu.css +1 -1
  23. package/build/lib/megamenu.css.map +1 -1
  24. package/build/lib/megamenu.js +1 -1
  25. package/build/lib/megamenu.js.map +1 -1
  26. package/build/lib/scripts.js +4 -4
  27. package/build/lib/scripts.js.map +1 -1
  28. package/build/lib/style.css +1 -1
  29. package/build/lib/style.css.map +1 -1
  30. package/build/lib/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +16 -16
  32. package/src/components/AnchorNavigation/AnchorNavigation.static.ts +253 -73
  33. package/src/components/AnchorNavigation/AnchorNavigation.tsx +31 -24
  34. package/src/components/AnchorNavigation/styles/mixins.scss +14 -17
  35. package/src/components/AnchorNavigation/tests/AnchorNavigation.conformance.test.js +67 -0
  36. package/src/components/AnchorNavigation/tests/AnchorNavigation.unit.test.js +163 -0
  37. package/src/components/BlockAction/styles/mixins.scss +0 -6
  38. package/src/components/Button/Button.tsx +2 -0
  39. package/src/components/Button/styles/mixins.scss +5 -0
  40. package/src/components/Button/styles/style.scss +4 -0
  41. package/src/components/Card/Card.tsx +5 -1
  42. package/src/components/Card/styles/style.scss +4 -0
  43. package/src/components/Carousel/Carousel.static.ts +67 -1
  44. package/src/components/Carousel/Carousel.tsx +41 -19
  45. package/src/components/Carousel/constants.ts +2 -0
  46. package/src/components/Carousel/styles/config.scss +1 -2
  47. package/src/components/Carousel/styles/mixins.scss +35 -2
  48. package/src/components/Carousel/styles/style.scss +8 -0
  49. package/src/components/Icon/styles/style.scss +11 -0
  50. package/src/components/Icon/tests/Pictogram.unit.test.js +38 -0
  51. package/src/components/Link/styles/style.scss +1 -1
  52. package/src/components/Link/tests/Link.conformance.test.js +5 -20
  53. package/src/components/Link/tests/Link.unit.test.js +1 -10
  54. package/src/components/Megamenu/Megamenu.static.ts +2 -0
  55. package/src/components/Megamenu/Megamenu.tsx +671 -665
  56. package/src/components/Megamenu/MegamenuBlog.tsx +187 -183
  57. package/src/components/Megamenu/constants.ts +2 -0
  58. package/src/components/Megamenu/styles/mixins.scss +30 -1
  59. package/src/components/Megamenu/styles/style.scss +8 -0
  60. package/src/components/Pill/Pill.tsx +1 -1
  61. package/src/components/Pill/styles/config.scss +4 -0
  62. package/src/components/Preview/PreviewGenerator.tsx +48 -21
  63. package/src/components/PromoBanner/PromoBanner.tsx +14 -26
  64. package/src/components/PromoBanner/styles/mixins.scss +20 -21
  65. package/src/components/PromoBanner/styles/style.scss +0 -6
  66. package/src/styles/base/globals.scss +19 -0
  67. package/src/styles/utilities/color.scss +94 -20
@@ -32,143 +32,145 @@ import {
32
32
  CLASS_ACCORDION_HEADER,
33
33
  CLASS_ACCORDION_ITEM,
34
34
  CLASS_ACCORDION_TITLE,
35
+ CLASS_SPACER_SMALL,
35
36
  } from "./constants";
36
37
 
37
38
  export const MegamenuBlog = ({ className }: any) => {
38
39
  return (
39
- <nav
40
- className={cx(CLASS_ROOT, className)}
41
- data-megamenu
42
- aria-label="Main navigation"
43
- >
44
- <div className={CLASS_MAIN}>
45
- <div className={CLASS_CONTAINER}>
46
- <h2 id="menu-title" className="sr-only">
47
- Hlavné menu
48
- </h2>
49
- <ul className={CLASS_NAV} aria-labelledby="menu-title">
50
- <li className={cx(CLASS_NAV_ITEM, CLASS_NAV_ITEM_MAIN)}>
51
- <a
52
- href="#"
53
- className={CLASS_NAV_LOGO}
54
- aria-label="Domovská stránka"
55
- >
56
- <svg
57
- viewBox="0 0 40 40"
58
- fill="none"
59
- xmlns="http://www.w3.org/2000/svg"
60
- aria-hidden="true"
40
+ <header>
41
+ <nav
42
+ className={cx(CLASS_ROOT, className)}
43
+ data-megamenu
44
+ aria-label="Main navigation"
45
+ >
46
+ <div className={CLASS_MAIN}>
47
+ <div className={CLASS_CONTAINER}>
48
+ <h2 id="menu-title" className="sr-only">
49
+ Hlavné menu
50
+ </h2>
51
+ <ul className={CLASS_NAV} aria-labelledby="menu-title">
52
+ <li className={cx(CLASS_NAV_ITEM, CLASS_NAV_ITEM_MAIN)}>
53
+ <a
54
+ href="#"
55
+ className={CLASS_NAV_LOGO}
56
+ aria-label="Domovská stránka"
61
57
  >
62
- <path d="M40 0H0V40H40V0Z" fill="#FF7900" />
63
- <path
64
- d="M34.2897 28.57H5.71973V34.28H34.2897V28.57Z"
65
- fill="white"
66
- />
67
- </svg>
68
- <span>Človek</span>
69
- </a>
70
- </li>
71
-
72
- <li
73
- className={cx(
74
- CLASS_NAV_ITEM,
75
- CLASS_NAV_ITEM_MAIN,
76
- CLASS_HIDE_MD_DOWN,
77
- )}
78
- >
79
- <a href="#" className={cx(CLASS_NAV_LINK)}>
80
- Naspať na Orange
81
- </a>
82
- </li>
83
-
84
- <li className={CLASS_NAV_SPACER} aria-hidden="true"></li>
58
+ <svg
59
+ viewBox="0 0 40 40"
60
+ fill="none"
61
+ xmlns="http://www.w3.org/2000/svg"
62
+ aria-hidden="true"
63
+ >
64
+ <path d="M40 0H0V40H40V0Z" fill="#FF7900" />
65
+ <path
66
+ d="M34.2897 28.57H5.71973V34.28H34.2897V28.57Z"
67
+ fill="white"
68
+ />
69
+ </svg>
70
+ <span>Človek</span>
71
+ </a>
72
+ </li>
85
73
 
86
- <li className={cx(CLASS_NAV_ITEM, CLASS_HIDE_MD_DOWN)}>
87
- <button
88
- type="button"
89
- className={CLASS_NAV_BUTTON}
90
- aria-label="Vyhľadávanie"
91
- aria-controls="megamenu-search"
92
- aria-expanded="false"
93
- aria-haspopup="true"
74
+ <li
75
+ className={cx(
76
+ CLASS_NAV_ITEM,
77
+ CLASS_NAV_ITEM_MAIN,
78
+ CLASS_HIDE_MD_DOWN,
79
+ )}
94
80
  >
95
- <MegamenuIcon
96
- width={24}
97
- height={24}
98
- name="search"
99
- aria-hidden="true"
100
- />
101
- </button>
81
+ <a href="#" className={cx(CLASS_NAV_LINK)}>
82
+ Naspať na Orange
83
+ </a>
84
+ </li>
85
+
86
+ <li className={CLASS_NAV_SPACER} aria-hidden="true"></li>
102
87
 
103
- <div className={CLASS_NAV_DROPDOWN} id="megamenu-search">
104
- <div className={CLASS_CONTAINER}>
105
- <input
106
- className={cx(
107
- CLASS_INPUT,
108
- CLASS_INPUT_SEARCH_ICON_WITH_PLACEHOLDER,
109
- )}
110
- id="search-1"
111
- type="text"
112
- placeholder="Search"
113
- name="search-1"
88
+ <li className={cx(CLASS_NAV_ITEM, CLASS_HIDE_MD_DOWN)}>
89
+ <button
90
+ type="button"
91
+ className={CLASS_NAV_BUTTON}
92
+ aria-label="Vyhľadávanie"
93
+ aria-controls="megamenu-search"
94
+ aria-expanded="false"
95
+ aria-haspopup="true"
96
+ >
97
+ <MegamenuIcon
98
+ width={24}
99
+ height={24}
100
+ name="search"
101
+ aria-hidden="true"
114
102
  />
115
- <ul className={CLASS_SUBNAV}>
116
- <li className={CLASS_SUBNAV_ITEM}>
117
- <a href="#">apple</a>
118
- </li>
119
- <li className={CLASS_SUBNAV_ITEM}>
120
- <a href="#">apple hodinky</a>
121
- </li>
122
- <li className={CLASS_SUBNAV_ITEM}>
123
- <a href="#">apple iphone</a>
124
- </li>
125
- <li className={CLASS_SUBNAV_ITEM}>
126
- <a href="#">apple 16</a>
127
- </li>
128
- <li className={CLASS_SUBNAV_ITEM}>
129
- <a href="#">apple pro</a>
130
- </li>
131
- <li className={CLASS_SUBNAV_ITEM}>
132
- <a href="#">apple watch</a>
133
- </li>
134
- </ul>
103
+ </button>
104
+
105
+ <div className={CLASS_NAV_DROPDOWN} id="megamenu-search">
106
+ <div className={CLASS_CONTAINER}>
107
+ <input
108
+ className={cx(
109
+ CLASS_INPUT,
110
+ CLASS_INPUT_SEARCH_ICON_WITH_PLACEHOLDER,
111
+ )}
112
+ id="search-1"
113
+ type="text"
114
+ placeholder="Search"
115
+ name="search-1"
116
+ />
117
+ <ul className={CLASS_SUBNAV}>
118
+ <li className={CLASS_SUBNAV_ITEM}>
119
+ <a href="#">apple</a>
120
+ </li>
121
+ <li className={CLASS_SUBNAV_ITEM}>
122
+ <a href="#">apple hodinky</a>
123
+ </li>
124
+ <li className={CLASS_SUBNAV_ITEM}>
125
+ <a href="#">apple iphone</a>
126
+ </li>
127
+ <li className={CLASS_SUBNAV_ITEM}>
128
+ <a href="#">apple 16</a>
129
+ </li>
130
+ <li className={CLASS_SUBNAV_ITEM}>
131
+ <a href="#">apple pro</a>
132
+ </li>
133
+ <li className={CLASS_SUBNAV_ITEM}>
134
+ <a href="#">apple watch</a>
135
+ </li>
136
+ </ul>
137
+ </div>
135
138
  </div>
136
- </div>
137
- </li>
138
- <li className={CLASS_NAV_ITEM}>
139
- <a href="#" className={CLASS_NAV_LINK}>
140
- <MegamenuIcon
141
- width={24}
142
- height={24}
143
- name="user"
144
- className={CLASS_NAV_ICON}
145
- aria-hidden="true"
146
- />
147
- Môj Orange
148
- </a>
149
- </li>
150
- <li className={cx(CLASS_NAV_ITEM, CLASS_HIDE_LG_UP)}>
151
- <button
152
- type="button"
153
- className={CLASS_NAV_BUTTON}
154
- aria-label="Otvoriť menu"
155
- aria-haspopup="true"
156
- aria-expanded="false"
157
- >
158
- <MegamenuIcon
159
- width={24}
160
- height={24}
161
- name="menu"
162
- aria-hidden="true"
163
- />
164
- </button>
165
- </li>
166
- </ul>
139
+ </li>
140
+ <li className={CLASS_NAV_ITEM}>
141
+ <a href="#" className={CLASS_NAV_LINK}>
142
+ <MegamenuIcon
143
+ width={24}
144
+ height={24}
145
+ name="user"
146
+ className={CLASS_NAV_ICON}
147
+ aria-hidden="true"
148
+ />
149
+ Môj Orange
150
+ </a>
151
+ </li>
152
+ <li className={cx(CLASS_NAV_ITEM, CLASS_HIDE_LG_UP)}>
153
+ <button
154
+ type="button"
155
+ className={CLASS_NAV_BUTTON}
156
+ aria-label="Otvoriť menu"
157
+ aria-haspopup="true"
158
+ aria-expanded="false"
159
+ >
160
+ <MegamenuIcon
161
+ width={24}
162
+ height={24}
163
+ name="menu"
164
+ aria-hidden="true"
165
+ />
166
+ </button>
167
+ </li>
168
+ </ul>
169
+ </div>
167
170
  </div>
168
- </div>
169
171
 
170
- {/* This is not needed, but I'll keep it here if anyone changes his mind to has it as part of megamenu */}
171
- {/* <div className={cx(CLASS_SUBMAIN, CLASS_HIDE_MD_DOWN)}>
172
+ {/* This is not needed, but I'll keep it here if anyone changes his mind to has it as part of megamenu */}
173
+ {/* <div className={cx(CLASS_SUBMAIN, CLASS_HIDE_MD_DOWN)}>
172
174
  <div className={CLASS_CONTAINER}>
173
175
  <ul className={cx(CLASS_LIST_INLINE, CLASS_ALIGN_CENTER)}>
174
176
  <li>
@@ -235,71 +237,73 @@ export const MegamenuBlog = ({ className }: any) => {
235
237
  </div>
236
238
  </div> */}
237
239
 
238
- {/* MOBILE MENU */}
240
+ {/* MOBILE MENU */}
239
241
 
240
- <div
241
- // className={cx(CLASS_MOBILE, "is-active")}
242
- className={cx(CLASS_MOBILE)}
243
- role="dialog"
244
- aria-modal="true"
245
- aria-labelledby="mobile-menu-title"
246
- >
247
- <h2 id="mobile-menu-title" className="sr-only">
248
- Hlavné menu
249
- </h2>
250
- <button
251
- aria-label="Zatvoriť menu"
252
- className={CLASS_MOBILE_OVERLAY}
253
- type="button"
254
- />
242
+ <div
243
+ // className={cx(CLASS_MOBILE, "is-active")}
244
+ className={cx(CLASS_MOBILE)}
245
+ role="dialog"
246
+ aria-modal="true"
247
+ aria-labelledby="mobile-menu-title"
248
+ >
249
+ <h2 id="mobile-menu-title" className="sr-only">
250
+ Hlavné menu
251
+ </h2>
252
+ <button
253
+ aria-label="Zatvoriť menu"
254
+ className={CLASS_MOBILE_OVERLAY}
255
+ type="button"
256
+ />
255
257
 
256
- <div className={CLASS_MOBILE_WRAPPER}>
257
- <div className={CLASS_MOBILE_HEADER}>
258
- <div className={CLASS_CONTAINER}>
259
- <ul className={cx(CLASS_NAV, CLASS_NAV_SPACE_SMALL)}>
260
- <li className={CLASS_NAV_SPACER} aria-hidden="true"></li>
258
+ <div className={CLASS_MOBILE_WRAPPER}>
259
+ <div className={CLASS_MOBILE_HEADER}>
260
+ <div className={CLASS_CONTAINER}>
261
+ <ul className={cx(CLASS_NAV, CLASS_NAV_SPACE_SMALL)}>
262
+ <li className={CLASS_NAV_SPACER} aria-hidden="true"></li>
261
263
 
262
- <li className={CLASS_NAV_ITEM}>
263
- <button
264
- type="button"
265
- data-megamenu-close-button
266
- className={CLASS_NAV_BUTTON}
267
- aria-label="Zatvoriť menu"
268
- >
269
- <MegamenuIcon
270
- name="close"
271
- width={20}
272
- height={20}
273
- aria-hidden="true"
274
- />
275
- </button>
276
- </li>
277
- </ul>
264
+ <li className={CLASS_NAV_ITEM}>
265
+ <button
266
+ type="button"
267
+ data-megamenu-close-button
268
+ className={CLASS_NAV_BUTTON}
269
+ aria-label="Zatvoriť menu"
270
+ >
271
+ <MegamenuIcon
272
+ name="close"
273
+ width={20}
274
+ height={20}
275
+ aria-hidden="true"
276
+ />
277
+ </button>
278
+ </li>
279
+ </ul>
280
+ </div>
278
281
  </div>
279
- </div>
280
- <div className={CLASS_MOBILE_BODY}>
281
- <div className={CLASS_CONTAINER}>
282
- <ul className={CLASS_ACCORDION}>
283
- <li className={CLASS_ACCORDION_ITEM}>
284
- <div className={CLASS_ACCORDION_HEADER}>
285
- <a href="#" className={CLASS_ACCORDION_BUTTON}>
286
- <span className={CLASS_ACCORDION_TITLE}>
287
- Naspať na Orange
288
- </span>
289
- </a>
290
- </div>
291
- </li>
292
- </ul>
282
+ <div className={CLASS_MOBILE_BODY}>
283
+ <div className={CLASS_CONTAINER}>
284
+ <ul className={CLASS_ACCORDION}>
285
+ <li className={CLASS_ACCORDION_ITEM}>
286
+ <div className={CLASS_ACCORDION_HEADER}>
287
+ <a href="#" className={CLASS_ACCORDION_BUTTON}>
288
+ <span className={CLASS_ACCORDION_TITLE}>
289
+ Naspať na Orange
290
+ </span>
291
+ </a>
292
+ </div>
293
+ </li>
294
+ </ul>
295
+ </div>
293
296
  </div>
294
297
  </div>
295
298
  </div>
296
- </div>
297
299
 
298
- <button
299
- aria-label="Zatvoriť dropdown menu"
300
- className={CLASS_OVERLAY}
301
- type="button"
302
- />
303
- </nav>
300
+ <button
301
+ aria-label="Zatvoriť dropdown menu"
302
+ className={CLASS_OVERLAY}
303
+ type="button"
304
+ />
305
+ </nav>
306
+ <div className={CLASS_SPACER_SMALL} aria-hidden="true" />
307
+ </header>
304
308
  );
305
309
  };
@@ -22,6 +22,8 @@ export const CLASS_NAV_DROPDOWN = `${CLASS_ROOT}__nav-dropdown`;
22
22
  export const CLASS_SUBNAV = `${CLASS_ROOT}__subnav`;
23
23
  export const CLASS_SUBNAV_ITEM = `${CLASS_ROOT}__subnav-item`;
24
24
  export const CLASS_OVERLAY = `${CLASS_ROOT}__overlay`;
25
+ export const CLASS_SPACER = `${CLASS_ROOT}-spacer`;
26
+ export const CLASS_SPACER_SMALL = `${CLASS_ROOT}-spacer--small`;
25
27
 
26
28
  export const CLASS_TEXT_LARGE = `${CLASS_ROOT}__text--large`;
27
29
  export const CLASS_HIDE_MD_DOWN = `${CLASS_ROOT}--hide-md-down`;
@@ -140,6 +140,19 @@
140
140
  ~ #{config.$class-root}__main {
141
141
  transform: translateY(-#{convert.to-rem(40px)});
142
142
  }
143
+
144
+ // When top is hidden, reduce the overall container height by the top bar height
145
+ #{config.$class-root}__top[data-hide-when-sticky="true"].is-hidden {
146
+ height: #{convert.to-rem(40px)};
147
+ overflow: hidden;
148
+ }
149
+ }
150
+
151
+ // Adjust container height when top is hidden
152
+ &.top-hidden {
153
+ @include breakpoint.get("lg") {
154
+ height: #{convert.to-rem(80px)} !important;
155
+ }
143
156
  }
144
157
  }
145
158
  }
@@ -239,7 +252,7 @@
239
252
  @mixin nav-link {
240
253
  display: flex;
241
254
  font-weight: 700;
242
- font-size: convert.to-rem(16px);
255
+ font-size: convert.to-rem(16px) !important;
243
256
  align-items: center;
244
257
  color: var(--color-text-default);
245
258
  text-decoration: none;
@@ -571,6 +584,22 @@
571
584
  }
572
585
  }
573
586
 
587
+ @mixin spacer {
588
+ height: convert.to-rem(118px);
589
+
590
+ @include breakpoint.get("md", "down") {
591
+ height: convert.to-rem(58px);
592
+ }
593
+ }
594
+
595
+ @mixin spacer-small {
596
+ height: convert.to-rem(78px);
597
+
598
+ @include breakpoint.get("md", "down") {
599
+ height: convert.to-rem(58px);
600
+ }
601
+ }
602
+
574
603
  @mixin accordion {
575
604
  @include accordion.base;
576
605
  margin-bottom: convert.to-rem(20px);
@@ -139,6 +139,14 @@
139
139
  @include mixins.overlay;
140
140
  }
141
141
 
142
+ &-spacer {
143
+ @include mixins.spacer;
144
+
145
+ &--small {
146
+ @include mixins.spacer-small;
147
+ }
148
+ }
149
+
142
150
  &__accordion {
143
151
  @include mixins.accordion;
144
152
  }
@@ -3,7 +3,7 @@ import cx from "classnames";
3
3
 
4
4
  const CLASS_ROOT = "pill";
5
5
 
6
- export const pillColors = ["white", "gray", "transparent"] as const;
6
+ export const pillColors = ["white", "gray", "transparent", "orange"] as const;
7
7
  export type PillColor = (typeof pillColors)[number];
8
8
 
9
9
  interface PillProps extends HTMLAttributes<HTMLSpanElement> {
@@ -31,6 +31,10 @@ $colors: (
31
31
  background-color: var(--color-surface-subtle),
32
32
  color: var(--color-text-default),
33
33
  ),
34
+ "orange": (
35
+ background-color: var(--color-icon-brand),
36
+ color: var(--color-text-inverse),
37
+ ),
34
38
  "transparent": (
35
39
  background-color: rgba(#ffffff, 0.5),
36
40
  color: var(--color-text-default),
@@ -115,29 +115,36 @@ const getBackgroundsAsArray = (
115
115
  return acc;
116
116
  }, []);
117
117
 
118
- // Map human-friendly color names to bg-* utility classes
118
+ // Map names to only the 6 allowed background classes
119
119
  const getBgClassFromName = (name: string): string => {
120
120
  const normalized = name.toLowerCase().replace(/\s+/g, "-");
121
- const n = normalized === "grey" ? "gray" : normalized;
122
- if (n === "none") return "bg-none";
123
- return `bg-${n}`; // e.g. white -> bg-white, orange-dark -> bg-orange-dark
124
- };
125
121
 
126
- // Determine contrast helper class for nested component styling
127
- const getThemeClassFromName = (name: string): string => {
128
- const n = name.toLowerCase();
129
- // Only black switches global dark tokens; other colors keep light tokens
130
- return n === "black" ? "is-dark" : "is-light";
122
+ // Only allow these background classes
123
+ const allowedBackgrounds = [
124
+ "background-primary",
125
+ "background-secondary",
126
+ "background-contrast",
127
+ "background-accent",
128
+ "background-accent1-blog",
129
+ "background-accent2-blog",
130
+ "background-none",
131
+ ];
132
+
133
+ // Return the class if it's in the allowed list, otherwise default to background-primary
134
+ return allowedBackgrounds.includes(normalized)
135
+ ? normalized
136
+ : "background-primary";
131
137
  };
132
138
 
133
139
  const PreviewGenerator: FunctionComponent<PreviewProps> = ({
134
- bgTheme = "white",
140
+ bgTheme = "background-primary",
135
141
  bgThemeColors = {
136
- White: "bg-white",
137
- Gray: "bg-gray",
138
- Black: "bg-black",
139
- "Accent1 Blog": "bg-accent1-blog",
140
- "Accent2 Blog": "bg-accent2-blog",
142
+ "Background Primary": "background-primary",
143
+ "Background Secondary": "background-secondary",
144
+ "Background Contrast": "background-contrast",
145
+ "Background Accent": "background-accent",
146
+ "Background Accent1 Blog": "background-accent1-blog",
147
+ "Background Accent2 Blog": "background-accent2-blog",
141
148
  },
142
149
  bgThemeExcludedColors = [],
143
150
  children,
@@ -153,6 +160,7 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
153
160
  }) => {
154
161
  const [isCodeShown, setIsCodeShown] = useState(false);
155
162
  const [isFullscreen, setIsFullscreen] = useState(false);
163
+ const [isDarkMode, setIsDarkMode] = useState(false);
156
164
  // Ensure unique dropdown id per Preview instance to avoid id collisions (SSR-safe)
157
165
  const backgroundDropdownId = `background-select-${useId()}`;
158
166
  const [previewBackground, setPreviewBackground] = useState<PreviewBackground>(
@@ -185,10 +193,10 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
185
193
 
186
194
  return {
187
195
  label: bgTheme,
188
- value: bgThemeColors[bgTheme] || "bg-white",
196
+ value: bgThemeColors[bgTheme] || "background-primary",
189
197
  };
190
198
  }
191
- return { label: "white", value: "bg-white" };
199
+ return { label: "Background Primary", value: "background-primary" };
192
200
  },
193
201
  );
194
202
 
@@ -204,7 +212,11 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
204
212
  setIsFullscreen(!isFullscreen);
205
213
  }
206
214
 
207
- const themeClass = getThemeClassFromName(previewBackground.label);
215
+ function handleToggleDarkMode() {
216
+ setIsDarkMode(!isDarkMode);
217
+ }
218
+
219
+ const themeClass = isDarkMode ? "is-dark" : "is-light";
208
220
  const bgClass = getBgClassFromName(previewBackground.label);
209
221
 
210
222
  const classes = cx(CLASS_ROOT, themeClass, bgClass, className);
@@ -220,6 +232,23 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
220
232
  bgThemeExcludedColors,
221
233
  );
222
234
 
235
+ // Add theme toggle button
236
+ actions.push(
237
+ <Button key="theme-toggle" onClick={handleToggleDarkMode} type="ghost">
238
+ <Icon
239
+ name={isDarkMode ? "sleep" : "flashlight"}
240
+ size="medium"
241
+ fill={"currentColor"}
242
+ style={{ marginRight: "0.5rem" }}
243
+ />
244
+ {isDarkMode ? (
245
+ <code className="small bold">{".is-dark"}</code>
246
+ ) : (
247
+ <code className="small bold">{".is-light"}</code>
248
+ )}
249
+ </Button>,
250
+ );
251
+
223
252
  if (bgColorsOptions.length) {
224
253
  actions.push(
225
254
  <Dropdown
@@ -352,6 +381,4 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
352
381
  );
353
382
  };
354
383
 
355
- PreviewGenerator.displayName = "PreviewGenerator";
356
-
357
384
  export { PreviewGenerator };