@hubspot/cms-component-library 0.3.1 → 0.3.3

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 (25) hide show
  1. package/components/componentLibrary/Accordion/AccordionItem/index.module.scss +4 -0
  2. package/components/componentLibrary/Accordion/AccordionTitle/ContentFields.tsx +1 -0
  3. package/components/componentLibrary/Accordion/AccordionTitle/icons.tsx +19 -0
  4. package/components/componentLibrary/Accordion/AccordionTitle/index.module.scss +4 -0
  5. package/components/componentLibrary/Accordion/AccordionTitle/index.tsx +3 -1
  6. package/components/componentLibrary/Accordion/AccordionTitle/types.ts +1 -1
  7. package/components/componentLibrary/Accordion/llm.txt +7 -6
  8. package/components/componentLibrary/Accordion/stories/Accordion.stories.tsx +21 -0
  9. package/components/componentLibrary/Divider/StyleFields.tsx +72 -14
  10. package/components/componentLibrary/Divider/index.tsx +31 -16
  11. package/components/componentLibrary/Divider/llm.txt +97 -103
  12. package/components/componentLibrary/Divider/stories/Divider.stories.tsx +30 -19
  13. package/components/componentLibrary/Divider/types.ts +31 -20
  14. package/components/componentLibrary/Icon/StyleFields.tsx +69 -0
  15. package/components/componentLibrary/Icon/index.module.scss +11 -0
  16. package/components/componentLibrary/Icon/index.tsx +31 -4
  17. package/components/componentLibrary/Icon/llm.txt +50 -10
  18. package/components/componentLibrary/Icon/types.ts +29 -0
  19. package/components/componentLibrary/Text/ContentFields.tsx +66 -0
  20. package/components/componentLibrary/Text/index.module.scss +3 -0
  21. package/components/componentLibrary/Text/index.tsx +27 -0
  22. package/components/componentLibrary/Text/llm.txt +170 -0
  23. package/components/componentLibrary/Text/types.ts +16 -0
  24. package/package.json +4 -4
  25. package/components/componentLibrary/Divider/ContentFields.tsx +0 -63
@@ -13,7 +13,7 @@ const meta: Meta<DividerProps> = {
13
13
  layout: 'centered',
14
14
  docs: {
15
15
  description: {
16
- component: `The Divider component provides a visual separator between content sections. It supports both horizontal and vertical orientations with customizable styling options including border style, thickness, length, and spacing.`,
16
+ component: `The Divider component provides a visual separator between content sections. It supports both horizontal and vertical orientations with customizable styling options including line type, thickness, length, alignment, color, and spacing.`,
17
17
  },
18
18
  },
19
19
  },
