@hubspot/cms-component-library 0.1.0 → 0.2.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 (143) hide show
  1. package/components/componentLibrary/Accordion/AccordionContent/ContentFields.tsx +5 -3
  2. package/components/componentLibrary/Accordion/AccordionItem/StyleFields.tsx +5 -3
  3. package/components/componentLibrary/Accordion/AccordionItem/index.module.scss +2 -2
  4. package/components/componentLibrary/Accordion/AccordionItem/index.tsx +3 -3
  5. package/components/componentLibrary/Accordion/AccordionTitle/ContentFields.tsx +5 -3
  6. package/components/componentLibrary/Accordion/AccordionTitle/index.module.scss +2 -2
  7. package/components/componentLibrary/Accordion/stories/Accordion.stories.tsx +80 -1
  8. package/components/componentLibrary/Accordion/stories/AccordionDecorator.tsx +14 -14
  9. package/components/componentLibrary/Button/ContentFields.tsx +5 -3
  10. package/components/componentLibrary/Button/StyleFields.tsx +5 -3
  11. package/components/componentLibrary/Button/index.module.scss +22 -14
  12. package/components/componentLibrary/Button/index.tsx +6 -6
  13. package/components/componentLibrary/Button/stories/Button.AsButton.stories.tsx +30 -1
  14. package/components/componentLibrary/Button/stories/Button.AsLink.stories.tsx +38 -1
  15. package/components/componentLibrary/Button/stories/ButtonDecorator.tsx +1 -1
  16. package/components/componentLibrary/Card/StyleFields.tsx +5 -3
  17. package/components/componentLibrary/Card/stories/Card.stories.tsx +46 -1
  18. package/components/componentLibrary/Card/stories/CardDecorator.tsx +1 -1
  19. package/components/componentLibrary/Divider/ContentFields.tsx +5 -3
  20. package/components/componentLibrary/Divider/StyleFields.tsx +5 -3
  21. package/components/componentLibrary/Divider/index.module.scss +6 -6
  22. package/components/componentLibrary/Divider/index.tsx +7 -3
  23. package/components/componentLibrary/Divider/stories/Divider.stories.tsx +44 -50
  24. package/components/componentLibrary/Divider/stories/{DividerDecorator.module.css → DividerDecorator.module.scss} +5 -4
  25. package/components/componentLibrary/Divider/stories/DividerDecorator.tsx +1 -1
  26. package/components/componentLibrary/Divider/types.ts +3 -1
  27. package/components/componentLibrary/Drawer/hooks/index.tsx +13 -0
  28. package/components/componentLibrary/Drawer/index.module.scss +94 -0
  29. package/components/componentLibrary/Drawer/index.tsx +131 -0
  30. package/components/componentLibrary/Drawer/llm.txt +416 -0
  31. package/components/componentLibrary/Drawer/stories/Drawer.stories.tsx +512 -0
  32. package/components/componentLibrary/Drawer/stories/DrawerDecorator.module.scss +8 -0
  33. package/components/componentLibrary/Drawer/stories/DrawerDecorator.tsx +18 -0
  34. package/components/componentLibrary/Drawer/types.ts +25 -0
  35. package/components/componentLibrary/Flex/stories/FlexDecorator.tsx +1 -1
  36. package/components/componentLibrary/Flex/types.ts +3 -1
  37. package/components/componentLibrary/Grid/stories/Grid.stories.tsx +454 -152
  38. package/components/componentLibrary/Grid/stories/GridDecorator.tsx +2 -2
  39. package/components/componentLibrary/Heading/ContentFields.tsx +5 -3
  40. package/components/componentLibrary/Heading/StyleFields.tsx +11 -9
  41. package/components/componentLibrary/Heading/index.tsx +3 -3
  42. package/components/componentLibrary/Heading/llm.txt +8 -8
  43. package/components/componentLibrary/Heading/stories/Heading.stories.tsx +3 -3
  44. package/components/componentLibrary/Heading/stories/HeadingDecorator.tsx +1 -1
  45. package/components/componentLibrary/Heading/types.ts +4 -4
  46. package/components/componentLibrary/Icon/ContentFields.tsx +5 -3
  47. package/components/componentLibrary/Icon/stories/Icon.stories.tsx +1 -1
  48. package/components/componentLibrary/Icon/stories/IconDecorator.tsx +1 -1
  49. package/components/componentLibrary/Image/ContentFields.tsx +5 -3
  50. package/components/componentLibrary/Image/index.tsx +4 -4
  51. package/components/componentLibrary/Image/llm.txt +17 -17
  52. package/components/componentLibrary/Image/stories/Image.stories.tsx +61 -18
  53. package/components/componentLibrary/Image/stories/ImageDecorator.tsx +1 -1
  54. package/components/componentLibrary/Image/types.ts +2 -2
  55. package/components/componentLibrary/LanguageSwitcher/ContentFields.tsx +18 -0
  56. package/components/componentLibrary/LanguageSwitcher/LanguageOptions.module.scss +37 -0
  57. package/components/componentLibrary/LanguageSwitcher/LanguageOptions.tsx +65 -0
  58. package/components/componentLibrary/LanguageSwitcher/StyleFields.tsx +48 -0
  59. package/components/componentLibrary/LanguageSwitcher/_dummyData.tsx +247 -0
  60. package/components/componentLibrary/LanguageSwitcher/assets/Globe.tsx +16 -0
  61. package/components/componentLibrary/LanguageSwitcher/index.module.scss +58 -0
  62. package/components/componentLibrary/LanguageSwitcher/index.tsx +125 -0
  63. package/components/componentLibrary/LanguageSwitcher/llm.txt +380 -0
  64. package/components/componentLibrary/LanguageSwitcher/stories/LanguageSwitcher.stories.tsx +349 -0
  65. package/components/componentLibrary/LanguageSwitcher/stories/LanguageSwitcherDecorator.module.scss +5 -0
  66. package/components/componentLibrary/LanguageSwitcher/stories/LanguageSwitcherDecorator.tsx +8 -0
  67. package/components/componentLibrary/LanguageSwitcher/types.ts +48 -0
  68. package/components/componentLibrary/LanguageSwitcher/utils.tsx +38 -0
  69. package/components/componentLibrary/Link/ContentFields.tsx +5 -3
  70. package/components/componentLibrary/Link/StyleFields.tsx +5 -3
  71. package/components/componentLibrary/Link/index.module.scss +10 -0
  72. package/components/componentLibrary/Link/index.tsx +24 -14
  73. package/components/componentLibrary/Link/stories/Link.stories.tsx +35 -5
  74. package/components/componentLibrary/Link/stories/LinkDecorator.tsx +11 -1
  75. package/components/componentLibrary/Link/types.ts +22 -13
  76. package/components/componentLibrary/List/ContentFields.tsx +5 -3
  77. package/components/componentLibrary/List/ListItem/ContentFields.tsx +6 -17
  78. package/components/componentLibrary/List/ListItem/index.module.scss +1 -13
  79. package/components/componentLibrary/List/ListItem/index.tsx +3 -30
  80. package/components/componentLibrary/List/ListItem/types.ts +1 -16
  81. package/components/componentLibrary/List/StyleFields.tsx +15 -18
  82. package/components/componentLibrary/List/index.module.scss +3 -0
  83. package/components/componentLibrary/List/index.tsx +5 -2
  84. package/components/componentLibrary/List/llm.txt +73 -103
  85. package/components/componentLibrary/List/stories/List.stories.tsx +56 -80
  86. package/components/componentLibrary/List/stories/ListDecorator.tsx +3 -6
  87. package/components/componentLibrary/List/types.ts +1 -3
  88. package/components/componentLibrary/Logo/_dummyLogoData.ts +12 -0
  89. package/components/componentLibrary/Logo/assets/hubspot-logo.png +0 -0
  90. package/components/componentLibrary/Logo/index.module.scss +22 -0
  91. package/components/componentLibrary/Logo/index.tsx +73 -0
  92. package/components/componentLibrary/Logo/llm.txt +262 -0
  93. package/components/componentLibrary/Logo/stories/Logo.stories.tsx +88 -0
  94. package/components/componentLibrary/Logo/stories/LogoDecorator.module.scss +10 -0
  95. package/components/componentLibrary/Logo/stories/LogoDecorator.tsx +8 -0
  96. package/components/componentLibrary/Logo/types.tsx +16 -0
  97. package/components/componentLibrary/Menu/ContentFields.tsx +16 -0
  98. package/components/componentLibrary/Menu/MenuItem/Chevron/index.module.scss +6 -0
  99. package/components/componentLibrary/Menu/MenuItem/Chevron/index.tsx +17 -0
  100. package/components/componentLibrary/Menu/MenuItem/index.module.scss +7 -0
  101. package/components/componentLibrary/Menu/MenuItem/index.tsx +266 -0
  102. package/components/componentLibrary/Menu/MenuItem/types.ts +17 -0
  103. package/components/componentLibrary/Menu/NavigationMenu/ContentFields.tsx +20 -0
  104. package/components/componentLibrary/Menu/NavigationMenu/index.tsx +18 -0
  105. package/components/componentLibrary/Menu/NavigationMenu/islands/NavigationMenuIsland.tsx +95 -0
  106. package/components/componentLibrary/Menu/NavigationMenu/islands/index.module.scss +100 -0
  107. package/components/componentLibrary/Menu/NavigationMenu/islands/types.ts +19 -0
  108. package/components/componentLibrary/Menu/NavigationMenu/llm.txt +197 -0
  109. package/components/componentLibrary/Menu/NavigationMenu/stories/NavigationMenu.stories.tsx +286 -0
  110. package/components/componentLibrary/Menu/NavigationMenu/stories/NavigationMenuDecorator.module.scss +15 -0
  111. package/components/componentLibrary/Menu/NavigationMenu/stories/NavigationMenuDecorator.tsx +12 -0
  112. package/components/componentLibrary/Menu/NavigationMenu/types.ts +3 -0
  113. package/components/componentLibrary/Menu/VerticalMenu/ContentFields.tsx +20 -0
  114. package/components/componentLibrary/Menu/VerticalMenu/index.tsx +18 -0
  115. package/components/componentLibrary/Menu/VerticalMenu/islands/index.module.scss +53 -0
  116. package/components/componentLibrary/Menu/VerticalMenu/islands/verticalMenuIsland.tsx +78 -0
  117. package/components/componentLibrary/Menu/VerticalMenu/llm.txt +177 -0
  118. package/components/componentLibrary/Menu/VerticalMenu/stories/VerticalMenu.stories.tsx +242 -0
  119. package/components/componentLibrary/Menu/VerticalMenu/stories/VerticalMenuDecorator.module.scss +19 -0
  120. package/components/componentLibrary/Menu/VerticalMenu/stories/VerticalMenuDecorator.tsx +12 -0
  121. package/components/componentLibrary/Menu/VerticalMenu/types.ts +21 -0
  122. package/components/componentLibrary/Menu/_dummyMenuData.js +1346 -0
  123. package/components/componentLibrary/Menu/types.ts +56 -0
  124. package/components/componentLibrary/Menu/utils/transformMenuData.ts +11 -0
  125. package/components/componentLibrary/_patterns/README.md +15 -17
  126. package/components/componentLibrary/_patterns/checklist-and-examples.md +17 -17
  127. package/components/componentLibrary/_patterns/component-structure.md +21 -23
  128. package/components/componentLibrary/_patterns/css-patterns.md +170 -18
  129. package/components/componentLibrary/_patterns/field-patterns.md +97 -27
  130. package/components/componentLibrary/_patterns/function-declaration-patterns.md +281 -0
  131. package/components/componentLibrary/_patterns/llm-txt.template.md +4 -2
  132. package/components/componentLibrary/_patterns/prop-naming-patterns.md +208 -0
  133. package/components/componentLibrary/_patterns/storybook-patterns.md +25 -8
  134. package/components/componentLibrary/_patterns/typescript-patterns.md +6 -3
  135. package/package.json +4 -2
  136. /package/components/componentLibrary/Button/stories/{ButtonDecorator.module.css → ButtonDecorator.module.scss} +0 -0
  137. /package/components/componentLibrary/Card/stories/{CardDecorator.module.css → CardDecorator.module.scss} +0 -0
  138. /package/components/componentLibrary/Flex/stories/{FlexDecorator.module.css → FlexDecorator.module.scss} +0 -0
  139. /package/components/componentLibrary/Grid/stories/{GridDecorator.module.css → GridDecorator.module.scss} +0 -0
  140. /package/components/componentLibrary/Heading/stories/{HeadingDecorator.module.css → HeadingDecorator.module.scss} +0 -0
  141. /package/components/componentLibrary/Icon/stories/{IconDecorator.module.css → IconDecorator.module.scss} +0 -0
  142. /package/components/componentLibrary/Image/stories/{ImageDecorator.module.css → ImageDecorator.module.scss} +0 -0
  143. /package/components/componentLibrary/Image/stories/assets/{catSmile.jpg → cat-smile.jpg} +0 -0
