@hubspot/cms-component-library 0.2.0 → 0.3.1
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.
- package/components/componentLibrary/Button/StyleFields.tsx +21 -1
- package/components/componentLibrary/Button/index.tsx +1 -1
- package/components/componentLibrary/Button/llm.txt +5 -1
- package/components/componentLibrary/Button/types.ts +6 -1
- package/components/componentLibrary/Flex/index.module.scss +4 -6
- package/components/componentLibrary/Flex/llm.txt +5 -7
- package/components/componentLibrary/Flex/types.ts +0 -4
- package/components/componentLibrary/Icon/index.module.scss +2 -2
- package/components/componentLibrary/Icon/index.tsx +3 -2
- package/components/componentLibrary/Icon/llm.txt +7 -6
- package/components/componentLibrary/Icon/stories/Icon.stories.tsx +11 -11
- package/components/componentLibrary/Icon/stories/IconDecorator.module.scss +1 -2
- package/components/componentLibrary/Icon/types.ts +1 -1
- package/components/componentLibrary/_patterns/css-patterns.md +7 -18
- package/package.json +3 -2
- package/components/componentLibrary/Heading/ContentFields.tsx +0 -37
- package/components/componentLibrary/Heading/StyleFields.tsx +0 -40
- package/components/componentLibrary/Heading/index.module.scss +0 -11
- package/components/componentLibrary/Heading/index.tsx +0 -52
- package/components/componentLibrary/Heading/llm.txt +0 -175
- package/components/componentLibrary/Heading/stories/Heading.stories.tsx +0 -88
- package/components/componentLibrary/Heading/stories/HeadingDecorator.module.scss +0 -47
- package/components/componentLibrary/Heading/stories/HeadingDecorator.tsx +0 -8
- package/components/componentLibrary/Heading/types.ts +0 -35
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import { ChoiceField } from '@hubspot/cms-components/fields';
|
|
1
|
+
import { ChoiceField, Visibility } from '@hubspot/cms-components/fields';
|
|
2
2
|
import { StyleFieldsProps } from './types.js';
|
|
3
3
|
|
|
4
4
|
const StyleFields = ({
|
|
5
5
|
buttonVariantLabel = 'Button variant',
|
|
6
6
|
buttonVariantName = 'buttonVariant',
|
|
7
7
|
buttonVariantDefault = 'primary',
|
|
8
|
+
buttonIconPositionLabel = 'Icon position',
|
|
9
|
+
buttonIconPositionName = 'buttonIconPosition',
|
|
10
|
+
buttonIconPositionDefault = 'right',
|
|
8
11
|
}: StyleFieldsProps) => {
|
|
12
|
+
// iconComponentShowIcon is the hardcoded id in @components/componentLibrary/Icon/ContentFields.tsx
|
|
13
|
+
const iconPositionVisibility: Visibility = {
|
|
14
|
+
operator: 'EQUAL',
|
|
15
|
+
controlling_field: 'iconComponentShowIcon',
|
|
16
|
+
controlling_value_regex: 'true',
|
|
17
|
+
};
|
|
18
|
+
|
|
9
19
|
return (
|
|
10
20
|
<>
|
|
11
21
|
<ChoiceField
|
|
@@ -18,6 +28,16 @@ const StyleFields = ({
|
|
|
18
28
|
]}
|
|
19
29
|
default={buttonVariantDefault}
|
|
20
30
|
/>
|
|
31
|
+
<ChoiceField
|
|
32
|
+
label={buttonIconPositionLabel}
|
|
33
|
+
name={buttonIconPositionName}
|
|
34
|
+
choices={[
|
|
35
|
+
['left', 'Left'],
|
|
36
|
+
['right', 'Right'],
|
|
37
|
+
]}
|
|
38
|
+
default={buttonIconPositionDefault}
|
|
39
|
+
visibility={iconPositionVisibility}
|
|
40
|
+
/>
|
|
21
41
|
</>
|
|
22
42
|
);
|
|
23
43
|
};
|
|
@@ -234,18 +234,22 @@ Configurable props for customizing field labels, names, and defaults:
|
|
|
234
234
|
|
|
235
235
|
#### StyleFields.tsx
|
|
236
236
|
|
|
237
|
-
Configurable props for variant
|
|
237
|
+
Configurable props for variant and icon position:
|
|
238
238
|
|
|
239
239
|
```tsx
|
|
240
240
|
<Button.StyleFields
|
|
241
241
|
buttonVariantLabel="Button variant"
|
|
242
242
|
buttonVariantName="buttonVariant"
|
|
243
243
|
buttonVariantDefault="primary"
|
|
244
|
+
buttonIconPositionLabel="Icon position"
|
|
245
|
+
buttonIconPositionName="buttonIconPosition"
|
|
246
|
+
buttonIconPositionDefault="right"
|
|
244
247
|
/>
|
|
245
248
|
```
|
|
246
249
|
|
|
247
250
|
**Fields:**
|
|
248
251
|
- `buttonVariant`: ChoiceField for selecting visual style (primary, secondary, tertiary)
|
|
252
|
+
- `buttonIconPosition`: ChoiceField for selecting icon placement (left, right). This field has a hardcoded visibility rule — it is only shown when the icon toggle is enabled (`iconComponentShowIcon === true`), which corresponds to the `BooleanField` id hardcoded in `Icon.ContentFields`.
|
|
249
253
|
|
|
250
254
|
### Module Usage Example
|
|
251
255
|
|
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
} from '@hubspot/cms-components/fields';
|
|
5
5
|
import { IconContentFieldsWithToggleProps } from '../Icon/types.js';
|
|
6
6
|
|
|
7
|
+
export type IconPositionHorizontal = 'left' | 'right';
|
|
8
|
+
|
|
7
9
|
// Base props shared by all variants
|
|
8
10
|
export type BaseButtonProps = {
|
|
9
11
|
variant?: 'primary' | 'secondary' | 'tertiary'; // !todo: not used atm but keeping for when we need to add variant system.
|
|
@@ -11,7 +13,7 @@ export type BaseButtonProps = {
|
|
|
11
13
|
style?: React.CSSProperties;
|
|
12
14
|
children?: React.ReactNode;
|
|
13
15
|
iconFieldPath?: string;
|
|
14
|
-
iconPosition?:
|
|
16
|
+
iconPosition?: IconPositionHorizontal;
|
|
15
17
|
iconSize?: number;
|
|
16
18
|
showIcon?: boolean;
|
|
17
19
|
iconPurpose?: 'SEMANTIC' | 'DECORATIVE';
|
|
@@ -56,6 +58,9 @@ export type StyleFieldsProps = {
|
|
|
56
58
|
buttonVariantLabel?: string;
|
|
57
59
|
buttonVariantName?: string;
|
|
58
60
|
buttonVariantDefault?: string;
|
|
61
|
+
buttonIconPositionLabel?: string;
|
|
62
|
+
buttonIconPositionName?: string;
|
|
63
|
+
buttonIconPositionDefault?: IconPositionHorizontal;
|
|
59
64
|
};
|
|
60
65
|
|
|
61
66
|
export type RenderWithIconProps = Pick<
|
|
@@ -9,12 +9,10 @@
|
|
|
9
9
|
align-items: var(--hscl-flex-alignItems, stretch);
|
|
10
10
|
align-content: var(--hscl-flex-alignContent, stretch);
|
|
11
11
|
gap: var(--hscl-flex-gap, 0);
|
|
12
|
-
padding: var(--hscl-flex-
|
|
13
|
-
padding-
|
|
14
|
-
|
|
15
|
-
margin: var(--hscl-flex-
|
|
16
|
-
margin-inline: var(--hscl-flex-marginInline);
|
|
17
|
-
margin-block: var(--hscl-flex-marginBlock);
|
|
12
|
+
padding-inline: var(--hscl-flex-paddingInline, 0);
|
|
13
|
+
padding-block: var(--hscl-flex-paddingBlock, 0);
|
|
14
|
+
margin-inline: var(--hscl-flex-marginInline, 0);
|
|
15
|
+
margin-block: var(--hscl-flex-marginBlock, 0);
|
|
18
16
|
max-width: var(--hscl-flex-maxWidth, 100%);
|
|
19
17
|
max-height: var(--hscl-flex-maxHeight, auto);
|
|
20
18
|
}
|
|
@@ -47,7 +47,7 @@ Flex/
|
|
|
47
47
|
maxHeight?: string; // Maximum height constraint
|
|
48
48
|
inline?: boolean; // Use inline-flex instead of flex (default: false)
|
|
49
49
|
className?: string; // Additional CSS classes
|
|
50
|
-
style?:
|
|
50
|
+
style?: CSSVariables; // Inline styles and CSS variable overrides
|
|
51
51
|
children?: React.ReactNode; // Child elements
|
|
52
52
|
}
|
|
53
53
|
```
|
|
@@ -169,12 +169,10 @@ The Flex component uses CSS variables for all styling properties:
|
|
|
169
169
|
- `--hscl-flex-alignItems`: Cross axis alignment (default: 'stretch')
|
|
170
170
|
- `--hscl-flex-alignContent`: Multi-line alignment (default: 'stretch')
|
|
171
171
|
- `--hscl-flex-gap`: Gap between items
|
|
172
|
-
- `--hscl-flex-
|
|
173
|
-
- `--hscl-flex-
|
|
174
|
-
- `--hscl-flex-
|
|
175
|
-
- `--hscl-flex-
|
|
176
|
-
- `--hscl-flex-marginInline`: Horizontal margin
|
|
177
|
-
- `--hscl-flex-marginBlock`: Vertical margin
|
|
172
|
+
- `--hscl-flex-paddingInline`: Horizontal padding (default: 0)
|
|
173
|
+
- `--hscl-flex-paddingBlock`: Vertical padding (default: 0)
|
|
174
|
+
- `--hscl-flex-marginInline`: Horizontal margin (default: 0)
|
|
175
|
+
- `--hscl-flex-marginBlock`: Vertical margin (default: 0)
|
|
178
176
|
- `--hscl-flex-maxWidth`: Maximum width (default: 100%)
|
|
179
177
|
- `--hscl-flex-maxHeight`: Maximum height (default: auto)
|
|
180
178
|
|
|
@@ -48,12 +48,8 @@ export type FlexProps = {
|
|
|
48
48
|
alignItems?: FlexAlignItems;
|
|
49
49
|
alignContent?: FlexAlignContent;
|
|
50
50
|
gap?: string;
|
|
51
|
-
rowGap?: string;
|
|
52
|
-
columnGap?: string;
|
|
53
|
-
padding?: string;
|
|
54
51
|
paddingInline?: string;
|
|
55
52
|
paddingBlock?: string;
|
|
56
|
-
margin?: string;
|
|
57
53
|
marginInline?: string;
|
|
58
54
|
marginBlock?: string;
|
|
59
55
|
inline?: boolean;
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
justify-content: center;
|
|
5
5
|
fill: var(--hscl-icon-fill);
|
|
6
6
|
stroke: var(--hscl-icon-stroke);
|
|
7
|
-
width: var(--hscl-icon-
|
|
8
|
-
height: var(--hscl-icon-
|
|
7
|
+
width: var(--hscl-icon-size);
|
|
8
|
+
height: var(--hscl-icon-size);
|
|
9
9
|
}
|
|
@@ -8,7 +8,7 @@ import { IconProps } from './types.js';
|
|
|
8
8
|
const IconComponent = ({
|
|
9
9
|
fieldPath,
|
|
10
10
|
showIcon = true,
|
|
11
|
-
|
|
11
|
+
size = 12,
|
|
12
12
|
className = '',
|
|
13
13
|
style = {},
|
|
14
14
|
purpose = 'DECORATIVE',
|
|
@@ -21,13 +21,14 @@ const IconComponent = ({
|
|
|
21
21
|
const combinedClasses = cx(defaultClasses, className);
|
|
22
22
|
|
|
23
23
|
const cssVariables: CSSVariables = {
|
|
24
|
+
'--hscl-icon-size': `${size}px`,
|
|
24
25
|
...(fill && { '--hscl-icon-fill': fill }),
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
return (
|
|
28
29
|
<CMSIcon
|
|
29
30
|
fieldPath={fieldPath}
|
|
30
|
-
height={
|
|
31
|
+
height={size}
|
|
31
32
|
className={combinedClasses}
|
|
32
33
|
style={{ ...cssVariables, ...style }}
|
|
33
34
|
purpose={purpose}
|
|
@@ -35,7 +35,7 @@ Icon/
|
|
|
35
35
|
```tsx
|
|
36
36
|
{
|
|
37
37
|
fieldPath?: string; // Path to icon in HubSpot fields
|
|
38
|
-
|
|
38
|
+
size?: number; // Icon size in pixels, sets both width and height (default: 12)
|
|
39
39
|
fill?: string; // Icon fill color (overrides CSS variable)
|
|
40
40
|
className?: string; // Additional CSS classes
|
|
41
41
|
style?: React.CSSProperties; // Inline styles (including CSS variables)
|
|
@@ -54,7 +54,7 @@ import Icon from '@hubspot/cms-component-library/Icon';
|
|
|
54
54
|
|
|
55
55
|
<Icon
|
|
56
56
|
fieldPath="icon"
|
|
57
|
-
|
|
57
|
+
size={24}
|
|
58
58
|
/>
|
|
59
59
|
```
|
|
60
60
|
|
|
@@ -63,7 +63,7 @@ import Icon from '@hubspot/cms-component-library/Icon';
|
|
|
63
63
|
```tsx
|
|
64
64
|
<Icon
|
|
65
65
|
fieldPath="icon"
|
|
66
|
-
|
|
66
|
+
size={24}
|
|
67
67
|
purpose="SEMANTIC"
|
|
68
68
|
title="Download file"
|
|
69
69
|
/>
|
|
@@ -74,7 +74,7 @@ import Icon from '@hubspot/cms-component-library/Icon';
|
|
|
74
74
|
```tsx
|
|
75
75
|
<Icon
|
|
76
76
|
fieldPath="icon"
|
|
77
|
-
|
|
77
|
+
size={32}
|
|
78
78
|
fill="#FF7A59"
|
|
79
79
|
/>
|
|
80
80
|
```
|
|
@@ -84,7 +84,7 @@ import Icon from '@hubspot/cms-component-library/Icon';
|
|
|
84
84
|
```tsx
|
|
85
85
|
<Icon
|
|
86
86
|
fieldPath="icon"
|
|
87
|
-
|
|
87
|
+
size={20}
|
|
88
88
|
showIcon={shouldShowIcon}
|
|
89
89
|
/>
|
|
90
90
|
```
|
|
@@ -128,7 +128,7 @@ export default function IconModule({ fieldValues }) {
|
|
|
128
128
|
return (
|
|
129
129
|
<Icon
|
|
130
130
|
fieldPath="icon"
|
|
131
|
-
|
|
131
|
+
size={fieldValues.iconSize || 24}
|
|
132
132
|
showIcon={fieldValues.showIcon}
|
|
133
133
|
purpose="DECORATIVE"
|
|
134
134
|
/>
|
|
@@ -159,6 +159,7 @@ The Icon component uses CSS variables for theming and customization:
|
|
|
159
159
|
|
|
160
160
|
**Base Styles:**
|
|
161
161
|
- `--hscl-icon-fill`: Icon fill color (default: currentColor)
|
|
162
|
+
- `--hscl-icon-size`: Icon width and height (set automatically from the `size` prop)
|
|
162
163
|
|
|
163
164
|
|
|
164
165
|
## Accessibility
|
|
@@ -25,7 +25,7 @@ type Story = StoryObj<typeof meta>;
|
|
|
25
25
|
export const Default: Story = {
|
|
26
26
|
args: {
|
|
27
27
|
fieldPath: 'icon',
|
|
28
|
-
|
|
28
|
+
size: 24,
|
|
29
29
|
showIcon: true,
|
|
30
30
|
purpose: 'DECORATIVE',
|
|
31
31
|
},
|
|
@@ -37,27 +37,27 @@ export const IconSizes: Story = {
|
|
|
37
37
|
<SBContainer flex direction="row" gap="large" alignItems="center">
|
|
38
38
|
<SBContainer addBackground flex alignItems="center">
|
|
39
39
|
<h4>12px (default)</h4>
|
|
40
|
-
<Icon fieldPath="icon"
|
|
40
|
+
<Icon fieldPath="icon" size={12} />
|
|
41
41
|
</SBContainer>
|
|
42
42
|
|
|
43
43
|
<SBContainer addBackground flex alignItems="center">
|
|
44
44
|
<h4>16px</h4>
|
|
45
|
-
<Icon fieldPath="icon"
|
|
45
|
+
<Icon fieldPath="icon" size={16} />
|
|
46
46
|
</SBContainer>
|
|
47
47
|
|
|
48
48
|
<SBContainer addBackground flex alignItems="center">
|
|
49
49
|
<h4>24px</h4>
|
|
50
|
-
<Icon fieldPath="icon"
|
|
50
|
+
<Icon fieldPath="icon" size={24} />
|
|
51
51
|
</SBContainer>
|
|
52
52
|
|
|
53
53
|
<SBContainer addBackground flex alignItems="center">
|
|
54
54
|
<h4>32px</h4>
|
|
55
|
-
<Icon fieldPath="icon"
|
|
55
|
+
<Icon fieldPath="icon" size={32} />
|
|
56
56
|
</SBContainer>
|
|
57
57
|
|
|
58
58
|
<SBContainer addBackground flex alignItems="center">
|
|
59
59
|
<h4>48px</h4>
|
|
60
|
-
<Icon fieldPath="icon"
|
|
60
|
+
<Icon fieldPath="icon" size={48} />
|
|
61
61
|
</SBContainer>
|
|
62
62
|
</SBContainer>
|
|
63
63
|
),
|
|
@@ -69,34 +69,34 @@ export const Colors: Story = {
|
|
|
69
69
|
<SBContainer flex direction="row" gap="large" alignItems="center">
|
|
70
70
|
<SBContainer addBackground flex alignItems="center">
|
|
71
71
|
<h4>Default (currentColor)</h4>
|
|
72
|
-
<Icon fieldPath="icon"
|
|
72
|
+
<Icon fieldPath="icon" size={32} />
|
|
73
73
|
</SBContainer>
|
|
74
74
|
|
|
75
75
|
<SBContainer addBackground flex alignItems="center">
|
|
76
76
|
<h4>Blue Fill</h4>
|
|
77
77
|
<div className={styles.blueFill}>
|
|
78
|
-
<Icon fieldPath="icon"
|
|
78
|
+
<Icon fieldPath="icon" size={32} />
|
|
79
79
|
</div>
|
|
80
80
|
</SBContainer>
|
|
81
81
|
|
|
82
82
|
<SBContainer addBackground flex alignItems="center">
|
|
83
83
|
<h4>Red Fill</h4>
|
|
84
84
|
<div className={styles.redFill}>
|
|
85
|
-
<Icon fieldPath="icon"
|
|
85
|
+
<Icon fieldPath="icon" size={32} />
|
|
86
86
|
</div>
|
|
87
87
|
</SBContainer>
|
|
88
88
|
|
|
89
89
|
<SBContainer addBackground flex alignItems="center">
|
|
90
90
|
<h4>Green Fill</h4>
|
|
91
91
|
<div className={styles.greenFill}>
|
|
92
|
-
<Icon fieldPath="icon"
|
|
92
|
+
<Icon fieldPath="icon" size={32} />
|
|
93
93
|
</div>
|
|
94
94
|
</SBContainer>
|
|
95
95
|
|
|
96
96
|
<SBContainer addBackground flex alignItems="center">
|
|
97
97
|
<h4>Custom Stroke</h4>
|
|
98
98
|
<div className={styles.customStroke}>
|
|
99
|
-
<Icon fieldPath="icon"
|
|
99
|
+
<Icon fieldPath="icon" size={32} />
|
|
100
100
|
</div>
|
|
101
101
|
</SBContainer>
|
|
102
102
|
</SBContainer>
|
|
@@ -7,7 +7,7 @@ This document outlines CSS variable naming conventions, styling patterns, and CS
|
|
|
7
7
|
**Pattern:** `--hscl-componentName-[elementName]-cssProperty-[state]`
|
|
8
8
|
|
|
9
9
|
- **Prefix:** Always start with `--hscl-` (HubSpot Component Library)
|
|
10
|
-
- **Component name:** Lowercase component name in camelCase, with name taken from the index.tsx file (e.g., `button`, `
|
|
10
|
+
- **Component name:** Lowercase component name in camelCase, with name taken from the index.tsx file (e.g., `button`, `icon`, `divider`, `image`, `accordion`, `card`)
|
|
11
11
|
- **Element name (optional):** For sub-elements within a component, specify the element name in camelCase (e.g., `icon`, `body`, `title`, `header`, `overlay`, `submenu`)
|
|
12
12
|
- Omit for properties that apply to the main component element itself
|
|
13
13
|
- Include for properties that apply to specific sub-elements
|
|
@@ -19,8 +19,6 @@ This document outlines CSS variable naming conventions, styling patterns, and CS
|
|
|
19
19
|
--hscl-button-backgroundColor
|
|
20
20
|
--hscl-button-backgroundColor-hover
|
|
21
21
|
--hscl-button-backgroundColor-focus
|
|
22
|
-
--hscl-heading-fontSize
|
|
23
|
-
--hscl-heading-textAlign
|
|
24
22
|
--hscl-divider-borderColor
|
|
25
23
|
--hscl-icon-fill
|
|
26
24
|
--hscl-card-padding
|
|
@@ -47,12 +45,12 @@ This document outlines CSS variable naming conventions, styling patterns, and CS
|
|
|
47
45
|
|
|
48
46
|
**Nested/Dynamic Variables:**
|
|
49
47
|
```typescript
|
|
50
|
-
//
|
|
51
|
-
'--hscl-
|
|
52
|
-
'--hscl-
|
|
48
|
+
// Components can use template variables to dynamically reference nested variables
|
|
49
|
+
'--hscl-component-font': `var(--hscl-component-${variantValue}-font)`
|
|
50
|
+
'--hscl-component-fontSize': `var(--hscl-component-${variantValue}-fontSize)`
|
|
53
51
|
```
|
|
54
52
|
|
|
55
|
-
**Note:** When using dynamic variants
|
|
53
|
+
**Note:** When using dynamic variants, use numbers without underscores (e.g., `variant1` not `variant_1`).
|
|
56
54
|
|
|
57
55
|
## CSS Variables Application
|
|
58
56
|
|
|
@@ -105,15 +103,6 @@ const elementStyle: CSSVariables = {
|
|
|
105
103
|
```typescript
|
|
106
104
|
import type { CSSVariables } from '../utils/types.js';
|
|
107
105
|
|
|
108
|
-
// Heading - dynamic variable references
|
|
109
|
-
const cssVariables: CSSVariables = {
|
|
110
|
-
'--hscl-heading-font': `var(--hscl-heading-${displayAsValue}-font)`,
|
|
111
|
-
'--hscl-heading-fontSize': `var(--hscl-heading-${displayAsValue}-fontSize)`,
|
|
112
|
-
...(alignment && {
|
|
113
|
-
'--hscl-heading-textAlign': alignment.toLowerCase(),
|
|
114
|
-
}),
|
|
115
|
-
};
|
|
116
|
-
|
|
117
106
|
// Divider - direct values with units
|
|
118
107
|
const cssVariables: CSSVariables = {
|
|
119
108
|
'--hscl-divider-alignment': getAlignmentCSSVar(alignment),
|
|
@@ -235,8 +224,8 @@ Variables can reference other variables for dynamic behavior:
|
|
|
235
224
|
|
|
236
225
|
```typescript
|
|
237
226
|
const cssVariables = {
|
|
238
|
-
'--hscl-
|
|
239
|
-
'--hscl-
|
|
227
|
+
'--hscl-component-font': `var(--hscl-component-${variantValue}-font)`,
|
|
228
|
+
'--hscl-component-fontSize': `var(--hscl-component-${variantValue}-fontSize)`,
|
|
240
229
|
};
|
|
241
230
|
```
|
|
242
231
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cms-component-library",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "HubSpot CMS React component library for building CMS modules",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"exports": {
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"url": "git@git.hubteam.com:HubSpot/cms-component-library.git"
|
|
17
17
|
},
|
|
18
18
|
"publishConfig": {
|
|
19
|
-
"access": "public"
|
|
19
|
+
"access": "public",
|
|
20
|
+
"registry": "https://registry.npmjs.org"
|
|
20
21
|
},
|
|
21
22
|
"type": "module",
|
|
22
23
|
"dependencies": {
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { ChoiceField, TextField } from '@hubspot/cms-components/fields';
|
|
2
|
-
import type { ContentFieldsProps } from './types.js';
|
|
3
|
-
|
|
4
|
-
const ContentFields = ({
|
|
5
|
-
headingTextLabel = 'Heading text',
|
|
6
|
-
headingTextName = 'headingText',
|
|
7
|
-
headingTextDefault = 'Heading Text',
|
|
8
|
-
headingLevelLabel = 'Heading level',
|
|
9
|
-
headingLevelName = 'headingLevel',
|
|
10
|
-
headingLevelDefault = 'h1',
|
|
11
|
-
}: ContentFieldsProps) => {
|
|
12
|
-
return (
|
|
13
|
-
<>
|
|
14
|
-
<TextField
|
|
15
|
-
label={headingTextLabel}
|
|
16
|
-
name={headingTextName}
|
|
17
|
-
default={headingTextDefault}
|
|
18
|
-
/>
|
|
19
|
-
<ChoiceField
|
|
20
|
-
label={headingLevelLabel}
|
|
21
|
-
name={headingLevelName}
|
|
22
|
-
choices={[
|
|
23
|
-
['h1', 'h1'],
|
|
24
|
-
['h2', 'h2'],
|
|
25
|
-
['h3', 'h3'],
|
|
26
|
-
['h4', 'h4'],
|
|
27
|
-
['h5', 'h5'],
|
|
28
|
-
['h6', 'h6'],
|
|
29
|
-
]}
|
|
30
|
-
required={true}
|
|
31
|
-
default={headingLevelDefault}
|
|
32
|
-
/>
|
|
33
|
-
</>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export default ContentFields;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { AlignmentField, ChoiceField } from '@hubspot/cms-components/fields';
|
|
2
|
-
import type { StyleFieldsProps } from './types.js';
|
|
3
|
-
|
|
4
|
-
const StyleFields = ({
|
|
5
|
-
textAlignLabel = 'Heading alignment',
|
|
6
|
-
textAlignName = 'headingTextAlign',
|
|
7
|
-
textAlignDefault = 'LEFT',
|
|
8
|
-
displayAsLabel = 'Display as',
|
|
9
|
-
displayAsName = 'headingDisplayAs',
|
|
10
|
-
displayAsDefault = 'h1',
|
|
11
|
-
}: StyleFieldsProps) => {
|
|
12
|
-
return (
|
|
13
|
-
<>
|
|
14
|
-
<AlignmentField
|
|
15
|
-
label={textAlignLabel}
|
|
16
|
-
name={textAlignName}
|
|
17
|
-
alignmentDirection="HORIZONTAL"
|
|
18
|
-
default={{ horizontal_align: textAlignDefault }}
|
|
19
|
-
/>
|
|
20
|
-
<ChoiceField
|
|
21
|
-
label={displayAsLabel}
|
|
22
|
-
name={displayAsName}
|
|
23
|
-
choices={[
|
|
24
|
-
['h1', 'h1'],
|
|
25
|
-
['h2', 'h2'],
|
|
26
|
-
['h3', 'h3'],
|
|
27
|
-
['h4', 'h4'],
|
|
28
|
-
['h5', 'h5'],
|
|
29
|
-
['h6', 'h6'],
|
|
30
|
-
['display_1', 'Display 1'],
|
|
31
|
-
['display_2', 'Display 2'],
|
|
32
|
-
]}
|
|
33
|
-
required={true}
|
|
34
|
-
default={displayAsDefault}
|
|
35
|
-
/>
|
|
36
|
-
</>
|
|
37
|
-
);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export default StyleFields;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
.heading {
|
|
2
|
-
font-family: var(--hscl-heading-font);
|
|
3
|
-
font-size: var(--hscl-heading-fontSize);
|
|
4
|
-
font-style: var(--hscl-heading-fontStyle);
|
|
5
|
-
font-weight: var(--hscl-heading-fontWeight);
|
|
6
|
-
line-height: var(--hscl-heading-lineHeight);
|
|
7
|
-
margin-block: var(--hscl-heading-margin);
|
|
8
|
-
color: var(--hscl-heading-color);
|
|
9
|
-
text-align: var(--hscl-heading-textAlign);
|
|
10
|
-
}
|
|
11
|
-
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import styles from './index.module.scss';
|
|
2
|
-
import ContentFields from './ContentFields.js';
|
|
3
|
-
import StyleFields from './StyleFields.js';
|
|
4
|
-
import cx from '../utils/classname.js';
|
|
5
|
-
import type { CSSVariables } from '../utils/types.js';
|
|
6
|
-
import { HeadingProps } from './types.js';
|
|
7
|
-
|
|
8
|
-
const HeadingComponent = ({
|
|
9
|
-
headingLevel,
|
|
10
|
-
displayAs,
|
|
11
|
-
textAlign,
|
|
12
|
-
className = '',
|
|
13
|
-
style = {},
|
|
14
|
-
children = 'A clear and bold heading',
|
|
15
|
-
...rest
|
|
16
|
-
}: HeadingProps) => {
|
|
17
|
-
const HeadingLevel = headingLevel;
|
|
18
|
-
const displayAsValue = displayAs || headingLevel;
|
|
19
|
-
|
|
20
|
-
const cssVariables: CSSVariables = {
|
|
21
|
-
'--hscl-heading-font': `var(--hscl-heading-${displayAsValue}-font)`,
|
|
22
|
-
'--hscl-heading-fontSize': `var(--hscl-heading-${displayAsValue}-fontSize)`,
|
|
23
|
-
'--hscl-heading-fontStyle': `var(--hscl-heading-${displayAsValue}-fontStyle)`,
|
|
24
|
-
'--hscl-heading-fontWeight': `var(--hscl-heading-${displayAsValue}-fontWeight)`,
|
|
25
|
-
...(textAlign && {
|
|
26
|
-
'--hscl-heading-textAlign': textAlign.toLowerCase(),
|
|
27
|
-
}),
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const defaultClasses = cx(styles.heading, className);
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<HeadingLevel
|
|
34
|
-
className={defaultClasses}
|
|
35
|
-
style={{ ...cssVariables, ...style }}
|
|
36
|
-
{...rest}
|
|
37
|
-
>
|
|
38
|
-
{children}
|
|
39
|
-
</HeadingLevel>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
type HeadingComponentType = typeof HeadingComponent & {
|
|
44
|
-
ContentFields: typeof ContentFields;
|
|
45
|
-
StyleFields: typeof StyleFields;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const Heading = HeadingComponent as HeadingComponentType;
|
|
49
|
-
Heading.ContentFields = ContentFields;
|
|
50
|
-
Heading.StyleFields = StyleFields;
|
|
51
|
-
|
|
52
|
-
export default Heading;
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# Heading Component
|
|
2
|
-
|
|
3
|
-
A semantic heading component that renders HTML heading elements (h1-h6) with flexible visual styling and alignment controls, allowing the semantic level to differ from the visual appearance.
|
|
4
|
-
|
|
5
|
-
## Import path
|
|
6
|
-
```tsx
|
|
7
|
-
import Heading from '@hubspot/cms-component-library/Heading';
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
## Purpose
|
|
11
|
-
|
|
12
|
-
The Heading component provides proper semantic structure while maintaining visual design flexibility. It solves the common challenge where semantic HTML hierarchy (h1-h6) needs to differ from visual styling - for example, an h3 element styled to look like an h1. This separation of semantic meaning from visual presentation ensures both accessibility and design consistency.
|
|
13
|
-
|
|
14
|
-
## Component Structure
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
Heading/
|
|
18
|
-
├── index.tsx # Main component with render logic
|
|
19
|
-
├── types.ts # TypeScript type definitions
|
|
20
|
-
├── ContentFields.tsx # HubSpot field definitions for content
|
|
21
|
-
├── StyleFields.tsx # HubSpot field definitions for styling
|
|
22
|
-
├── index.module.scss # CSS module with design tokens
|
|
23
|
-
└── stories/
|
|
24
|
-
├── Heading.stories.tsx # Component usage examples
|
|
25
|
-
├── HeadingDecorator.tsx # Storybook decorator
|
|
26
|
-
└── HeadingDecorator.module.css # Decorator styles
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Props
|
|
30
|
-
|
|
31
|
-
```tsx
|
|
32
|
-
{
|
|
33
|
-
headingLevel: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; // Semantic HTML level (required)
|
|
34
|
-
displayAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'display_1' | 'display_2'; // Visual style (defaults to headingLevel)
|
|
35
|
-
textAlign?: 'LEFT' | 'CENTER' | 'RIGHT'; // Text alignment
|
|
36
|
-
className?: string; // Additional CSS classes
|
|
37
|
-
style?: React.CSSProperties; // Inline styles (including CSS variables)
|
|
38
|
-
children?: React.ReactNode; // Heading text content
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Usage Examples
|
|
43
|
-
|
|
44
|
-
### Basic Heading
|
|
45
|
-
|
|
46
|
-
```tsx
|
|
47
|
-
import Heading from '@hubspot/cms-component-library/Heading';
|
|
48
|
-
|
|
49
|
-
<Heading headingLevel="h1">
|
|
50
|
-
Welcome to Our Site
|
|
51
|
-
</Heading>
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Semantic vs Visual Styling
|
|
55
|
-
|
|
56
|
-
When you need a lower-level heading to look like a higher-level one:
|
|
57
|
-
|
|
58
|
-
```tsx
|
|
59
|
-
<Heading
|
|
60
|
-
headingLevel="h3" // Semantic: third-level heading
|
|
61
|
-
displayAs="h1" // Visual: styled like an h1
|
|
62
|
-
>
|
|
63
|
-
Section Title
|
|
64
|
-
</Heading>
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### With Text Alignment
|
|
68
|
-
|
|
69
|
-
```tsx
|
|
70
|
-
<Heading
|
|
71
|
-
headingLevel="h2"
|
|
72
|
-
textAlign="CENTER"
|
|
73
|
-
>
|
|
74
|
-
Centered Heading
|
|
75
|
-
</Heading>
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
## HubSpot CMS Integration
|
|
80
|
-
|
|
81
|
-
### Field Definitions
|
|
82
|
-
|
|
83
|
-
#### ContentFields.tsx
|
|
84
|
-
|
|
85
|
-
```tsx
|
|
86
|
-
<Heading.ContentFields
|
|
87
|
-
headingTextLabel="Heading text"
|
|
88
|
-
headingTextName="headingText"
|
|
89
|
-
headingTextDefault="Heading Text"
|
|
90
|
-
headingLevelLabel="Heading Level"
|
|
91
|
-
headingLevelName="headingLevel"
|
|
92
|
-
headingLevelDefault="h1"
|
|
93
|
-
/>
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**Fields:**
|
|
97
|
-
- `headingText`: TextField for heading content
|
|
98
|
-
- `headingLevel`: ChoiceField for semantic level (h1-h6)
|
|
99
|
-
|
|
100
|
-
#### StyleFields.tsx
|
|
101
|
-
|
|
102
|
-
```tsx
|
|
103
|
-
<Heading.StyleFields
|
|
104
|
-
textAlignLabel="Heading text align"
|
|
105
|
-
textAlignName="headingTextAlign"
|
|
106
|
-
textAlignDefault="LEFT"
|
|
107
|
-
displayAsLabel="Display as"
|
|
108
|
-
displayAsName="headingDisplayAs"
|
|
109
|
-
displayAsDefault="h1"
|
|
110
|
-
/>
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**Fields:**
|
|
114
|
-
- `headingTextAlign`: AlignmentField for text alignment
|
|
115
|
-
- `headingDisplayAs`: ChoiceField for visual style (h1-h6, display_1, display_2)
|
|
116
|
-
|
|
117
|
-
### Module Usage Example
|
|
118
|
-
|
|
119
|
-
```tsx
|
|
120
|
-
import Heading from '@hubspot/cms-component-library/Heading';
|
|
121
|
-
|
|
122
|
-
export default function HeroModule({ fieldValues }) {
|
|
123
|
-
return (
|
|
124
|
-
<Heading
|
|
125
|
-
headingLevel={fieldValues.headingLevel}
|
|
126
|
-
displayAs={fieldValues.headingDisplayAs}
|
|
127
|
-
textAlign={fieldValues.headingTextAlign?.horizontal_align}
|
|
128
|
-
>
|
|
129
|
-
{fieldValues.headingText}
|
|
130
|
-
</Heading>
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Styling
|
|
136
|
-
|
|
137
|
-
### CSS Variables
|
|
138
|
-
|
|
139
|
-
The Heading component uses CSS variables for theming and customization:
|
|
140
|
-
|
|
141
|
-
**Base Styles:**
|
|
142
|
-
- `--hscl-heading-font`: Font family
|
|
143
|
-
- `--hscl-heading-fontSize`: Font size (set by displayAs level)
|
|
144
|
-
- `--hscl-heading-fontStyle`: Font style (set by displayAs level)
|
|
145
|
-
- `--hscl-heading-fontWeight`: Font weight (set by displayAs level)
|
|
146
|
-
- `--hscl-heading-lineHeight`: Line height
|
|
147
|
-
- `--hscl-heading-margin`: Vertical margin (margin-block)
|
|
148
|
-
- `--hscl-heading-color`: Text color
|
|
149
|
-
- `--hscl-heading-textAlign`: Text alignment
|
|
150
|
-
|
|
151
|
-
**Level-specific Variables:**
|
|
152
|
-
Each heading level has its own design tokens:
|
|
153
|
-
- `--hscl-heading-h1-font`, `--hscl-heading-h1-fontSize`, etc.
|
|
154
|
-
- `--hscl-heading-h2-font`, `--hscl-heading-h2-fontSize`, etc.
|
|
155
|
-
- Through `--hscl-heading-h6-font`, `--hscl-heading-h6-fontSize`, etc.
|
|
156
|
-
- `--hscl-heading-display_1-font`, `--hscl-heading-display_1-fontSize`, etc.
|
|
157
|
-
- `--hscl-heading-display_2-font`, `--hscl-heading-display_2-fontSize`, etc.
|
|
158
|
-
|
|
159
|
-
## Accessibility
|
|
160
|
-
|
|
161
|
-
The Heading component follows accessibility best practices:
|
|
162
|
-
|
|
163
|
-
- **Semantic HTML**: Always renders the appropriate heading element (h1-h6) based on `headingLevel` for proper document structure
|
|
164
|
-
- **Visual Hierarchy Independence**: The `displayAs` prop allows visual styling to differ from semantic structure, ensuring flexibility without breaking accessibility
|
|
165
|
-
- **Proper Nesting**: Ensure headings follow logical order in your document (h1 → h2 → h3, etc.) regardless of visual styling
|
|
166
|
-
- **Screen Readers**: Screen readers announce the semantic level (`headingLevel`), not the visual style
|
|
167
|
-
- **Keyboard Navigation**: Native heading element support for keyboard navigation and focus management
|
|
168
|
-
|
|
169
|
-
## Best Practices
|
|
170
|
-
|
|
171
|
-
- **Follow semantic order**: Use headings in logical order (h1 for main title, h2 for sections, h3 for subsections, etc.)
|
|
172
|
-
- **One h1 per page**: Each page should have exactly one h1 element representing the main topic
|
|
173
|
-
- **Use displayAs for visual flexibility**: When you need a different visual style than the semantic level requires, use the `displayAs` prop
|
|
174
|
-
- **Don't skip levels**: Don't jump from h2 to h4; maintain proper hierarchy
|
|
175
|
-
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import Heading from '../index.js';
|
|
3
|
-
import { HeadingProps } from '../types.js';
|
|
4
|
-
import { withHeadingStyles } from './HeadingDecorator.js';
|
|
5
|
-
import { SBContainer } from '@sb-utils/SBContainer.js';
|
|
6
|
-
|
|
7
|
-
const meta: Meta<HeadingProps> = {
|
|
8
|
-
title: 'Component Library/Heading',
|
|
9
|
-
component: Heading,
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: 'centered',
|
|
12
|
-
docs: {
|
|
13
|
-
description: {
|
|
14
|
-
component: `The Heading component provides a flexible and accessible way to render semantic HTML headings (h1-h6) with customizable visual styles through the displayAs prop.`,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
decorators: [withHeadingStyles],
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default meta;
|
|
22
|
-
type Story = StoryObj<typeof meta>;
|
|
23
|
-
|
|
24
|
-
export const Default: Story = {
|
|
25
|
-
args: {
|
|
26
|
-
headingLevel: 'h2',
|
|
27
|
-
children: 'A clear and bold heading',
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const AllHeadingLevels: Story = {
|
|
32
|
-
name: 'All Heading Levels',
|
|
33
|
-
render: () => (
|
|
34
|
-
<SBContainer flex direction="column" gap="large">
|
|
35
|
-
<SBContainer addBackground>
|
|
36
|
-
<p>
|
|
37
|
-
Each heading level has different semantic meaning and default styling
|
|
38
|
-
</p>
|
|
39
|
-
<Heading headingLevel="h1">Heading Level 1</Heading>
|
|
40
|
-
<Heading headingLevel="h2">Heading Level 2</Heading>
|
|
41
|
-
<Heading headingLevel="h3">Heading Level 3</Heading>
|
|
42
|
-
<Heading headingLevel="h4">Heading Level 4</Heading>
|
|
43
|
-
<Heading headingLevel="h5">Heading Level 5</Heading>
|
|
44
|
-
<Heading headingLevel="h6">Heading Level 6</Heading>
|
|
45
|
-
</SBContainer>
|
|
46
|
-
</SBContainer>
|
|
47
|
-
),
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const TextAlignment: Story = {
|
|
51
|
-
name: 'Text Alignment',
|
|
52
|
-
render: () => (
|
|
53
|
-
<SBContainer flex direction="column" gap="large" minWidth="500px">
|
|
54
|
-
<SBContainer addBackground>
|
|
55
|
-
<Heading headingLevel="h2" textAlign="LEFT">
|
|
56
|
-
Left Aligned
|
|
57
|
-
</Heading>
|
|
58
|
-
</SBContainer>
|
|
59
|
-
<SBContainer addBackground>
|
|
60
|
-
<Heading headingLevel="h2" textAlign="CENTER">
|
|
61
|
-
Center Aligned
|
|
62
|
-
</Heading>
|
|
63
|
-
</SBContainer>
|
|
64
|
-
<SBContainer addBackground>
|
|
65
|
-
<Heading headingLevel="h2" textAlign="RIGHT">
|
|
66
|
-
Right Aligned
|
|
67
|
-
</Heading>
|
|
68
|
-
</SBContainer>
|
|
69
|
-
</SBContainer>
|
|
70
|
-
),
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export const LongText: Story = {
|
|
74
|
-
name: 'Long Text',
|
|
75
|
-
render: () => (
|
|
76
|
-
<SBContainer flex direction="column" gap="large" maxWidth="500px">
|
|
77
|
-
<SBContainer addBackground>
|
|
78
|
-
<h4>Long Heading Text</h4>
|
|
79
|
-
<p>Headings should handle long text gracefully</p>
|
|
80
|
-
<Heading headingLevel="h2">
|
|
81
|
-
This is a very long heading that demonstrates how the component
|
|
82
|
-
handles extensive text content that may wrap across multiple lines in
|
|
83
|
-
the layout
|
|
84
|
-
</Heading>
|
|
85
|
-
</SBContainer>
|
|
86
|
-
</SBContainer>
|
|
87
|
-
),
|
|
88
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
.decoratorContainer {
|
|
2
|
-
padding: 20px;
|
|
3
|
-
--hscl-heading-h1-font: Arial, sans-serif;
|
|
4
|
-
--hscl-heading-h1-fontSize: 48px;
|
|
5
|
-
--hscl-heading-h1-fontStyle: normal;
|
|
6
|
-
--hscl-heading-h1-fontWeight: 700;
|
|
7
|
-
--hscl-heading-h2-font: Arial, sans-serif;
|
|
8
|
-
--hscl-heading-h2-fontSize: 36px;
|
|
9
|
-
--hscl-heading-h2-fontStyle: normal;
|
|
10
|
-
--hscl-heading-h2-fontWeight: 600;
|
|
11
|
-
--hscl-heading-h3-font: Arial, sans-serif;
|
|
12
|
-
--hscl-heading-h3-fontSize: 28px;
|
|
13
|
-
--hscl-heading-h3-fontStyle: normal;
|
|
14
|
-
--hscl-heading-h3-fontWeight: 600;
|
|
15
|
-
--hscl-heading-h4-font: Arial, sans-serif;
|
|
16
|
-
--hscl-heading-h4-fontSize: 24px;
|
|
17
|
-
--hscl-heading-h4-fontStyle: normal;
|
|
18
|
-
--hscl-heading-h4-fontWeight: 500;
|
|
19
|
-
--hscl-heading-h5-font: Arial, sans-serif;
|
|
20
|
-
--hscl-heading-h5-fontSize: 20px;
|
|
21
|
-
--hscl-heading-h5-fontStyle: normal;
|
|
22
|
-
--hscl-heading-h5-fontWeight: 500;
|
|
23
|
-
--hscl-heading-h6-font: Arial, sans-serif;
|
|
24
|
-
--hscl-heading-h6-fontSize: 16px;
|
|
25
|
-
--hscl-heading-h6-fontStyle: normal;
|
|
26
|
-
--hscl-heading-h6-fontWeight: 500;
|
|
27
|
-
--hscl-heading-display_1-font: Arial, sans-serif;
|
|
28
|
-
--hscl-heading-display_1-fontSize: 72px;
|
|
29
|
-
--hscl-heading-display_1-fontStyle: normal;
|
|
30
|
-
--hscl-heading-display_1-fontWeight: 800;
|
|
31
|
-
--hscl-heading-display_2-font: Arial, sans-serif;
|
|
32
|
-
--hscl-heading-display_2-fontSize: 60px;
|
|
33
|
-
--hscl-heading-display_2-fontStyle: normal;
|
|
34
|
-
--hscl-heading-display_2-fontWeight: 800;
|
|
35
|
-
--hscl-heading-lineHeight: 1.2;
|
|
36
|
-
--hscl-heading-margin: 0;
|
|
37
|
-
--hscl-heading-color: #2d3e50;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.decoratorContainer h1,
|
|
41
|
-
.decoratorContainer h2,
|
|
42
|
-
.decoratorContainer h3,
|
|
43
|
-
.decoratorContainer h4,
|
|
44
|
-
.decoratorContainer h5,
|
|
45
|
-
.decoratorContainer h6 {
|
|
46
|
-
margin-bottom: 1rem;
|
|
47
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AlignmentFieldDefaults,
|
|
3
|
-
TextFieldDefaults,
|
|
4
|
-
} from '@hubspot/cms-components/fields';
|
|
5
|
-
|
|
6
|
-
export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
7
|
-
|
|
8
|
-
export type DisplayAs = HeadingLevel | 'display_1' | 'display_2';
|
|
9
|
-
|
|
10
|
-
export type HeadingProps = {
|
|
11
|
-
headingLevel: HeadingLevel;
|
|
12
|
-
displayAs?: DisplayAs;
|
|
13
|
-
textAlign?: (typeof AlignmentFieldDefaults)['horizontal_align'];
|
|
14
|
-
className?: string;
|
|
15
|
-
style?: React.CSSProperties;
|
|
16
|
-
children?: React.ReactNode;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type ContentFieldsProps = {
|
|
20
|
-
headingTextLabel?: string;
|
|
21
|
-
headingTextName?: string;
|
|
22
|
-
headingTextDefault?: typeof TextFieldDefaults;
|
|
23
|
-
headingLevelLabel?: string;
|
|
24
|
-
headingLevelName?: string;
|
|
25
|
-
headingLevelDefault?: HeadingLevel;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export type StyleFieldsProps = {
|
|
29
|
-
textAlignLabel?: string;
|
|
30
|
-
textAlignName?: string;
|
|
31
|
-
textAlignDefault?: (typeof AlignmentFieldDefaults)['horizontal_align'];
|
|
32
|
-
displayAsLabel?: string;
|
|
33
|
-
displayAsName?: string;
|
|
34
|
-
displayAsDefault?: DisplayAs;
|
|
35
|
-
};
|