@@ -26,7 +26,6 @@ type Story = StoryObj<typeof meta>;
26
26
  export const Default: Story = {
27
27
  args: {
28
28
  orientation: 'horizontal',
29
- alignment: 'stretch',
30
29
  borderStyle: 'solid',
31
30
  length: 100,
32
31
  thickness: 1,
@@ -196,25 +195,37 @@ export const Alignment: Story = {
196
195
  <SBContainer addBackground flex>
197
196
  <h4>Stretch (Default)</h4>
198
197
  <p>Divider stretches to fill available space</p>
199
- <Divider length={100} thickness={1} alignment="stretch" />
198
+ <Divider length={100} thickness={1} />
200
199
  </SBContainer>
201
200
 
202
201
  <SBContainer addBackground flex>
203
- <h4>Start</h4>
204
- <p>Divider aligns to the start (left for horizontal)</p>
205
- <Divider length={50} thickness={1} alignment="start" />
202
+ <h4>Left</h4>
203
+ <p>Divider aligns to the left</p>
204
+ <Divider
205
+ length={50}
206
+ thickness={1}
207
+ alignment={{ horizontal_align: 'LEFT' }}
208
+ />
206
209
  </SBContainer>
207
210
 
208
211
  <SBContainer addBackground flex>
209
212
  <h4>Center</h4>
210
213
  <p>Divider aligns to the center</p>
211
- <Divider length={50} thickness={1} alignment="center" />
214
+ <Divider
215
+ length={50}
216
+ thickness={1}
217
+ alignment={{ horizontal_align: 'CENTER' }}
218
+ />
212
219
  </SBContainer>
213
220
 
214
221
  <SBContainer addBackground flex>
215
- <h4>End</h4>
216
- <p>Divider aligns to the end (right for horizontal)</p>
217
- <Divider length={50} thickness={1} alignment="end" />
222
+ <h4>Right</h4>
223
+ <p>Divider aligns to the right</p>
224
+ <Divider
225
+ length={50}
226
+ thickness={1}
227
+ alignment={{ horizontal_align: 'RIGHT' }}
228
+ />
218
229
  </SBContainer>
219
230
  </SBContainer>
220
231
  ),
@@ -323,8 +334,8 @@ export const VerticalAlignment: Story = {
323
334
  render: () => (
324
335
  <SBContainer flex direction="column" gap="large">
325
336
  <SBContainer addBackground>
326
- <h4>Start</h4>
327
- <p>Divider aligns to the start (top for vertical)</p>
337
+ <h4>Top</h4>
338
+ <p>Divider aligns to the top</p>
328
339
  <div
329
340
  style={{
330
341
  display: 'flex',
@@ -337,7 +348,7 @@ export const VerticalAlignment: Story = {
337
348
  orientation="vertical"
338
349
  length={50}
339
350
  thickness={1}
340
- alignment="start"
351
+ alignment={{ vertical_align: 'TOP' }}
341
352
  spacing="16px"
342
353
  />
343
354
  <span>Right</span>
@@ -345,8 +356,8 @@ export const VerticalAlignment: Story = {
345
356
  </SBContainer>
346
357
 
347
358
  <SBContainer addBackground>
348
- <h4>Center</h4>
349
- <p>Divider aligns to the center</p>
359
+ <h4>Middle</h4>
360
+ <p>Divider aligns to the middle</p>
350
361
  <div
351
362
  style={{
352
363
  display: 'flex',
@@ -359,7 +370,7 @@ export const VerticalAlignment: Story = {
359
370
  orientation="vertical"
360
371
  length={50}
361
372
  thickness={1}
362
- alignment="center"
373
+ alignment={{ vertical_align: 'MIDDLE' }}
363
374
  spacing="16px"
364
375
  />
365
376
  <span>Right</span>
@@ -367,8 +378,8 @@ export const VerticalAlignment: Story = {
367
378
  </SBContainer>
368
379
 
369
380
  <SBContainer addBackground>
370
- <h4>End</h4>
371
- <p>Divider aligns to the end (bottom for vertical)</p>
381
+ <h4>Bottom</h4>
382
+ <p>Divider aligns to the bottom</p>
372
383
  <div
373
384
  style={{
374
385
  display: 'flex',
@@ -381,7 +392,7 @@ export const VerticalAlignment: Story = {
381
392
  orientation="vertical"
382
393
  length={50}
383
394
  thickness={1}
384
- alignment="end"
395
+ alignment={{ vertical_align: 'BOTTOM' }}
385
396
  spacing="16px"
386
397
  />
387
398
  <span>Right</span>
@@ -1,45 +1,56 @@
1
+ import type {
2
+ AlignmentFieldDefaults,
3
+ ColorFieldDefaults,
4
+ } from '@hubspot/cms-components/fields';
1
5
  import type { CSSVariables } from '../utils/types.js';
2
6
 
3
- export type DividerOrientation = 'horizontal' | 'vertical';
7
+ type AlignmentValue = typeof AlignmentFieldDefaults;
8
+ type ColorValue = typeof ColorFieldDefaults;
4
9
 
5
- export type DividerAlignment = 'stretch' | 'start' | 'center' | 'end';
10
+ export type DividerOrientation = 'horizontal' | 'vertical';
6
11
 
7
12
  export type DividerBorderStyle = 'solid' | 'dotted' | 'dashed' | 'double';
8
13
 
14
+ export type DividerAlignmentDirection = 'HORIZONTAL' | 'VERTICAL';
15
+
9
16
  type PixelValue = `${number}px`;
10
17
 
11
18
  export type DividerProps = {
12
19
  orientation?: DividerOrientation;
13
- alignment?: DividerAlignment;
20
+ alignment?: AlignmentValue;
14
21
  spacing?: PixelValue;
15
22
  borderStyle?: DividerBorderStyle;
16
23
  length?: number;
17
24
  thickness?: number;
25
+ color?: ColorValue;
18
26
  variant?: 'primary' | 'secondary' | 'tertiary';
19
27
  className?: string;
20
28
  style?: CSSVariables;
21
29
  };
22
30
 
23
- export type ContentFieldsProps = {
24
- orientationLabel?: string;
25
- orientationName?: string;
26
- orientationDefault?: string;
27
- alignmentLabel?: string;
28
- alignmentName?: string;
29
- alignmentDefault?: string;
30
- lengthLabel?: string;
31
- lengthName?: string;
32
- lengthDefault?: number;
33
- thicknessLabel?: string;
34
- thicknessName?: string;
35
- thicknessDefault?: number;
36
- };
31
+ export type StyleFieldName =
32
+ | 'borderStyle'
33
+ | 'color'
34
+ | 'thickness'
35
+ | 'length'
36
+ | 'alignment';
37
37
 
38
38
  export type StyleFieldsProps = {
39
- spacingLabel?: string;
40
- spacingName?: string;
41
- spacingDefault?: string;
39
+ hideFields?: StyleFieldName[];
42
40
  borderStyleLabel?: string;
43
41
  borderStyleName?: string;
44
42
  borderStyleDefault?: string;
43
+ thicknessLabel?: string;
44
+ thicknessName?: string;
45
+ thicknessDefault?: number;
46
+ lengthLabel?: string;
47
+ lengthName?: string;
48
+ lengthDefault?: number;
49
+ alignmentLabel?: string;
50
+ alignmentName?: string;
51
+ alignmentDefault?: AlignmentValue;
52
+ alignmentDirection?: DividerAlignmentDirection;
53
+ colorLabel?: string;
54
+ colorName?: string;
55
+ colorDefault?: ColorValue;
45
56
  };
@@ -0,0 +1,69 @@
1
+ import { ColorField, ChoiceField } from '@hubspot/cms-components/fields';
2
+ import type { StyleFieldsProps } from './types.js';
3
+
4
+ const StyleFields = ({
5
+ hideFields = [],
6
+ iconColorLabel = 'Icon color',
7
+ iconColorName = 'iconColor',
8
+ iconColorDefault = { color: '#A8A8A8', opacity: 100 },
9
+ iconBackgroundColorLabel = 'Background color',
10
+ iconBackgroundColorName = 'iconBackgroundColor',
11
+ iconBackgroundColorDefault = { color: '#2C2C2C', opacity: 100 },
12
+ iconShapeLabel = 'Icon shape',
13
+ iconShapeName = 'iconShape',
14
+ iconShapeDefault = '0px',
15
+ iconSizeLabel = 'Icon size',
16
+ iconSizeName = 'iconSize',
17
+ iconSizeDefault = '16',
18
+ }: StyleFieldsProps) => {
19
+ return (
20
+ <>
21
+ {!hideFields.includes('iconColor') && (
22
+ <ColorField
23
+ label={iconColorLabel}
24
+ name={iconColorName}
25
+ default={iconColorDefault}
26
+ showOpacity={false}
27
+ />
28
+ )}
29
+ {!hideFields.includes('iconBackgroundColor') && (
30
+ <ColorField
31
+ label={iconBackgroundColorLabel}
32
+ name={iconBackgroundColorName}
33
+ default={iconBackgroundColorDefault}
34
+ showOpacity={false}
35
+ />
36
+ )}
37
+ {!hideFields.includes('iconShape') && (
38
+ <ChoiceField
39
+ label={iconShapeLabel}
40
+ name={iconShapeName}
41
+ display="buttons"
42
+ preset="icon_shape"
43
+ choices={[
44
+ ['0px', 'Square'],
45
+ ['8px', 'Rounded'],
46
+ ['100%', 'Circle'],
47
+ ]}
48
+ default={iconShapeDefault}
49
+ required={true}
50
+ />
51
+ )}
52
+ {!hideFields.includes('iconSize') && (
53
+ <ChoiceField
54
+ label={iconSizeLabel}
55
+ name={iconSizeName}
56
+ choices={[
57
+ ['16', 'Small (16x16 px)'],
58
+ ['24', 'Medium (24x24 px)'],
59
+ ['32', 'Large (32x32 px)'],
60
+ ]}
61
+ default={iconSizeDefault}
62
+ required={true}
63
+ />
64
+ )}
65
+ </>
66
+ );
67
+ };
68
+
69
+ export default StyleFields;
@@ -7,3 +7,14 @@
7
7
  width: var(--hscl-icon-size);
8
8
  height: var(--hscl-icon-size);
9
9
  }
10
+
11
+ .iconBackground {
12
+ display: inline-flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ justify-self: flex-start;
16
+ align-self: flex-start;
17
+ background-color: var(--hscl-iconBackground-backgroundColor, transparent);
18
+ padding: var(--hscl-iconBackground-padding, 12px);
19
+ border-radius: var(--hscl-iconBackground-shape, 0px);
20
+ }
@@ -1,6 +1,7 @@
1
1
  import styles from './index.module.scss';
2
2
  import { Icon as CMSIcon } from '@hubspot/cms-components';
3
3
  import ContentFields from './ContentFields.js';
4
+ import StyleFields from './StyleFields.js';
4
5
  import cx from '../utils/classname.js';
5
6
  import type { CSSVariables } from '../utils/types.js';
6
7
  import { IconProps } from './types.js';
@@ -14,18 +15,22 @@ const IconComponent = ({
14
15
  purpose = 'DECORATIVE',
15
16
  title = '',
16
17
  fill,
18
+ showIconBackground = false,
19
+ iconBackgroundColor,
20
+ iconBackgroundPadding,
21
+ iconBackgroundShape,
17
22
  }: IconProps) => {
18
23
  if (!showIcon) return null;
19
24
 
20
- const defaultClasses = styles.icon;
21
- const combinedClasses = cx(defaultClasses, className);
22
-
23
25
  const cssVariables: CSSVariables = {
24
26
  '--hscl-icon-size': `${size}px`,
25
27
  ...(fill && { '--hscl-icon-fill': fill }),
26
28
  };
27
29
 
28
- return (
30
+ const defaultClasses = styles.icon;
31
+ const combinedClasses = cx(defaultClasses, className);
32
+
33
+ const icon = (
29
34
  <CMSIcon
30
35
  fieldPath={fieldPath}
31
36
  height={size}
@@ -35,13 +40,35 @@ const IconComponent = ({
35
40
  title={title}
36
41
  />
37
42
  );
43
+
44
+ if (!showIconBackground) return icon;
45
+
46
+ const backgroundCssVariables: CSSVariables = {
47
+ ...(iconBackgroundColor && {
48
+ '--hscl-iconBackground-backgroundColor': iconBackgroundColor,
49
+ }),
50
+ ...(iconBackgroundPadding && {
51
+ '--hscl-iconBackground-padding': `${iconBackgroundPadding}px`,
52
+ }),
53
+ ...(iconBackgroundShape && {
54
+ '--hscl-iconBackground-shape': iconBackgroundShape,
55
+ }),
56
+ };
57
+
58
+ return (
59
+ <div className={styles.iconBackground} style={backgroundCssVariables}>
60
+ {icon}
61
+ </div>
62
+ );
38
63
  };
39
64
 
40
65
  type IconComponentType = typeof IconComponent & {
41
66
  ContentFields: typeof ContentFields;
67
+ StyleFields: typeof StyleFields;
42
68
  };
43
69
 
44
70
  const Icon = IconComponent as IconComponentType;
45
71
  Icon.ContentFields = ContentFields;
72
+ Icon.StyleFields = StyleFields;
46
73
 
47
74
  export default Icon;
@@ -9,7 +9,7 @@ import Icon from '@hubspot/cms-component-library/Icon';
9
9
 
10
10
  ## Purpose
11
11
 
12
- The Icon component wraps the native HubSpot CMS Icon component to provide a consistent interface for rendering icons with customizable styling and accessibility options. It simplifies icon usage in HubSpot CMS projects by handling common configuration patterns like sizing, color theming through CSS variables, and proper accessibility attributes (SEMANTIC vs DECORATIVE purpose).
12
+ The Icon component wraps the native HubSpot CMS Icon component to provide a consistent interface for rendering icons with customizable styling and accessibility options. It simplifies icon usage in HubSpot CMS projects by handling common configuration patterns like sizing, color theming through CSS variables, optional background containers, and proper accessibility attributes (SEMANTIC vs DECORATIVE purpose).
13
13
 
14
14
  ## Component Structure
15
15
 
@@ -18,6 +18,7 @@ Icon/
18
18
  ├── index.tsx # Main component with render logic
19
19
  ├── types.ts # TypeScript type definitions
20
20
  ├── ContentFields.tsx # HubSpot field definitions for icon content
21
+ ├── StyleFields.tsx # HubSpot field definitions for icon styles
21
22
  ├── index.module.scss # CSS module with design tokens
22
23
  └── stories/
23
24
  ├── Icon.stories.tsx # Component usage examples
@@ -29,7 +30,7 @@ Icon/
29
30
 
30
31
  ### Icon (Main Component)
31
32
 
32
- **Purpose:** Renders an icon with configurable size, color, and accessibility properties.
33
+ **Purpose:** Renders an icon with configurable size, color, background, and accessibility properties.
33
34
 
34
35
  **Props:**
35
36
  ```tsx
@@ -42,6 +43,10 @@ Icon/
42
43
  showIcon?: boolean; // Toggle icon visibility (default: true)
43
44
  purpose?: 'SEMANTIC' | 'DECORATIVE'; // Icon accessibility role (default: 'DECORATIVE')
44
45
  title?: string; // Icon title for screen readers (use with SEMANTIC)
46
+ showIconBackground?: boolean; // Renders a centered background div behind the icon (default: false)
47
+ iconBackgroundColor?: string; // Background div color (used when showIconBackground is true)
48
+ iconBackgroundPadding?: number; // Padding around the icon inside the background div in px (default: 12)
49
+ iconBackgroundShape?: string; // Border-radius of the background div, e.g. '0px', '8px', '100%' (default: 0px)
45
50
  }
46
51
  ```
47
52
 
@@ -89,6 +94,19 @@ import Icon from '@hubspot/cms-component-library/Icon';
89
94
  />
90
95
  ```
91
96
 
97
+ ### Icon with Background
98
+
99
+ ```tsx
100
+ <Icon
101
+ fieldPath="icon"
102
+ size={24}
103
+ showIconBackground={true}
104
+ iconBackgroundColor="#2C2C2C"
105
+ iconBackgroundPadding={16}
106
+ iconBackgroundShape="100%"
107
+ />
108
+ ```
109
+
92
110
  ## HubSpot CMS Integration
93
111
 
94
112
  ### Field Definitions
@@ -115,9 +133,21 @@ Configurable props for icon selection and visibility:
115
133
  - `icon`: IconField for selecting the icon
116
134
  - `showIcon`: BooleanField toggle for icon visibility (optional, enabled with `addIconToggle={true}`)
117
135
 
118
- #### Style Fields
136
+ #### StyleFields
119
137
 
120
- **Note:** There are no style fields included with this component. Do not try to import them.
138
+ Configurable props for icon appearance:
139
+
140
+ ```tsx
141
+ <Icon.StyleFields />
142
+ ```
143
+
144
+ **Fields:**
145
+ - `iconColor`: ColorField for the icon fill color
146
+ - `iconBackgroundColor`: ColorField for the background div color
147
+ - `iconShape`: ChoiceField for the background border-radius (`'0px'` Square, `'8px'` Rounded, `'100%'` Circle)
148
+ - `iconSize`: ChoiceField for icon size (16px Small, 24px Medium, 32px Large)
149
+
150
+ All fields support `label`, `name`, and `default` customization props, and can be hidden via `hideFields`.
121
151
 
122
152
  ### Module Usage Example
123
153
 
@@ -128,8 +158,12 @@ export default function IconModule({ fieldValues }) {
128
158
  return (
129
159
  <Icon
130
160
  fieldPath="icon"
131
- size={fieldValues.iconSize || 24}
161
+ size={Number(fieldValues.style?.iconSize) || 24}
132
162
  showIcon={fieldValues.showIcon}
163
+ fill={fieldValues.style?.iconColor?.color}
164
+ showIconBackground={fieldValues.style?.showIconBackground}
165
+ iconBackgroundColor={fieldValues.style?.iconBackgroundColor?.color}
166
+ iconBackgroundShape={fieldValues.style?.iconShape}
133
167
  purpose="DECORATIVE"
134
168
  />
135
169
  );
@@ -139,14 +173,15 @@ export default function IconModule({ fieldValues }) {
139
173
  ### Module Fields Example
140
174
 
141
175
  ```tsx
142
- import { ModuleFields } from '@hubspot/cms-components/fields';
176
+ import { ModuleFields, FieldGroup } from '@hubspot/cms-components/fields';
143
177
  import Icon from '@hubspot/cms-component-library/Icon';
144
178
 
145
179
  export const fields = (
146
180
  <ModuleFields>
147
- <Icon.ContentFields
148
- addIconToggle={true}
149
- />
181
+ <Icon.ContentFields addIconToggle={true} />
182
+ <FieldGroup name="style" label="Style" tab="STYLE">
183
+ <Icon.StyleFields />
184
+ </FieldGroup>
150
185
  </ModuleFields>
151
186
  );
152
187
  ```
@@ -161,6 +196,11 @@ The Icon component uses CSS variables for theming and customization:
161
196
  - `--hscl-icon-fill`: Icon fill color (default: currentColor)
162
197
  - `--hscl-icon-size`: Icon width and height (set automatically from the `size` prop)
163
198
 
199
+ **Background Styles (applied when `showIconBackground` is true):**
200
+ - `--hscl-iconBackground-backgroundColor`: Background div color
201
+ - `--hscl-iconBackground-padding`: Padding around the icon inside the background div (default: 12px)
202
+ - `--hscl-iconBackground-shape`: Border-radius of the background div (default: 0px)
203
+
164
204
 
165
205
  ## Accessibility
166
206
 
@@ -179,4 +219,4 @@ The Icon component follows accessibility best practices:
179
219
  - **Use CSS variables for theming**: Override `--hscl-icon-fill` for consistent color theming across your application
180
220
  - **Size appropriately**: Common sizes are 12px (small), 16px (default inline), 24px (medium), 32px (large), 48px (extra large)
181
221
  - **Field path**: The `fieldPath` prop should match the field name defined in ContentFields
182
- - **Style fields**: There are no style fields in this component. Do not try to import them.
222
+ - **Background shape**: The `iconShape` StyleField value maps directly to `iconBackgroundShape` on the component pass it through as-is
@@ -1,8 +1,11 @@
1
1
  import {
2
2
  IconFieldDefaults,
3
3
  BooleanFieldDefaults,
4
+ ColorFieldDefaults,
4
5
  } from '@hubspot/cms-components/fields';
5
6
 
7
+ type ColorFieldValue = typeof ColorFieldDefaults;
8
+
6
9
  export type IconPurpose = 'SEMANTIC' | 'DECORATIVE';
7
10
 
8
11
  export type IconProps = {
@@ -14,6 +17,10 @@ export type IconProps = {
14
17
  showIcon?: boolean;
15
18
  purpose?: IconPurpose;
16
19
  title?: string;
20
+ showIconBackground?: boolean;
21
+ iconBackgroundColor?: string;
22
+ iconBackgroundPadding?: number;
23
+ iconBackgroundShape?: string;
17
24
  };
18
25
 
19
26
  type IconToggleProps = {
@@ -36,3 +43,25 @@ export type IconContentFieldsWithToggleProps =
36
43
  export type ContentFieldsProps =
37
44
  | IconContentFieldsWithToggleProps
38
45
  | IconContentFieldsWithoutToggleProps;
46
+
47
+ export type StyleFieldName =
48
+ | 'iconColor'
49
+ | 'iconBackgroundColor'
50
+ | 'iconShape'
51
+ | 'iconSize';
52
+
53
+ export type StyleFieldsProps = {
54
+ hideFields?: StyleFieldName[];
55
+ iconColorLabel?: string;
56
+ iconColorName?: string;
57
+ iconColorDefault?: ColorFieldValue;
58
+ iconBackgroundColorLabel?: string;
59
+ iconBackgroundColorName?: string;
60
+ iconBackgroundColorDefault?: ColorFieldValue;
61
+ iconShapeLabel?: string;
62
+ iconShapeName?: string;
63
+ iconShapeDefault?: string;
64
+ iconSizeLabel?: string;
65
+ iconSizeName?: string;
66
+ iconSizeDefault?: string;
67
+ };
@@ -0,0 +1,66 @@
1
+ import {
2
+ RichTextField,
3
+ RichTextFieldType,
4
+ } from '@hubspot/cms-components/fields';
5
+ import type { ContentFieldsProps } from './types.js';
6
+
7
+ // To do: These are placeholders - we can refine and add more after some UX feedback and further discussion
8
+
9
+ const headingEnabledFeatures: RichTextFieldType['enabledFeatures'] = [
10
+ 'block',
11
+ 'alignment',
12
+ 'indents',
13
+ 'lists',
14
+ 'standard_emphasis',
15
+ 'advanced_emphasis',
16
+ 'link',
17
+ 'personalize',
18
+ 'nonbreaking_space',
19
+ 'source_code',
20
+ 'visual_blocks',
21
+ ];
22
+
23
+ const bodyContentEnabledFeatures: RichTextFieldType['enabledFeatures'] = [
24
+ 'block',
25
+ 'alignment',
26
+ 'indents',
27
+ 'lists',
28
+ 'standard_emphasis',
29
+ 'advanced_emphasis',
30
+ 'link',
31
+ 'image',
32
+ 'emoji',
33
+ 'table',
34
+ 'personalize',
35
+ 'cta',
36
+ 'embed',
37
+ 'video',
38
+ 'charmap',
39
+ 'anchor',
40
+ 'nonbreaking_space',
41
+ 'source_code',
42
+ 'visual_blocks',
43
+ ];
44
+
45
+ const featureSetMap = {
46
+ bodyContent: bodyContentEnabledFeatures,
47
+ heading: headingEnabledFeatures,
48
+ };
49
+
50
+ const ContentFields = ({
51
+ textLabel = 'Text',
52
+ textName = 'text',
53
+ textDefault = '<p>Text goes here.</p>',
54
+ textFeatureSet = 'bodyContent',
55
+ }: ContentFieldsProps) => {
56
+ return (
57
+ <RichTextField
58
+ label={textLabel}
59
+ name={textName}
60
+ default={textDefault}
61
+ enabledFeatures={featureSetMap[textFeatureSet]}
62
+ />
63
+ );
64
+ };
65
+
66
+ export default ContentFields;
@@ -0,0 +1,3 @@
1
+ .text {
2
+ color: var(--hscl-text-color, currentColor);
3
+ }
@@ -0,0 +1,27 @@
1
+ import { RichText } from '@hubspot/cms-components';
2
+ import styles from './index.module.scss';
3
+ import ContentFields from './ContentFields.js';
4
+ import cx from '../utils/classname.js';
5
+ import { TextProps } from './types.js';
6
+
7
+ const TextComponent = ({
8
+ fieldPath,
9
+ className = '',
10
+ style = {},
11
+ }: TextProps) => {
12
+ const defaultClasses = styles.text;
13
+ const combinedClasses = cx(defaultClasses, className);
14
+
15
+ return (
16
+ <RichText fieldPath={fieldPath} className={combinedClasses} style={style} />
17
+ );
18
+ };
19
+
20
+ type TextComponentType = typeof TextComponent & {
21
+ ContentFields: typeof ContentFields;
22
+ };
23
+
24
+ const Text = TextComponent as TextComponentType;
25
+ Text.ContentFields = ContentFields;
26
+
27
+ export default Text;