@@ -0,0 +1,65 @@
1
+ import styles from './LanguageOptions.module.scss';
2
+ import cx from '../utils/classname.js';
3
+ import type { CSSVariables } from '../utils/types.js';
4
+ import type { LanguageOptionsProps } from './types.js';
5
+ import List, { ListItem } from '../List/index.js';
6
+ import Link from '../Link/index.js';
7
+
8
+ const LanguageOptions = ({
9
+ translations,
10
+ menuBackgroundColor,
11
+ menuBackgroundColorHover,
12
+ color,
13
+ colorHover,
14
+ }: LanguageOptionsProps) => {
15
+ if (!translations || translations.length <= 1) {
16
+ return null;
17
+ }
18
+
19
+ const cssVariables: CSSVariables = {
20
+ ...(color?.rgba && {
21
+ '--hscl-languageSwitcher-color': color.rgba,
22
+ }),
23
+ ...(menuBackgroundColor?.rgba && {
24
+ '--hscl-languageSwitcher-backgroundColor': menuBackgroundColor.rgba,
25
+ }),
26
+ ...(menuBackgroundColorHover?.rgba && {
27
+ '--hscl-languageSwitcher-backgroundColor-hover':
28
+ menuBackgroundColorHover.rgba,
29
+ }),
30
+ ...(colorHover?.rgba && {
31
+ '--hscl-languageSwitcher-color-hover': colorHover.rgba,
32
+ }),
33
+ };
34
+
35
+ return (
36
+ <List
37
+ style={cssVariables}
38
+ role="menu"
39
+ className={styles.languageList}
40
+ gap="0px"
41
+ showMarker={false}
42
+ >
43
+ {translations.map(translation => (
44
+ <ListItem
45
+ key={translation.languageCode}
46
+ role="menuitem"
47
+ className={cx(styles.languageItem, {
48
+ [styles['languageItem--active']]: translation.isActive,
49
+ })}
50
+ >
51
+ <Link
52
+ href={translation.localizedUrl}
53
+ lang={translation.languageCode}
54
+ // hrefLang={translation.languageCode} // this was in the Elevate implementation, so leaving here for now
55
+ className={styles.languageLink}
56
+ >
57
+ {translation.languageDisplayName.LOCALIZED}
58
+ </Link>
59
+ </ListItem>
60
+ ))}
61
+ </List>
62
+ );
63
+ };
64
+
65
+ export default LanguageOptions;
@@ -0,0 +1,48 @@
1
+ import { ColorField } from '@hubspot/cms-components/fields';
2
+ import type { StyleFieldsProps } from './types.js';
3
+
4
+ const StyleFields = ({
5
+ colorLabel = 'Text color',
6
+ colorName = 'color',
7
+ colorDefault = { color: '#000000', opacity: 100 },
8
+ colorHoverLabel = 'Text color (hover)',
9
+ colorHoverName = 'colorHover',
10
+ colorHoverDefault = { color: '#000000', opacity: 100 },
11
+ menuBackgroundColorLabel = 'Menu background color',
12
+ menuBackgroundColorName = 'menuBackgroundColor',
13
+ menuBackgroundColorDefault = { color: '#FFFFFF', opacity: 100 },
14
+ menuBackgroundColorHoverLabel = 'Menu background color (hover)',
15
+ menuBackgroundColorHoverName = 'menuBackgroundColorHover',
16
+ menuBackgroundColorHoverDefault = { color: '#eaeaea', opacity: 100 },
17
+ }: StyleFieldsProps) => {
18
+ return (
19
+ <>
20
+ <ColorField
21
+ label={colorLabel}
22
+ name={colorName}
23
+ default={colorDefault}
24
+ showOpacity={false}
25
+ />
26
+ <ColorField
27
+ label={colorHoverLabel}
28
+ name={colorHoverName}
29
+ default={colorHoverDefault}
30
+ showOpacity={false}
31
+ />
32
+ <ColorField
33
+ label={menuBackgroundColorLabel}
34
+ name={menuBackgroundColorName}
35
+ default={menuBackgroundColorDefault}
36
+ showOpacity={false}
37
+ />
38
+ <ColorField
39
+ label={menuBackgroundColorHoverLabel}
40
+ name={menuBackgroundColorHoverName}
41
+ default={menuBackgroundColorHoverDefault}
42
+ showOpacity={false}
43
+ />
44
+ </>
45
+ );
46
+ };
47
+
48
+ export default StyleFields;
@@ -0,0 +1,247 @@
1
+ import { LanguageVariant } from '@hubspot/cms-components';
2
+
3
+ export const dummyTranslationsAsObject = {
4
+ fr: {
5
+ isActive: false,
6
+ languageCode: 'fr',
7
+ languageDisplayName: {
8
+ PAGELANG: 'Französisch',
9
+ LOCALIZED: 'Français',
10
+ HYBRID: 'Français (Französisch)',
11
+ },
12
+ localizedUrl: 'https://www.example.com/fr/asdfasd',
13
+ },
14
+ en: {
15
+ isActive: false,
16
+ languageCode: 'en',
17
+ languageDisplayName: {
18
+ PAGELANG: 'Englisch',
19
+ LOCALIZED: 'English',
20
+ HYBRID: 'English (Englisch)',
21
+ },
22
+ localizedUrl: 'https://www.example.com/asdfasd',
23
+ },
24
+ de: {
25
+ isActive: true,
26
+ languageCode: 'de',
27
+ languageDisplayName: {
28
+ PAGELANG: 'Deutsch',
29
+ LOCALIZED: 'Deutsch',
30
+ HYBRID: 'Deutsch',
31
+ },
32
+ localizedUrl: 'https://www.example.com/de/asdfasd',
33
+ },
34
+ es: {
35
+ isActive: false,
36
+ languageCode: 'es',
37
+ languageDisplayName: {
38
+ PAGELANG: 'Spanisch',
39
+ LOCALIZED: 'Español',
40
+ HYBRID: 'Español (Spanisch)',
41
+ },
42
+ localizedUrl: 'https://www.example.com/es/asdfasd',
43
+ },
44
+ it: {
45
+ isActive: false,
46
+ languageCode: 'it',
47
+ languageDisplayName: {
48
+ PAGELANG: 'Italienisch',
49
+ LOCALIZED: 'Italiano',
50
+ HYBRID: 'Italiano (Italienisch)',
51
+ },
52
+ localizedUrl: 'https://www.example.com/it/asdfasd',
53
+ },
54
+ zh: {
55
+ isActive: false,
56
+ languageCode: 'zh',
57
+ languageDisplayName: {
58
+ PAGELANG: 'Chinesisch',
59
+ LOCALIZED: '中文',
60
+ HYBRID: '中文 (Chinesisch)',
61
+ },
62
+ localizedUrl: 'https://www.example.com/zh/asdfasd',
63
+ },
64
+ ru: {
65
+ isActive: false,
66
+ languageCode: 'ru',
67
+ languageDisplayName: {
68
+ PAGELANG: 'Russisch',
69
+ LOCALIZED: 'Русский',
70
+ HYBRID: 'Русский (Russisch)',
71
+ },
72
+ localizedUrl: 'https://www.example.com/ru/asdfasd',
73
+ },
74
+ ko: {
75
+ isActive: false,
76
+ languageCode: 'ko',
77
+ languageDisplayName: {
78
+ PAGELANG: 'Koreanisch',
79
+ LOCALIZED: '한국어',
80
+ HYBRID: '한국어 (Koreanisch)',
81
+ },
82
+ localizedUrl: 'https://www.example.com/ko/asdfasd',
83
+ },
84
+ ar: {
85
+ isActive: false,
86
+ languageCode: 'ar',
87
+ languageDisplayName: {
88
+ PAGELANG: 'Arabisch',
89
+ LOCALIZED: 'العربية',
90
+ HYBRID: 'العربية (Arabisch)',
91
+ },
92
+ localizedUrl: 'https://www.example.com/ar/asdfasd',
93
+ },
94
+ fi: {
95
+ isActive: false,
96
+ languageCode: 'fi',
97
+ languageDisplayName: {
98
+ PAGELANG: 'Finnisch',
99
+ LOCALIZED: 'Suomi',
100
+ HYBRID: 'Suomi (Finnisch)',
101
+ },
102
+ localizedUrl: 'https://www.example.com/fi/asdfasd',
103
+ },
104
+ tr: {
105
+ isActive: false,
106
+ languageCode: 'tr',
107
+ languageDisplayName: {
108
+ PAGELANG: 'Türkisch',
109
+ LOCALIZED: 'Türkçe',
110
+ HYBRID: 'Türkçe (Türkisch)',
111
+ },
112
+ localizedUrl: 'https://www.example.com/tr/asdfasd',
113
+ },
114
+ he: {
115
+ isActive: false,
116
+ languageCode: 'he',
117
+ languageDisplayName: {
118
+ PAGELANG: 'Hebräisch',
119
+ LOCALIZED: 'עברית',
120
+ HYBRID: 'עברית (Hebräisch)',
121
+ },
122
+ localizedUrl: 'https://www.example.com/he/asdfasd',
123
+ },
124
+ };
125
+
126
+ export const dummyTranslations: LanguageVariant[] = [
127
+ {
128
+ isActive: false,
129
+ languageCode: 'fr',
130
+ languageDisplayName: {
131
+ PAGELANG: 'Französisch',
132
+ LOCALIZED: 'Français',
133
+ HYBRID: 'Français (Französisch)',
134
+ },
135
+ localizedUrl: 'https://www.example.com/fr/asdfasd',
136
+ },
137
+ {
138
+ isActive: true,
139
+ languageCode: 'de',
140
+ languageDisplayName: {
141
+ PAGELANG: 'Deutsch',
142
+ LOCALIZED: 'Deutsch',
143
+ HYBRID: 'Deutsch',
144
+ },
145
+ localizedUrl: 'https://www.example.com/de/asdfasd',
146
+ },
147
+ {
148
+ isActive: false,
149
+ languageCode: 'en',
150
+ languageDisplayName: {
151
+ PAGELANG: 'Englisch',
152
+ LOCALIZED: 'English',
153
+ HYBRID: 'English (Englisch)',
154
+ },
155
+ localizedUrl: 'https://www.example.com/asdfasd',
156
+ },
157
+ {
158
+ isActive: false,
159
+ languageCode: 'es',
160
+ languageDisplayName: {
161
+ PAGELANG: 'Spanisch',
162
+ LOCALIZED: 'Español',
163
+ HYBRID: 'Español (Spanisch)',
164
+ },
165
+ localizedUrl: 'https://www.example.com/es/asdfasd',
166
+ },
167
+ {
168
+ isActive: false,
169
+ languageCode: 'it',
170
+ languageDisplayName: {
171
+ PAGELANG: 'Italienisch',
172
+ LOCALIZED: 'Italiano',
173
+ HYBRID: 'Italiano (Italienisch)',
174
+ },
175
+ localizedUrl: 'https://www.example.com/it/asdfasd',
176
+ },
177
+ {
178
+ isActive: false,
179
+ languageCode: 'zh',
180
+ languageDisplayName: {
181
+ PAGELANG: 'Chinesisch',
182
+ LOCALIZED: '中文',
183
+ HYBRID: '中文 (Chinesisch)',
184
+ },
185
+ localizedUrl: 'https://www.example.com/zh/asdfasd',
186
+ },
187
+ {
188
+ isActive: false,
189
+ languageCode: 'ru',
190
+ languageDisplayName: {
191
+ PAGELANG: 'Russisch',
192
+ LOCALIZED: 'Русский',
193
+ HYBRID: 'Русский (Russisch)',
194
+ },
195
+ localizedUrl: 'https://www.example.com/ru/asdfasd',
196
+ },
197
+ {
198
+ isActive: false,
199
+ languageCode: 'ko',
200
+ languageDisplayName: {
201
+ PAGELANG: 'Koreanisch',
202
+ LOCALIZED: '한국어',
203
+ HYBRID: '한국어 (Koreanisch)',
204
+ },
205
+ localizedUrl: 'https://www.example.com/ko/asdfasd',
206
+ },
207
+ {
208
+ isActive: false,
209
+ languageCode: 'ar',
210
+ languageDisplayName: {
211
+ PAGELANG: 'Arabisch',
212
+ LOCALIZED: 'العربية',
213
+ HYBRID: 'العربية (Arabisch)',
214
+ },
215
+ localizedUrl: 'https://www.example.com/ar/asdfasd',
216
+ },
217
+ {
218
+ isActive: false,
219
+ languageCode: 'fi',
220
+ languageDisplayName: {
221
+ PAGELANG: 'Finnisch',
222
+ LOCALIZED: 'Suomi',
223
+ HYBRID: 'Suomi (Finnisch)',
224
+ },
225
+ localizedUrl: 'https://www.example.com/fi/asdfasd',
226
+ },
227
+ {
228
+ isActive: false,
229
+ languageCode: 'tr',
230
+ languageDisplayName: {
231
+ PAGELANG: 'Türkisch',
232
+ LOCALIZED: 'Türkçe',
233
+ HYBRID: 'Türkçe (Türkisch)',
234
+ },
235
+ localizedUrl: 'https://www.example.com/tr/asdfasd',
236
+ },
237
+ {
238
+ isActive: false,
239
+ languageCode: 'he',
240
+ languageDisplayName: {
241
+ PAGELANG: 'Hebräisch',
242
+ LOCALIZED: 'עברית',
243
+ HYBRID: 'עברית (Hebräisch)',
244
+ },
245
+ localizedUrl: 'https://www.example.com/he/asdfasd',
246
+ },
247
+ ];
@@ -0,0 +1,16 @@
1
+ export default function GlobeIcon() {
2
+ return (
3
+ <svg
4
+ width="24"
5
+ height="25"
6
+ viewBox="0 0 24 25"
7
+ fill="none"
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ >
10
+ <path
11
+ d="M2.70469 9.54688L3.14531 10.3156C3.53437 10.9953 4.17188 11.4969 4.92656 11.7125L7.64062 12.4859C8.44687 12.7156 9 13.4516 9 14.2906V16.1609C9 16.6766 9.29062 17.1453 9.75 17.375C10.2094 17.6047 10.5 18.0734 10.5 18.5891V20.4172C10.5 21.1484 11.1984 21.6781 11.9016 21.4766C12.6562 21.2609 13.2422 20.6562 13.4344 19.8922L13.5656 19.3672C13.7625 18.575 14.2781 17.8953 14.9859 17.4922L15.3656 17.2766C16.0687 16.8781 16.5 16.1281 16.5 15.3219V14.9328C16.5 14.3375 16.2609 13.7656 15.8391 13.3438L15.6562 13.1609C15.2344 12.7391 14.6625 12.5 14.0672 12.5H12.0469C11.5266 12.5 11.0109 12.3641 10.5562 12.1063L8.93906 11.1828C8.7375 11.0656 8.58281 10.8781 8.50781 10.6578C8.35781 10.2078 8.55937 9.72031 8.98594 9.50937L9.2625 9.36875C9.57188 9.21406 9.93281 9.18594 10.2609 9.29844L11.3484 9.65937C11.7328 9.78594 12.1547 9.64062 12.375 9.30781C12.5953 8.97969 12.5719 8.54375 12.3187 8.23906L11.6812 7.475C11.2125 6.9125 11.2172 6.09219 11.6953 5.53906L12.4313 4.68125C12.8438 4.19844 12.9094 3.50938 12.5953 2.96094L12.4828 2.76406C12.3187 2.75469 12.1594 2.75 11.9953 2.75C7.64531 2.75 3.95625 5.60469 2.70469 9.54688ZM21.75 12.5C21.75 10.775 21.3 9.15312 20.5125 7.74219L19.3125 8.225C18.5766 8.52031 18.1969 9.34063 18.4453 10.0906L19.2375 12.4672C19.4016 12.9547 19.8 13.325 20.2969 13.4469L21.6609 13.7891C21.7172 13.3672 21.7453 12.9359 21.7453 12.5H21.75ZM0 12.5C0 9.3174 1.26428 6.26516 3.51472 4.01472C5.76516 1.76428 8.8174 0.5 12 0.5C15.1826 0.5 18.2348 1.76428 20.4853 4.01472C22.7357 6.26516 24 9.3174 24 12.5C24 15.6826 22.7357 18.7348 20.4853 20.9853C18.2348 23.2357 15.1826 24.5 12 24.5C8.8174 24.5 5.76516 23.2357 3.51472 20.9853C1.26428 18.7348 0 15.6826 0 12.5Z"
12
+ fill="currentColor"
13
+ />
14
+ </svg>
15
+ );
16
+ }
@@ -0,0 +1,58 @@
1
+ .languageSwitcher {
2
+ position: relative;
3
+ display: inline-block;
4
+ }
5
+
6
+ .button {
7
+ display: flex;
8
+ padding: 8px 12px;
9
+ align-items: center;
10
+ background-color: transparent;
11
+ color: var(--hscl-languageSwitcher-color, currentColor);
12
+ cursor: pointer;
13
+ font-size: 18px;
14
+ gap: 8px;
15
+
16
+ svg {
17
+ height: 20px;
18
+
19
+ path {
20
+ fill: currentcolor;
21
+ }
22
+ }
23
+ }
24
+
25
+ .drawer {
26
+ overflow-y: auto;
27
+ width: 400px;
28
+
29
+ @media (width <= 400px) {
30
+ width: 100%;
31
+ }
32
+ }
33
+
34
+ .sidePanelHeader {
35
+ position: sticky;
36
+ z-index: 1;
37
+ top: 0;
38
+ display: flex;
39
+ padding: 24px;
40
+ align-items: center;
41
+ justify-content: space-between;
42
+ background-color: var(--hscl-languageSwitcher-backgroundColor, #ffffff);
43
+ }
44
+
45
+ .sidePanelTitle {
46
+ margin: 0;
47
+ color: var(--hscl-languageSwitcher-color, currentColor);
48
+ font-size: 24px;
49
+ font-weight: 600;
50
+ }
51
+
52
+ .sidePanelCloseButton {
53
+ color: var(--hscl-languageSwitcher-color, currentColor);
54
+ }
55
+
56
+ .sidePanelOptionsContainer {
57
+ padding: 24px;
58
+ }
@@ -0,0 +1,125 @@
1
+ import styles from './index.module.scss';
2
+ import cx from '../utils/classname.js';
3
+ import { getLanguageDisplayName } from './utils.js';
4
+ import LanguageOptions from './LanguageOptions.js';
5
+ import GlobeIcon from './assets/Globe.js';
6
+ import type { LanguageSwitcherProps } from './types.js';
7
+ import ContentFields from './ContentFields.js';
8
+ import StyleFields from './StyleFields.js';
9
+ import Button from '../Button/index.js';
10
+ import { useLanguageVariants } from '@hubspot/cms-components';
11
+ import { createTranslationsArrayAsObject } from './utils.js';
12
+ import Drawer, { useDrawer } from '../Drawer/index.js';
13
+ import { dummyTranslationsAsObject, dummyTranslations } from './_dummyData.js';
14
+ import Divider from '../Divider/index.js';
15
+ import type { CSSVariables } from '../utils/types.js';
16
+
17
+ const LanguageSwitcherComponent = ({
18
+ useDummyData = false, // !todo - remove this in PROD (NOTE: storybook still needs the _dummyData, so add the _dummyData file to storybook dir and refactor usage there)
19
+ menuBackgroundColor,
20
+ menuBackgroundColorHover,
21
+ color,
22
+ colorHover,
23
+ languageSwitcherSelectText = 'Select a language',
24
+ className = '',
25
+ style = {},
26
+ }: LanguageSwitcherProps) => {
27
+ const translations = useDummyData ? dummyTranslations : useLanguageVariants(); // !todo remove this in PROD
28
+ const translationsArrayAsObject = useDummyData
29
+ ? dummyTranslationsAsObject
30
+ : createTranslationsArrayAsObject(translations); // !todo remove this in PROD
31
+ const activeTranslation = translations?.find(item => item.isActive);
32
+ const currentPageLanguage = activeTranslation?.languageCode ?? '';
33
+ const currentPageLanguageDisplayName = getLanguageDisplayName({
34
+ currentPageLanguage,
35
+ translationsArrayAsObject,
36
+ });
37
+
38
+ const { isOpen, toggle, close } = useDrawer();
39
+
40
+ const isInEditor = false; // !todo - update this to use useEditorVariableChecks() hook (is_in_editor property) once it's working
41
+
42
+ const colorCss = color?.rgba;
43
+ const menuBackgroundColorCss = menuBackgroundColor?.rgba;
44
+
45
+ const cssVariables = {
46
+ ...(colorCss && { '--hscl-languageSwitcher-color': colorCss }),
47
+ ...(menuBackgroundColorCss && {
48
+ '--hscl-languageSwitcher-backgroundColor': menuBackgroundColorCss,
49
+ }),
50
+ };
51
+
52
+ const dividerCssVariables: CSSVariables = {
53
+ '--hscl-divider-borderColor': colorCss,
54
+ };
55
+
56
+ const combinedClasses = cx(styles.languageSwitcher, className);
57
+
58
+ return (
59
+ <div style={{ ...cssVariables, ...style }} className={combinedClasses}>
60
+ <Button
61
+ buttonType="button"
62
+ aria-expanded={isOpen}
63
+ onClick={toggle}
64
+ className={styles.button}
65
+ style={{ color: colorCss }}
66
+ >
67
+ <GlobeIcon />
68
+ {currentPageLanguageDisplayName}
69
+ </Button>
70
+ {!isInEditor && (
71
+ <Drawer
72
+ open={isOpen}
73
+ direction="right"
74
+ onOverlayClick={close}
75
+ aria-label="Language selector"
76
+ className={styles.drawer}
77
+ style={{
78
+ ...cssVariables,
79
+ backgroundColor: menuBackgroundColorCss,
80
+ }}
81
+ >
82
+ <div className={styles.sidePanelHeader}>
83
+ <span className={styles.sidePanelTitle}>
84
+ {languageSwitcherSelectText}
85
+ </span>
86
+ <Button
87
+ buttonType="button"
88
+ onClick={close}
89
+ aria-label="Close language selector"
90
+ className={styles.sidePanelCloseButton}
91
+ >
92
+
93
+ </Button>
94
+ </div>
95
+
96
+ <Divider spacing="0px" style={dividerCssVariables} />
97
+
98
+ <div className={styles.sidePanelOptionsContainer}>
99
+ <LanguageOptions
100
+ {...{
101
+ translations,
102
+ menuBackgroundColor,
103
+ menuBackgroundColorHover,
104
+ color,
105
+ colorHover,
106
+ }}
107
+ />
108
+ </div>
109
+ </Drawer>
110
+ )}
111
+ </div>
112
+ );
113
+ };
114
+
115
+ type LanguageSwitcherComponentType = typeof LanguageSwitcherComponent & {
116
+ ContentFields: typeof ContentFields;
117
+ StyleFields: typeof StyleFields;
118
+ };
119
+
120
+ const LanguageSwitcher =
121
+ LanguageSwitcherComponent as LanguageSwitcherComponentType;
122
+ LanguageSwitcher.ContentFields = ContentFields;
123
+ LanguageSwitcher.StyleFields = StyleFields;
124
+
125
+ export default LanguageSwitcher;