@envive-ai/react-toolkit 0.3.66 → 0.3.68

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 (80) hide show
  1. package/dist/components/Accordion/Accordion.d.cts +2 -2
  2. package/dist/components/Accordion/Accordion.d.ts +2 -2
  3. package/dist/components/AnimatedChevron/AnimatedChevron.d.cts +2 -2
  4. package/dist/components/AnimatedChevron/AnimatedChevron.d.ts +2 -2
  5. package/dist/components/AppliedFiltersScrollbar/AppliedFiltersScrollbar.d.cts +2 -2
  6. package/dist/components/AppliedFiltersScrollbar/AppliedFiltersScrollbar.d.ts +2 -2
  7. package/dist/components/ButtonBase/ButtonBase.cjs +3 -1
  8. package/dist/components/ButtonBase/ButtonBase.d.cts +5 -3
  9. package/dist/components/ButtonBase/ButtonBase.d.ts +5 -3
  10. package/dist/components/ButtonBase/ButtonBase.js +3 -1
  11. package/dist/components/ButtonBase/types.d.cts +4 -0
  12. package/dist/components/ButtonBase/types.d.ts +4 -0
  13. package/dist/components/DynamicFiltersScrollbar/DynamicFiltersScrollbar.d.cts +2 -2
  14. package/dist/components/DynamicFiltersScrollbar/DynamicFiltersScrollbar.d.ts +2 -2
  15. package/dist/components/FilterScrollbar/AppliedFiltersScrollbar.d.cts +2 -2
  16. package/dist/components/FilterScrollbar/AppliedFiltersScrollbar.d.ts +2 -2
  17. package/dist/components/FilterScrollbar/DynamicFiltersScrollbar.d.cts +2 -2
  18. package/dist/components/FilterScrollbar/DynamicFiltersScrollbar.d.ts +2 -2
  19. package/dist/components/ImageWithFallback/ImageWithFallback.d.cts +2 -2
  20. package/dist/components/ImageWithFallback/ImageWithFallback.d.ts +2 -2
  21. package/dist/components/ModalSheet/ModalSheet.d.cts +2 -2
  22. package/dist/components/ModalSheet/ModalSheet.d.ts +2 -2
  23. package/dist/components/ProductCard/ProductCard.d.cts +4 -4
  24. package/dist/components/ProductCard/ProductCard.d.ts +4 -4
  25. package/dist/components/ProductGrid/ProductGrid.cjs +1 -1
  26. package/dist/components/ProductGrid/ProductGrid.d.cts +2 -2
  27. package/dist/components/ProductGrid/ProductGrid.d.ts +2 -2
  28. package/dist/components/ProductGrid/ProductGrid.js +1 -1
  29. package/dist/components/RadioButton/RadioButton.d.cts +2 -2
  30. package/dist/components/RadioButton/RadioButton.d.ts +2 -2
  31. package/dist/components/RadioButtonGroup/RadioButtonGroup.d.cts +2 -2
  32. package/dist/components/RadioButtonGroup/RadioButtonGroup.d.ts +2 -2
  33. package/dist/components/SearchAutocomplete/SearchAutocomplete.d.cts +2 -2
  34. package/dist/components/SearchFilter/SearchFilter.d.cts +2 -2
  35. package/dist/components/SearchFilter/SearchFilter.d.ts +2 -2
  36. package/dist/components/SearchFilter/SearchFilterFooter.d.cts +2 -2
  37. package/dist/components/SearchFilter/SearchFilterFooter.d.ts +2 -2
  38. package/dist/components/SearchFilter/SearchFilterHeader.d.cts +2 -2
  39. package/dist/components/SearchFilter/SearchFilterHeader.d.ts +2 -2
  40. package/dist/components/SearchFilter/SearchFilterItem.d.cts +2 -2
  41. package/dist/components/SearchFilter/SearchFilterItem.d.ts +2 -2
  42. package/dist/components/SearchInputForm/SearchInputForm.d.cts +2 -2
  43. package/dist/components/SearchResultsContent/SearchResultsContent.d.ts +2 -2
  44. package/dist/components/SearchResultsFilterButton/SearchResultsFilterButton.d.cts +2 -2
  45. package/dist/components/SearchResultsFilterButton/SearchResultsFilterButton.d.ts +2 -2
  46. package/dist/components/SearchResultsFilterModal/SearchResultsFilterModal.d.ts +2 -2
  47. package/dist/components/SearchResultsFilterSidebar/SearchResultsFilter.d.cts +2 -2
  48. package/dist/components/SearchResultsFilterSidebar/SearchResultsFilter.d.ts +2 -2
  49. package/dist/components/SearchResultsStates/NoSearchResultsFound.d.cts +2 -2
  50. package/dist/components/SearchResultsStates/NoSearchResultsFound.d.ts +2 -2
  51. package/dist/components/SearchResultsStates/SearchResultsGrid.d.cts +2 -2
  52. package/dist/components/SearchResultsStates/SearchResultsGrid.d.ts +2 -2
  53. package/dist/components/SearchResultsStates/SearchResultsLoadingGrid.cjs +1 -1
  54. package/dist/components/SearchResultsStates/SearchResultsLoadingGrid.d.cts +2 -2
  55. package/dist/components/SearchResultsStates/SearchResultsLoadingGrid.d.ts +2 -2
  56. package/dist/components/SearchResultsStates/SearchResultsLoadingGrid.js +1 -1
  57. package/dist/components/SearchResultsToolbar/SearchResultsToolbar.d.cts +2 -2
  58. package/dist/components/SearchResultsToolbar/SearchResultsToolbar.d.ts +2 -2
  59. package/dist/components/SparkleAnimation/SparkleAnimation.d.cts +2 -2
  60. package/dist/components/SparkleAnimation/SparkleAnimation.d.ts +2 -2
  61. package/dist/components/Spinner/Spinner.d.cts +2 -2
  62. package/dist/components/SuggestionButton/SuggestionButton.cjs +8 -138
  63. package/dist/components/SuggestionButton/SuggestionButton.d.cts +7 -3
  64. package/dist/components/SuggestionButton/SuggestionButton.d.ts +7 -3
  65. package/dist/components/SuggestionButton/SuggestionButton.js +6 -136
  66. package/dist/components/SuggestionButton/index.cjs +3 -1
  67. package/dist/components/SuggestionButton/index.d.cts +2 -1
  68. package/dist/components/SuggestionButton/index.d.ts +2 -1
  69. package/dist/components/SuggestionButton/index.js +2 -1
  70. package/dist/components/SuggestionButton/variantClasses.cjs +148 -0
  71. package/dist/components/SuggestionButton/variantClasses.d.cts +12 -0
  72. package/dist/components/SuggestionButton/variantClasses.d.ts +12 -0
  73. package/dist/components/SuggestionButton/variantClasses.js +146 -0
  74. package/dist/components/ToggleButton/ToggleButton.d.cts +2 -2
  75. package/package.json +1 -1
  76. package/src/components/ButtonBase/ButtonBase.tsx +4 -0
  77. package/src/components/ButtonBase/types.ts +4 -0
  78. package/src/components/SuggestionButton/SuggestionButton.tsx +9 -190
  79. package/src/components/SuggestionButton/index.ts +1 -0
  80. package/src/components/SuggestionButton/variantClasses.ts +204 -0
@@ -2,166 +2,13 @@ import classNames from 'classnames';
2
2
  import OutlinedStar from '@envive-ai/react-icons/OutlinedStar';
3
3
  import FourPointStar from '@envive-ai/react-icons/FourPointStar';
4
4
  import type { SuggestionButtonVariant } from './types';
5
+ import { borderedVariants, getSuggestionButtonVariantClasses } from './variantClasses';
5
6
  import { ButtonBase } from '../ButtonBase/ButtonBase';
6
7
 
7
8
  export const SPIFFY_SUGGESTION_BUTTON_QUESTION_CLASS = 'spiffy-suggestion-button-question-class';
8
9
  export const SPIFFY_SUGGESTION_BUTTON_ANSWER_CLASS = 'spiffy-suggestion-button-answer-class';
9
10
  export const SPIFFY_SUGGESTION_BUTTON_TEXT_CLASS = 'spiffy-suggestion-button-text-class';
10
11
 
11
- // Add a comment that includes the hover prefix so that tailwind will pickup and generate the right css
12
- // Common class patterns to avoid duplication
13
- const BORDER_CLASS = 'spiffy-tw-border'; // hover:spiffy-tw-border
14
- const TEXT_LINK_CLASSES = [
15
- 'spiffy-tw-text-[--spiffy-colors-text-link]', // hover:spiffy-tw-text-[--spiffy-colors-text-link]
16
- 'spiffy-tw-fill-[--spiffy-colors-text-link]', // hover:spiffy-tw-fill-[--spiffy-colors-text-link]
17
- 'spiffy-tw-stroke-[--spiffy-colors-text-link]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-link]
18
- ];
19
- const TEXT_LIGHT_CLASSES = [
20
- 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
21
- 'spiffy-tw-fill-[--spiffy-colors-text-light]', // hover:spiffy-tw-fill-[--spiffy-colors-text-light]
22
- 'spiffy-tw-stroke-[--spiffy-colors-text-light]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-light]
23
- ];
24
- const TEXT_PRIMARY_CLASSES = [
25
- 'spiffy-tw-text-[--spiffy-colors-text-primary]', // hover:spiffy-tw-text-[--spiffy-colors-text-primary]
26
- 'spiffy-tw-fill-[--spiffy-colors-text-primary]', // hover:spiffy-tw-fill-[--spiffy-colors-text-primary]
27
- 'spiffy-tw-stroke-[--spiffy-colors-text-primary]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-primary]
28
- ];
29
- const ACCENT_PRIMARY_CLASSES = [
30
- 'spiffy-tw-fill-[--spiffy-colors-accent-primary]', // hover:spiffy-tw-fill-[--spiffy-colors-accent-primary]
31
- 'spiffy-tw-stroke-[--spiffy-colors-accent-primary]', // hover:spiffy-tw-stroke-[--spiffy-colors-accent-primary]
32
- ];
33
- const DARK_BACKGROUND_CLASSES = [
34
- 'spiffy-tw-bg-[--spiffy-colors-background-dark]', // hover:spiffy-tw-bg-[--spiffy-colors-background-dark]
35
- 'spiffy-tw-border-[--spiffy-colors-background-dark]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary]
36
- ];
37
- const SECONDARY_DARK_BACKGROUND_CLASSES = [
38
- 'spiffy-tw-bg-[--spiffy-colors-background-secondary-dark]', // hover:spiffy-tw-bg-[--spiffy-colors-background-secondary-dark]
39
- 'spiffy-tw-border-[--spiffy-colors-background-secondary-dark]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary-dark]
40
- ];
41
-
42
- const variantClassMap = new Map<SuggestionButtonVariant, string[]>([
43
- [
44
- 'outlined',
45
- [
46
- 'spiffy-tw-border-[--spiffy-colors-border-outline]', // hover:spiffy-tw-border-[--spiffy-colors-border-outline]
47
- ...TEXT_LINK_CLASSES,
48
- ],
49
- ],
50
- [
51
- 'outlinedLight',
52
- [
53
- 'spiffy-tw-border-[--spiffy-colors-border-outline]', // hover:spiffy-tw-border-[--spiffy-colors-border-outline]
54
- 'spiffy-tw-bg-[--spiffy-colors-background-light]', // hover:spiffy-tw-bg-[--spiffy-colors-background-light]
55
- ...TEXT_LINK_CLASSES,
56
- BORDER_CLASS,
57
- ],
58
- ],
59
- [
60
- 'primary',
61
- [
62
- 'spiffy-tw-bg-[--spiffy-colors-background-primary]', // hover:spiffy-tw-bg-[--spiffy-colors-background-primary]
63
- 'spiffy-tw-border-[--spiffy-colors-background-primary]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary]
64
- ...TEXT_LIGHT_CLASSES,
65
- BORDER_CLASS,
66
- ],
67
- ],
68
- [
69
- 'secondary',
70
- [
71
- 'spiffy-tw-bg-[--spiffy-colors-background-secondary]', // hover:spiffy-tw-bg-[--spiffy-colors-background-secondary]
72
- 'spiffy-tw-text-[--spiffy-colors-text-link]', // hover:spiffy-tw-text-[--spiffy-colors-text-link]
73
- 'spiffy-tw-border-[--spiffy-colors-background-secondary]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary]
74
- ...ACCENT_PRIMARY_CLASSES,
75
- BORDER_CLASS,
76
- ],
77
- ],
78
- [
79
- 'tertiary',
80
- [
81
- 'spiffy-tw-bg-[--spiffy-colors-background-tertiary]', // hover:spiffy-tw-bg-[--spiffy-colors-background-tertiary]
82
- 'spiffy-tw-border-[--spiffy-colors-background-tertiary]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary]
83
- ...TEXT_LINK_CLASSES,
84
- BORDER_CLASS,
85
- ],
86
- ],
87
- ['dark', [...DARK_BACKGROUND_CLASSES, ...TEXT_LIGHT_CLASSES, BORDER_CLASS]],
88
- [
89
- 'darkPrimary',
90
- [
91
- ...DARK_BACKGROUND_CLASSES,
92
- 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
93
- ...ACCENT_PRIMARY_CLASSES,
94
- BORDER_CLASS,
95
- ],
96
- ],
97
- [
98
- 'darkAccent',
99
- [
100
- ...DARK_BACKGROUND_CLASSES,
101
- 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
102
- 'spiffy-tw-fill-[--spiffy-colors-text-accent]', // hover:spiffy-tw-fill-[--spiffy-colors-text-accent]
103
- 'spiffy-tw-stroke-[--spiffy-colors-text-accent]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-accent]
104
- BORDER_CLASS,
105
- ],
106
- ],
107
- // dark accent appears to have been originally been made with the bg color text-accent
108
- // instead of the design, acccent-primary. This is a correction to match the design without
109
- // regressing intentional uses of the other styling. text-accent and accent-primary are often
110
- // the same or very similar colors but in some cases, they are very different to deal with contrast correctly.
111
- [
112
- 'darkAccentContrast',
113
- [
114
- ...DARK_BACKGROUND_CLASSES,
115
- 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
116
- 'spiffy-tw-fill-[--spiffy-colors-accent-primary]', // hover:spiffy-tw-fill-[--spiffy-colors-accent-primary]
117
- 'spiffy-tw-stroke-[--spiffy-colors-accent-primary]', // hover:spiffy-tw-stroke-[--spiffy-colors-accent-primary]
118
- BORDER_CLASS,
119
- ],
120
- ],
121
- [
122
- 'transparent',
123
- [
124
- 'spiffy-tw-bg-transparent', // hover:spiffy-tw-bg-transparent
125
- 'spiffy-tw-border-[--spiffy-colors-background-light]', // hover:spiffy-tw-border-[--spiffy-colors-background-light]
126
- 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
127
- 'spiffy-tw-fill-transparent', // hover:spiffy-tw-fill-transparent
128
- 'spiffy-tw-stroke-[--spiffy-colors-text-light]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-light]
129
- BORDER_CLASS,
130
- ],
131
- ],
132
- [
133
- 'transparentDark',
134
- [
135
- 'spiffy-tw-bg-transparent', // hover:spiffy-tw-bg-transparent
136
- 'spiffy-tw-border-[--spiffy-colors-border-light]', // hover:spiffy-tw-border-[--spiffy-colors-border-light]
137
- 'spiffy-tw-text-[--spiffy-colors-text-primary]', // hover:spiffy-tw-text-[--spiffy-colors-text-primary]
138
- 'spiffy-tw-fill-transparent', // hover:spiffy-tw-fill-transparent
139
- 'spiffy-tw-stroke-[--spiffy-colors-text-primary]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-primary]
140
- BORDER_CLASS,
141
- ],
142
- ],
143
- // This is used as the hover state for transparent
144
- ['secondaryDark', [...SECONDARY_DARK_BACKGROUND_CLASSES, ...TEXT_LINK_CLASSES, BORDER_CLASS]],
145
- [
146
- 'secondaryAccent',
147
- [
148
- ...SECONDARY_DARK_BACKGROUND_CLASSES,
149
- 'spiffy-tw-text-[--spiffy-colors-text-link]', // hover:spiffy-tw-text-[--spiffy-colors-text-link]
150
- ...ACCENT_PRIMARY_CLASSES,
151
- BORDER_CLASS,
152
- ],
153
- ],
154
- [
155
- 'lightDark',
156
- [
157
- 'spiffy-tw-bg-[--spiffy-colors-background-light]', // hover:spiffy-tw-bg-[--spiffy-colors-background-light]
158
- 'spiffy-tw-border-[--spiffy-colors-background-dark]', // hover:spiffy-tw-border-[--spiffy-colors-background-dark]
159
- ...TEXT_PRIMARY_CLASSES,
160
- BORDER_CLASS,
161
- ],
162
- ],
163
- ]);
164
-
165
12
  // Choose icon based on variant to match legacy exactly
166
13
  const Icon = ({ isAnswer, variant }: { isAnswer: boolean; variant: SuggestionButtonVariant }) => {
167
14
  if (isAnswer) return undefined;
@@ -182,28 +29,10 @@ interface SuggestionButtonProps {
182
29
  dataAttributes?: Record<string, string>;
183
30
  onClick: () => void;
184
31
  dataTestId?: string;
32
+ ariaHidden?: boolean;
33
+ tabIndex?: number;
185
34
  }
186
35
 
187
- const borderedVariants = [
188
- 'outlined',
189
- 'outlinedLight',
190
- 'primary',
191
- 'secondary',
192
- 'tertiary',
193
- 'dark',
194
- 'darkAccent',
195
- 'darkAccentContrast',
196
- 'darkPrimary',
197
- 'transparent',
198
- 'transparentDark',
199
- 'secondaryDark',
200
- 'secondaryAccent',
201
- 'lightDark',
202
- ];
203
-
204
- const hoverTransform = (variantClass: string[]): string[] =>
205
- variantClass?.map(className => `hover:${className}`);
206
-
207
36
  export const SuggestionButton = ({
208
37
  variant,
209
38
  hoverVariant,
@@ -215,6 +44,8 @@ export const SuggestionButton = ({
215
44
  dataAttributes,
216
45
  dataTestId,
217
46
  onClick,
47
+ ariaHidden,
48
+ tabIndex,
218
49
  }: SuggestionButtonProps) => {
219
50
  const buttonClassName = classNames({
220
51
  [SPIFFY_SUGGESTION_BUTTON_QUESTION_CLASS]: !isAnswer,
@@ -238,23 +69,9 @@ export const SuggestionButton = ({
238
69
  'spiffy-tw-fill-inherit': true,
239
70
  });
240
71
 
241
- const baseClasses = variantClassMap.get(variant) ?? [];
242
- const hoverClasses = variantClassMap.get(hoverVariant) ?? [];
243
-
244
- // Separate border classes for proper cascading
245
- const baseBorderClasses = baseClasses.filter(cls => cls.includes('border'));
246
- const baseNonBorderClasses = baseClasses.filter(cls => !cls.includes('border'));
247
- const hoverBorderClasses = hoverClasses.filter(cls => cls.includes('border'));
248
- const hoverNonBorderClasses = hoverClasses.filter(cls => !cls.includes('border'));
249
-
250
- const variantClasses = [
251
- ...baseNonBorderClasses,
252
- ...hoverTransform(hoverNonBorderClasses),
253
- ...baseBorderClasses,
254
- ...hoverTransform(hoverBorderClasses),
255
- ];
72
+ const variantClasses = getSuggestionButtonVariantClasses(variant, hoverVariant);
256
73
 
257
- const buttonClass = `${buttonClassName} ${variantClasses.join(' ')}`;
74
+ const buttonClass = `${buttonClassName} ${variantClasses}`;
258
75
 
259
76
  return (
260
77
  <ButtonBase
@@ -273,6 +90,8 @@ export const SuggestionButton = ({
273
90
  textClass={`${SPIFFY_SUGGESTION_BUTTON_TEXT_CLASS} ${textClassName}`}
274
91
  buttonClass={buttonClass}
275
92
  onClick={onClick}
93
+ ariaHidden={ariaHidden}
94
+ tabIndex={tabIndex}
276
95
  />
277
96
  );
278
97
  };
@@ -1,2 +1,3 @@
1
1
  export * from './SuggestionButton';
2
2
  export * from './types';
3
+ export { getSuggestionButtonVariantClasses } from './variantClasses';
@@ -0,0 +1,204 @@
1
+ import type { SuggestionButtonVariant } from './types';
2
+
3
+ // Add a comment that includes the hover prefix so that tailwind will pickup and generate the right css
4
+ // Common class patterns to avoid duplication
5
+ const BORDER_CLASS = 'spiffy-tw-border'; // hover:spiffy-tw-border
6
+ const TEXT_LINK_CLASSES = [
7
+ 'spiffy-tw-text-[--spiffy-colors-text-link]', // hover:spiffy-tw-text-[--spiffy-colors-text-link]
8
+ 'spiffy-tw-fill-[--spiffy-colors-text-link]', // hover:spiffy-tw-fill-[--spiffy-colors-text-link]
9
+ 'spiffy-tw-stroke-[--spiffy-colors-text-link]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-link]
10
+ ];
11
+ const TEXT_LIGHT_CLASSES = [
12
+ 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
13
+ 'spiffy-tw-fill-[--spiffy-colors-text-light]', // hover:spiffy-tw-fill-[--spiffy-colors-text-light]
14
+ 'spiffy-tw-stroke-[--spiffy-colors-text-light]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-light]
15
+ ];
16
+ const TEXT_PRIMARY_CLASSES = [
17
+ 'spiffy-tw-text-[--spiffy-colors-text-primary]', // hover:spiffy-tw-text-[--spiffy-colors-text-primary]
18
+ 'spiffy-tw-fill-[--spiffy-colors-text-primary]', // hover:spiffy-tw-fill-[--spiffy-colors-text-primary]
19
+ 'spiffy-tw-stroke-[--spiffy-colors-text-primary]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-primary]
20
+ ];
21
+ const ACCENT_PRIMARY_CLASSES = [
22
+ 'spiffy-tw-fill-[--spiffy-colors-accent-primary]', // hover:spiffy-tw-fill-[--spiffy-colors-accent-primary]
23
+ 'spiffy-tw-stroke-[--spiffy-colors-accent-primary]', // hover:spiffy-tw-stroke-[--spiffy-colors-accent-primary]
24
+ ];
25
+ const DARK_BACKGROUND_CLASSES = [
26
+ 'spiffy-tw-bg-[--spiffy-colors-background-dark]', // hover:spiffy-tw-bg-[--spiffy-colors-background-dark]
27
+ 'spiffy-tw-border-[--spiffy-colors-background-dark]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary]
28
+ ];
29
+ const SECONDARY_DARK_BACKGROUND_CLASSES = [
30
+ 'spiffy-tw-bg-[--spiffy-colors-background-secondary-dark]', // hover:spiffy-tw-bg-[--spiffy-colors-background-secondary-dark]
31
+ 'spiffy-tw-border-[--spiffy-colors-background-secondary-dark]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary-dark]
32
+ ];
33
+
34
+ const variantClassMap = new Map<SuggestionButtonVariant, string[]>([
35
+ [
36
+ 'outlined',
37
+ [
38
+ 'spiffy-tw-border-[--spiffy-colors-border-outline]', // hover:spiffy-tw-border-[--spiffy-colors-border-outline]
39
+ ...TEXT_LINK_CLASSES,
40
+ ],
41
+ ],
42
+ [
43
+ 'outlinedLight',
44
+ [
45
+ 'spiffy-tw-border-[--spiffy-colors-border-outline]', // hover:spiffy-tw-border-[--spiffy-colors-border-outline]
46
+ 'spiffy-tw-bg-[--spiffy-colors-background-light]', // hover:spiffy-tw-bg-[--spiffy-colors-background-light]
47
+ ...TEXT_LINK_CLASSES,
48
+ BORDER_CLASS,
49
+ ],
50
+ ],
51
+ [
52
+ 'primary',
53
+ [
54
+ 'spiffy-tw-bg-[--spiffy-colors-background-primary]', // hover:spiffy-tw-bg-[--spiffy-colors-background-primary]
55
+ 'spiffy-tw-border-[--spiffy-colors-background-primary]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary]
56
+ ...TEXT_LIGHT_CLASSES,
57
+ BORDER_CLASS,
58
+ ],
59
+ ],
60
+ [
61
+ 'secondary',
62
+ [
63
+ 'spiffy-tw-bg-[--spiffy-colors-background-secondary]', // hover:spiffy-tw-bg-[--spiffy-colors-background-secondary]
64
+ 'spiffy-tw-text-[--spiffy-colors-text-link]', // hover:spiffy-tw-text-[--spiffy-colors-text-link]
65
+ 'spiffy-tw-border-[--spiffy-colors-background-secondary]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary]
66
+ ...ACCENT_PRIMARY_CLASSES,
67
+ BORDER_CLASS,
68
+ ],
69
+ ],
70
+ [
71
+ 'tertiary',
72
+ [
73
+ 'spiffy-tw-bg-[--spiffy-colors-background-tertiary]', // hover:spiffy-tw-bg-[--spiffy-colors-background-tertiary]
74
+ 'spiffy-tw-border-[--spiffy-colors-background-tertiary]', // hover:spiffy-tw-border-[--spiffy-colors-background-secondary]
75
+ ...TEXT_LINK_CLASSES,
76
+ BORDER_CLASS,
77
+ ],
78
+ ],
79
+ ['dark', [...DARK_BACKGROUND_CLASSES, ...TEXT_LIGHT_CLASSES, BORDER_CLASS]],
80
+ [
81
+ 'darkPrimary',
82
+ [
83
+ ...DARK_BACKGROUND_CLASSES,
84
+ 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
85
+ ...ACCENT_PRIMARY_CLASSES,
86
+ BORDER_CLASS,
87
+ ],
88
+ ],
89
+ [
90
+ 'darkAccent',
91
+ [
92
+ ...DARK_BACKGROUND_CLASSES,
93
+ 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
94
+ 'spiffy-tw-fill-[--spiffy-colors-text-accent]', // hover:spiffy-tw-fill-[--spiffy-colors-text-accent]
95
+ 'spiffy-tw-stroke-[--spiffy-colors-text-accent]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-accent]
96
+ BORDER_CLASS,
97
+ ],
98
+ ],
99
+ // dark accent appears to have been originally been made with the bg color text-accent
100
+ // instead of the design, acccent-primary. This is a correction to match the design without
101
+ // regressing intentional uses of the other styling. text-accent and accent-primary are often
102
+ // the same or very similar colors but in some cases, they are very different to deal with contrast correctly.
103
+ [
104
+ 'darkAccentContrast',
105
+ [
106
+ ...DARK_BACKGROUND_CLASSES,
107
+ 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
108
+ 'spiffy-tw-fill-[--spiffy-colors-accent-primary]', // hover:spiffy-tw-fill-[--spiffy-colors-accent-primary]
109
+ 'spiffy-tw-stroke-[--spiffy-colors-accent-primary]', // hover:spiffy-tw-stroke-[--spiffy-colors-accent-primary]
110
+ BORDER_CLASS,
111
+ ],
112
+ ],
113
+ [
114
+ 'transparent',
115
+ [
116
+ 'spiffy-tw-bg-transparent', // hover:spiffy-tw-bg-transparent
117
+ 'spiffy-tw-border-[--spiffy-colors-background-light]', // hover:spiffy-tw-border-[--spiffy-colors-background-light]
118
+ 'spiffy-tw-text-[--spiffy-colors-text-light]', // hover:spiffy-tw-text-[--spiffy-colors-text-light]
119
+ 'spiffy-tw-fill-transparent', // hover:spiffy-tw-fill-transparent
120
+ 'spiffy-tw-stroke-[--spiffy-colors-text-light]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-light]
121
+ BORDER_CLASS,
122
+ ],
123
+ ],
124
+ [
125
+ 'transparentDark',
126
+ [
127
+ 'spiffy-tw-bg-transparent', // hover:spiffy-tw-bg-transparent
128
+ 'spiffy-tw-border-[--spiffy-colors-border-light]', // hover:spiffy-tw-border-[--spiffy-colors-border-light]
129
+ 'spiffy-tw-text-[--spiffy-colors-text-primary]', // hover:spiffy-tw-text-[--spiffy-colors-text-primary]
130
+ 'spiffy-tw-fill-transparent', // hover:spiffy-tw-fill-transparent
131
+ 'spiffy-tw-stroke-[--spiffy-colors-text-primary]', // hover:spiffy-tw-stroke-[--spiffy-colors-text-primary]
132
+ BORDER_CLASS,
133
+ ],
134
+ ],
135
+ // This is used as the hover state for transparent
136
+ ['secondaryDark', [...SECONDARY_DARK_BACKGROUND_CLASSES, ...TEXT_LINK_CLASSES, BORDER_CLASS]],
137
+ [
138
+ 'secondaryAccent',
139
+ [
140
+ ...SECONDARY_DARK_BACKGROUND_CLASSES,
141
+ 'spiffy-tw-text-[--spiffy-colors-text-link]', // hover:spiffy-tw-text-[--spiffy-colors-text-link]
142
+ ...ACCENT_PRIMARY_CLASSES,
143
+ BORDER_CLASS,
144
+ ],
145
+ ],
146
+ [
147
+ 'lightDark',
148
+ [
149
+ 'spiffy-tw-bg-[--spiffy-colors-background-light]', // hover:spiffy-tw-bg-[--spiffy-colors-background-light]
150
+ 'spiffy-tw-border-[--spiffy-colors-background-dark]', // hover:spiffy-tw-border-[--spiffy-colors-background-dark]
151
+ ...TEXT_PRIMARY_CLASSES,
152
+ BORDER_CLASS,
153
+ ],
154
+ ],
155
+ ]);
156
+
157
+ export const borderedVariants = [
158
+ 'outlined',
159
+ 'outlinedLight',
160
+ 'primary',
161
+ 'secondary',
162
+ 'tertiary',
163
+ 'dark',
164
+ 'darkAccent',
165
+ 'darkAccentContrast',
166
+ 'darkPrimary',
167
+ 'transparent',
168
+ 'transparentDark',
169
+ 'secondaryDark',
170
+ 'secondaryAccent',
171
+ 'lightDark',
172
+ ];
173
+
174
+ const hoverTransform = (variantClass: string[]): string[] =>
175
+ variantClass?.map(className => `hover:${className}`);
176
+
177
+ /**
178
+ * Background/border/text/icon classes for a suggestion button variant plus its hover
179
+ * variant. Exported so companion controls (e.g. the suggestion bar pause toggle) can
180
+ * match the merchant's button styling.
181
+ */
182
+ export const getSuggestionButtonVariantClasses = (
183
+ variant: SuggestionButtonVariant,
184
+ hoverVariant: SuggestionButtonVariant,
185
+ ): string => {
186
+ const baseClasses = variantClassMap.get(variant) ?? [];
187
+ const hoverClasses = variantClassMap.get(hoverVariant) ?? [];
188
+
189
+ // Separate border classes for proper cascading
190
+ const baseBorderClasses = baseClasses.filter(cls => cls.includes('border'));
191
+ const baseNonBorderClasses = baseClasses.filter(cls => !cls.includes('border'));
192
+ const hoverBorderClasses = hoverClasses.filter(cls => cls.includes('border'));
193
+ const hoverNonBorderClasses = hoverClasses.filter(cls => !cls.includes('border'));
194
+
195
+ return [
196
+ ...baseNonBorderClasses,
197
+ ...hoverTransform(hoverNonBorderClasses),
198
+ ...baseBorderClasses,
199
+ ...hoverTransform(hoverBorderClasses),
200
+ borderedVariants.includes(variant) && 'spiffy-tw-border-[1px] spiffy-tw-border-solid',
201
+ ]
202
+ .filter(Boolean)
203
+ .join(' ');
204
+ };