@hubspot/cms-component-library 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/components/componentLibrary/Accordion/AccordionContent/ContentFields.tsx +6 -6
  2. package/components/componentLibrary/Accordion/AccordionContent/index.tsx +3 -1
  3. package/components/componentLibrary/Accordion/AccordionContent/types.ts +2 -3
  4. package/components/componentLibrary/Accordion/AccordionTitle/AccordionTitleBase.tsx +45 -0
  5. package/components/componentLibrary/Accordion/AccordionTitle/ContentFields.tsx +8 -3
  6. package/components/componentLibrary/Accordion/AccordionTitle/index.tsx +18 -25
  7. package/components/componentLibrary/Accordion/AccordionTitle/islands/AccordionTitleIsland.tsx +29 -0
  8. package/components/componentLibrary/Accordion/AccordionTitle/types.ts +1 -0
  9. package/components/componentLibrary/Accordion/llm.txt +20 -13
  10. package/components/componentLibrary/Button/StyleFields.tsx +8 -8
  11. package/components/componentLibrary/Button/index.module.scss +24 -27
  12. package/components/componentLibrary/Button/index.tsx +4 -4
  13. package/components/componentLibrary/Button/llm.txt +51 -64
  14. package/components/componentLibrary/Button/stories/Button.AsButton.stories.tsx +2 -2
  15. package/components/componentLibrary/Button/stories/Button.AsLink.stories.tsx +2 -2
  16. package/components/componentLibrary/Button/stories/ButtonDecorator.module.scss +19 -23
  17. package/components/componentLibrary/Button/types.ts +2 -2
  18. package/components/componentLibrary/Card/StyleFields.tsx +9 -14
  19. package/components/componentLibrary/Card/index.module.scss +7 -7
  20. package/components/componentLibrary/Card/index.tsx +8 -13
  21. package/components/componentLibrary/Card/llm.txt +22 -43
  22. package/components/componentLibrary/Card/stories/Card.stories.tsx +28 -20
  23. package/components/componentLibrary/Card/stories/CardDecorator.module.scss +28 -5
  24. package/components/componentLibrary/Card/types.ts +8 -5
  25. package/components/componentLibrary/Form/StyleFields.tsx +19 -0
  26. package/components/componentLibrary/Form/index.tsx +7 -1
  27. package/components/componentLibrary/Form/islands/FormIsland.tsx +3 -1
  28. package/components/componentLibrary/Form/islands/LegacyFormIsland.tsx +2 -1
  29. package/components/componentLibrary/Form/islands/legacyForm.module.css +251 -0
  30. package/components/componentLibrary/Form/islands/v4Form.module.css +95 -0
  31. package/components/componentLibrary/Form/llm.txt +184 -0
  32. package/components/componentLibrary/Form/types.ts +6 -0
  33. package/components/componentLibrary/Link/ContentFields.tsx +11 -3
  34. package/components/componentLibrary/Link/llm.txt +13 -0
  35. package/components/componentLibrary/Link/types.ts +6 -4
  36. package/components/componentLibrary/Logo/ContentFields.tsx +25 -0
  37. package/components/componentLibrary/Logo/index.tsx +13 -4
  38. package/components/componentLibrary/Logo/types.tsx +15 -0
  39. package/components/componentLibrary/Video/ContentFields.tsx +112 -0
  40. package/components/componentLibrary/Video/StyleFields.tsx +19 -0
  41. package/components/componentLibrary/Video/index.tsx +47 -0
  42. package/components/componentLibrary/Video/islands/HSVideoIsland.tsx +53 -0
  43. package/components/componentLibrary/Video/serverUtils.ts +41 -0
  44. package/components/componentLibrary/Video/types.ts +74 -0
  45. package/components/componentLibrary/_patterns/README.md +11 -7
  46. package/components/componentLibrary/_patterns/checklist-and-examples.md +8 -0
  47. package/components/componentLibrary/_patterns/component-structure.md +5 -1
  48. package/components/componentLibrary/_patterns/field-patterns.md +65 -0
  49. package/components/componentLibrary/_patterns/island-patterns.md +136 -0
  50. package/components/componentLibrary/utils/index.ts +1 -0
  51. package/package.json +4 -3
@@ -37,7 +37,7 @@ Button/
37
37
  **Base Props (shared by both types):**
38
38
  ```tsx
39
39
  {
40
- variant?: 'primary' | 'secondary' | 'tertiary'; // Visual style variant
40
+ variant?: 'primaryButton' | 'secondaryButton' | 'tertiaryButton' | 'accentButton'; // Visual style variant (connected to theme settings)
41
41
  className?: string; // Additional CSS classes
42
42
  style?: React.CSSProperties; // Inline styles
43
43
  children?: React.ReactNode; // Button text/content
@@ -108,7 +108,7 @@ import { Island } from '@hubspot/cms-components'
108
108
  ```tsx
109
109
  <Button
110
110
  buttonType="link"
111
- variant="primary"
111
+ variant="primaryButton"
112
112
  href="https://www.hubspot.com"
113
113
  target="_self"
114
114
  >
@@ -121,7 +121,7 @@ import { Island } from '@hubspot/cms-components'
121
121
  ```tsx
122
122
  <Button
123
123
  buttonType="link"
124
- variant="primary"
124
+ variant="primaryButton"
125
125
  href="https://www.hubspot.com"
126
126
  target="_blank"
127
127
  rel="noopener noreferrer"
@@ -135,7 +135,7 @@ import { Island } from '@hubspot/cms-components'
135
135
  ```tsx
136
136
  <Button
137
137
  buttonType="button"
138
- variant="primary"
138
+ variant="primaryButton"
139
139
  onClick={handleClick}
140
140
  showIcon={true}
141
141
  iconFieldPath="icon"
@@ -152,7 +152,7 @@ import { Island } from '@hubspot/cms-components'
152
152
  ```tsx
153
153
  <Button
154
154
  buttonType="link"
155
- variant="secondary"
155
+ variant="secondaryButton"
156
156
  href="/back"
157
157
  showIcon={true}
158
158
  iconFieldPath="icon"
@@ -170,7 +170,7 @@ import { Island } from '@hubspot/cms-components'
170
170
  ```tsx
171
171
  <Button
172
172
  buttonType="button"
173
- variant="primary"
173
+ variant="primaryButton"
174
174
  disabled={true}
175
175
  onClick={handleClick}
176
176
  >
@@ -183,7 +183,7 @@ import { Island } from '@hubspot/cms-components'
183
183
  ```tsx
184
184
  <Button
185
185
  buttonType="link"
186
- variant="primary"
186
+ variant="primaryButton"
187
187
  href="/custom"
188
188
  className="custom-button-class"
189
189
  style={{ maxWidth: '300px' }}
@@ -240,7 +240,7 @@ Configurable props for variant and icon position:
240
240
  <Button.StyleFields
241
241
  buttonVariantLabel="Button variant"
242
242
  buttonVariantName="buttonVariant"
243
- buttonVariantDefault="primary"
243
+ buttonVariantDefault={{ variant_name: 'primaryButton' }}
244
244
  buttonIconPositionLabel="Icon position"
245
245
  buttonIconPositionName="buttonIconPosition"
246
246
  buttonIconPositionDefault="right"
@@ -248,7 +248,7 @@ Configurable props for variant and icon position:
248
248
  ```
249
249
 
250
250
  **Fields:**
251
- - `buttonVariant`: ChoiceField for selecting visual style (primary, secondary, tertiary)
251
+ - `buttonVariant`: VariantSelectionField connected to theme settings (primaryButton, secondaryButton, tertiaryButton, accentButton)
252
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`.
253
253
 
254
254
  ### Module Usage Example
@@ -276,57 +276,44 @@ export default function CTAModule({ fieldValues }) {
276
276
 
277
277
  ## Styling
278
278
 
279
- ### CSS Variables
280
-
281
- The Button component uses CSS variables for theming and customization:
282
-
283
- **Base Styles:**
284
- - `--hscl-button-gap`: Space between text and icon (default: 8px)
285
- - `--hscl-button-backgroundColor`: Background color
286
- - `--hscl-button-color`: Text color
287
- - `--hscl-button-paddingBlock`: Vertical padding
288
- - `--hscl-button-paddingInline`: Horizontal padding
289
- - `--hscl-button-borderRadius`: Border radius
290
- - `--hscl-button-borderWidth`: Border width
291
- - `--hscl-button-borderColor`: Border color
292
- - `--hscl-button-fontSize`: Font size
293
- - `--hscl-button-fontWeight`: Font weight
294
-
295
- **Hover States:**
296
- - `--hscl-button-backgroundColor-hover`: Hover background color
297
- - `--hscl-button-color-hover`: Hover text color
298
- - `--hscl-button-borderWidth-hover`: Hover border width
299
- - `--hscl-button-borderColor-hover`: Hover border color
300
-
301
- **Focus States:**
302
- - `--hscl-button-backgroundColor-focus`: Focus background color
303
- - `--hscl-button-color-focus`: Focus text color
304
- - `--hscl-button-borderWidth-focus`: Focus border width
305
- - `--hscl-button-borderColor-focus`: Focus border color
306
- - `--hscl-button-outlineWidth-focus`: Focus outline width
307
- - `--hscl-button-outlineColor-focus`: Focus outline color
308
- - `--hscl-button-outlineOffset-focus`: Focus outline offset
309
-
310
- **Icon:**
311
- - `--hscl-button-icon-fill`: Icon fill color
312
-
313
- ### Custom Styling Example
279
+ ### Theme CSS Variables
314
280
 
315
- ```tsx
316
- <Button
317
- buttonType="button"
318
- variant="primary"
319
- style={{
320
- '--hscl-button-backgroundColor': '#FF7A59',
321
- '--hscl-button-color': '#FFFFFF',
322
- '--hscl-button-paddingBlock': '12px',
323
- '--hscl-button-paddingInline': '24px',
324
- '--hscl-button-borderRadius': '8px',
325
- }}
326
- >
327
- Custom Colors
328
- </Button>
329
- ```
281
+ The Button component is themed via `--hs-button-*` CSS variables, which are provided by the theme settings variant system (scoped via the variant prop and `data-buttons-variant` attribute).
282
+
283
+ **Base Styles (from theme):**
284
+ - `--hs-button-backgroundColor`: Background color
285
+ - `--hs-button-color`: Text color
286
+ - `--hs-button-borderRadius`: Border radius
287
+ - `--hs-button-border`: Border shorthand
288
+ - `--hs-button-fontSize`: Font size
289
+ - `--hs-button-fontFamily`: Font family
290
+ - `--hs-button-fontStyle`: Font style
291
+ - `--hs-button-fontWeight`: Font weight
292
+ - `--hs-button-textDecoration`: Text decoration
293
+
294
+ **Hover States (from theme):**
295
+ - `--hs-button-backgroundColor-hover`: Hover background (falls back to base)
296
+ - `--hs-button-color-hover`: Hover text color (falls back to base)
297
+ - `--hs-button-border-hover`: Hover border (falls back to base)
298
+
299
+ **Focus States (from theme):**
300
+ - `--hs-button-backgroundColor-focus`: Focus background (falls back to base)
301
+ - `--hs-button-color-focus`: Focus text color (falls back to base)
302
+ - `--hs-button-border-focus`: Focus border (falls back to base)
303
+
304
+ **Active States (from theme):**
305
+ - `--hs-button-backgroundColor-active`: Active background (falls back to base)
306
+ - `--hs-button-color-active`: Active text color (falls back to base)
307
+ - `--hs-button-border-active`: Active border (falls back to base)
308
+
309
+ ### Hardcoded Layout Values
310
+
311
+ The following properties use fixed values and are not configurable via CSS variables:
312
+
313
+ - **Gap:** 8px (space between text and icon)
314
+ - **Padding:** 12px vertical, 24px horizontal
315
+ - **Focus outline:** 2px solid currentColor, offset 2px
316
+ - **Icon fill:** currentColor
330
317
 
331
318
  ## Accessibility
332
319
 
@@ -359,7 +346,7 @@ The Button component follows accessibility best practices:
359
346
  - **Icon purpose**: Use `SEMANTIC` when the icon adds meaning, `DECORATIVE` when it's purely visual
360
347
  - **Disabled state**: Only use with `buttonType="button"`, not applicable to links
361
348
  - **CSS Variables**: Override design tokens using CSS variables rather than hardcoding values
362
- - **Variant system**: Currently variants are passed as props but full theming implementation is pending
349
+ - **Variant system**: Variants are connected to theme settings via `VariantSelectionField` and `data-variant-name` attribute. CSS variables are scoped automatically by the ContentUILib variant system.
363
350
 
364
351
  ## Common Patterns
365
352
 
@@ -368,7 +355,7 @@ The Button component follows accessibility best practices:
368
355
  ```tsx
369
356
  <Button
370
357
  buttonType="link"
371
- variant="primary"
358
+ variant="primaryButton"
372
359
  href="/signup"
373
360
  showIcon={true}
374
361
  iconFieldPath="icon"
@@ -383,7 +370,7 @@ The Button component follows accessibility best practices:
383
370
  ```tsx
384
371
  <Button
385
372
  buttonType="button"
386
- variant="primary"
373
+ variant="primaryButton"
387
374
  onClick={handleSubmit}
388
375
  disabled={isSubmitting}
389
376
  >
@@ -396,7 +383,7 @@ The Button component follows accessibility best practices:
396
383
  ```tsx
397
384
  <Button
398
385
  buttonType="link"
399
- variant="secondary"
386
+ variant="secondaryButton"
400
387
  href="/dashboard"
401
388
  showIcon={true}
402
389
  iconFieldPath="icon"
@@ -411,7 +398,7 @@ The Button component follows accessibility best practices:
411
398
  ```tsx
412
399
  <Button
413
400
  buttonType="link"
414
- variant="tertiary"
401
+ variant="tertiaryButton"
415
402
  href="https://docs.hubspot.com"
416
403
  target="_blank"
417
404
  rel="noopener noreferrer"
@@ -26,7 +26,7 @@ type Story = StoryObj<typeof meta>;
26
26
 
27
27
  export const Default: Story = {
28
28
  args: {
29
- variant: 'primary',
29
+ variant: 'primaryButton',
30
30
  children: 'Click me',
31
31
  onClick: () => alert('Button clicked!'),
32
32
  },
@@ -34,7 +34,7 @@ export const Default: Story = {
34
34
 
35
35
  export const WithIcon: Story = {
36
36
  args: {
37
- variant: 'primary',
37
+ variant: 'primaryButton',
38
38
  children: 'Click me',
39
39
  onClick: () => alert('Button clicked!'),
40
40
  showIcon: true,
@@ -26,7 +26,7 @@ type Story = StoryObj<typeof meta>;
26
26
 
27
27
  export const Default: Story = {
28
28
  args: {
29
- variant: 'primary',
29
+ variant: 'primaryButton',
30
30
  children: 'Click me',
31
31
  href: 'https://www.hubspot.com',
32
32
  },
@@ -34,7 +34,7 @@ export const Default: Story = {
34
34
 
35
35
  export const WithIcon: Story = {
36
36
  args: {
37
- variant: 'primary',
37
+ variant: 'primaryButton',
38
38
  children: 'Click me',
39
39
  href: 'https://www.hubspot.com',
40
40
  showIcon: true,
@@ -1,25 +1,21 @@
1
1
  .buttonContainer {
2
- padding: '20px';
3
- --hscl-button-gap: 8px;
4
- --hscl-button-backgroundColor: #0066cc;
5
- --hscl-button-color: #ffffff;
6
- --hscl-button-paddingBlock: 10px;
7
- --hscl-button-paddingInline: 20px;
8
- --hscl-button-borderRadius: 4px;
9
- --hscl-button-borderWidth: 1px;
10
- --hscl-button-borderColor: transparent;
11
- --hscl-button-fontSize: 14px;
12
- --hscl-button-fontWeight: 500;
13
- --hscl-button-backgroundColor-hover: #0052a3;
14
- --hscl-button-color-hover: #ffffff;
15
- --hscl-button-borderWidth-hover: 1px;
16
- --hscl-button-borderColor-hover: transparent;
17
- --hscl-button-backgroundColor-focus: #0066cc;
18
- --hscl-button-color-focus: #ffffff;
19
- --hscl-button-borderWidth-focus: 1px;
20
- --hscl-button-borderColor-focus: transparent;
21
- --hscl-button-outlineWidth-focus: 2px;
22
- --hscl-button-outlineColor-focus: #0066cc;
23
- --hscl-button-outlineOffset-focus: 2px;
24
- --hscl-button-icon-fill: currentColor;
2
+ padding: 20px;
3
+ --hs-button-backgroundColor: #0066cc;
4
+ --hs-button-color: #ffffff;
5
+ --hs-button-borderRadius: 4px;
6
+ --hs-button-border: 1px solid transparent;
7
+ --hs-button-fontSize: 14px;
8
+ --hs-button-fontFamily: inherit;
9
+ --hs-button-fontStyle: normal;
10
+ --hs-button-fontWeight: 500;
11
+ --hs-button-textDecoration: none;
12
+ --hs-button-backgroundColor-hover: #0052a3;
13
+ --hs-button-color-hover: #ffffff;
14
+ --hs-button-border-hover: 1px solid transparent;
15
+ --hs-button-backgroundColor-focus: #0066cc;
16
+ --hs-button-color-focus: #ffffff;
17
+ --hs-button-border-focus: 1px solid transparent;
18
+ --hs-button-backgroundColor-active: #004080;
19
+ --hs-button-color-active: #ffffff;
20
+ --hs-button-border-active: 1px solid transparent;
25
21
  }
@@ -8,7 +8,7 @@ export type IconPositionHorizontal = 'left' | 'right';
8
8
 
9
9
  // Base props shared by all variants
10
10
  export type BaseButtonProps = {
11
- variant?: 'primary' | 'secondary' | 'tertiary'; // !todo: not used atm but keeping for when we need to add variant system.
11
+ variant?: 'primaryButton' | 'secondaryButton' | 'tertiaryButton' | 'accentButton';
12
12
  className?: string;
13
13
  style?: React.CSSProperties;
14
14
  children?: React.ReactNode;
@@ -57,7 +57,7 @@ export type ContentFieldsProps = Omit<
57
57
  export type StyleFieldsProps = {
58
58
  buttonVariantLabel?: string;
59
59
  buttonVariantName?: string;
60
- buttonVariantDefault?: string;
60
+ buttonVariantDefault?: { variant_name: string };
61
61
  buttonIconPositionLabel?: string;
62
62
  buttonIconPositionName?: string;
63
63
  buttonIconPositionDefault?: IconPositionHorizontal;
@@ -1,22 +1,17 @@
1
- import { ChoiceField } from '@hubspot/cms-components/fields';
1
+ import { VariantSelectionField } from '@hubspot/cms-components/fields';
2
2
  import { StyleFieldsProps } from './types.js';
3
3
 
4
4
  const StyleFields = ({
5
- variantLabel = 'Card Variant',
6
- variantName = 'variant',
7
- variantDefault = 'elevated',
5
+ cardVariantLabel = 'Card variant',
6
+ cardVariantName = 'cardVariant',
7
+ cardVariantDefault = { variantName: 'cardStyle1' },
8
8
  }: StyleFieldsProps) => {
9
9
  return (
10
- <ChoiceField
11
- label={variantLabel}
12
- name={variantName}
13
- required={true}
14
- choices={[
15
- ['elevated', 'Elevated (with shadow)'],
16
- ['outlined', 'Outlined (with border)'],
17
- ['filled', 'Filled (solid background)'],
18
- ]}
19
- default={variantDefault}
10
+ <VariantSelectionField
11
+ label={cardVariantLabel}
12
+ name={cardVariantName}
13
+ variantDefinitionName="card"
14
+ default={cardVariantDefault}
20
15
  />
21
16
  );
22
17
  };
@@ -2,13 +2,13 @@
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  box-sizing: border-box;
5
- padding: var(--hscl-card-padding, 24px);
6
- border-radius: var(--hscl-card-borderRadius, 8px);
7
- background-color: var(--hscl-card-backgroundColor, #ffffff);
8
- box-shadow: var(--hscl-card-boxShadow, none);
9
- border: var(--hscl-card-border, none);
5
+ padding: 24px;
6
+ border-radius: var(--hs-card-borderRadius, 8px);
7
+ background-color: var(--hs-card-backgroundColor, #ffffff);
8
+ color: var(--hs-card-color, inherit);
9
+ border: var(--hs-card-border, none);
10
10
 
11
- &:hover {
12
- box-shadow: var(--hscl-card-boxShadow-hover, var(--hscl-card-boxShadow, none));
11
+ h1,h2,h3,h4,h5,h6,p,span {
12
+ color: inherit;
13
13
  }
14
14
  }
@@ -1,30 +1,25 @@
1
1
  import styles from './index.module.scss';
2
2
  import cx from '../utils/classname.js';
3
- import type { CSSVariables } from '../utils/types.js';
4
3
  import { CardProps } from './types.js';
5
4
  import StyleFields from './StyleFields.js';
6
5
 
7
6
  const CardComponent = ({
8
- variant = 'elevated',
7
+ variant = 'cardStyle1',
9
8
  as: Component = 'div',
10
- borderRadius = 8,
11
9
  className = '',
12
10
  style = {},
13
11
  children,
14
12
  ...rest
15
13
  }: CardProps) => {
16
- const variantClass = styles[`hscl-card-${variant}`]; // !todo: not used atm but keeping for when we need to add variant system.
17
-
18
- const defaultClasses = cx(styles.card, variantClass);
19
- const combinedClasses = cx(defaultClasses, className);
20
-
21
- const cssVariables: CSSVariables = {
22
- '--hscl-card-borderRadius': `${borderRadius}px`,
23
- ...style,
24
- };
14
+ const combinedClasses = cx(styles.card, className);
25
15
 
26
16
  return (
27
- <Component className={combinedClasses} style={cssVariables} {...rest}>
17
+ <Component
18
+ className={combinedClasses}
19
+ style={style}
20
+ data-card-variant={variant}
21
+ {...rest}
22
+ >
28
23
  {children}
29
24
  </Component>
30
25
  );
@@ -1,6 +1,6 @@
1
1
  # Card Component
2
2
 
3
- A flexible, polymorphic container component that provides a consistent visual structure for grouping related content with customizable variants and styling.
3
+ A flexible, polymorphic container component that provides a consistent visual structure for grouping related content with theme variant styling.
4
4
 
5
5
  ## Import path
6
6
  ```tsx
@@ -9,7 +9,7 @@ import Card from '@hubspot/cms-component-library/Card';
9
9
 
10
10
  ## Purpose
11
11
 
12
- The Card component provides a reusable container for grouping related content in HubSpot CMS projects. It solves the challenge of maintaining visual consistency across content sections while supporting different elevation styles (shadows, borders, or filled backgrounds). Use it when you need to visually separate and organize content into distinct sections with flexible styling.
12
+ The Card component provides a reusable container for grouping related content in HubSpot CMS projects. It uses the theme variant system (via `data-card-variant` attribute) to apply visual styles like background color, text color, border radius, and borders. Use it when you need to visually separate and organize content into distinct sections with theme-consistent styling.
13
13
 
14
14
  ## Component Structure
15
15
 
@@ -17,29 +17,28 @@ The Card component provides a reusable container for grouping related content in
17
17
  Card/
18
18
  ├── index.tsx # Main component with render logic
19
19
  ├── types.ts # TypeScript type definitions
20
- ├── StyleFields.tsx # HubSpot field definitions for styling
21
- ├── index.module.scss # CSS module with design tokens
20
+ ├── StyleFields.tsx # HubSpot field definitions for styling (VariantSelectionField)
21
+ ├── index.module.scss # CSS module consuming theme variant CSS variables
22
22
  └── stories/
23
23
  ├── Card.stories.tsx # Storybook examples
24
24
  ├── CardDecorator.tsx # Storybook decorator
25
- └── CardDecorator.module.css # Decorator styles
25
+ └── CardDecorator.module.scss # Decorator styles with variant variable definitions
26
26
  ```
27
27
 
28
28
  ## Components
29
29
 
30
30
  ### Card (Main Component)
31
31
 
32
- **Purpose:** Polymorphic container component that renders as a `<div>`, `<article>`, or `<section>` element with configurable visual variants.
32
+ **Purpose:** Polymorphic container component that renders as a `<div>`, `<article>`, or `<section>` element with theme variant styling applied via the `data-card-variant` attribute.
33
33
 
34
34
  **Props:**
35
35
  ```tsx
36
36
  {
37
- variant?: 'elevated' | 'outlined' | 'filled'; // Visual style variant (default: 'elevated')
37
+ variant?: 'cardStyle1' | 'cardStyle2' | 'cardStyle3' | 'cardStyle4'; // Theme variant (default: 'cardStyle1')
38
38
  as?: 'div' | 'article' | 'section'; // HTML element to render (default: 'div')
39
- borderRadius?: number; // Border radius in pixels (default: 8)
40
39
  children?: React.ReactNode; // Card content
41
40
  className?: string; // Additional CSS classes
42
- style?: React.CSSProperties; // Inline styles with CSS variables
41
+ style?: React.CSSProperties; // Inline styles
43
42
  }
44
43
  ```
45
44
 
@@ -59,7 +58,7 @@ import Card from '@hubspot/cms-component-library/Card';
59
58
  ### Semantic Article Card
60
59
 
61
60
  ```tsx
62
- <Card as="article" variant="filled">
61
+ <Card as="article" variant="cardStyle3">
63
62
  <h3>Blog Post Title</h3>
64
63
  <p>Article content goes here...</p>
65
64
  </Card>
@@ -84,25 +83,11 @@ const features = [
84
83
  </div>
85
84
  ```
86
85
 
87
- ### Card with Rich Content
88
-
89
- ```tsx
90
- <Card variant="outlined">
91
- <h3>Product Features</h3>
92
- <ul>
93
- <li>Real-time collaboration</li>
94
- <li>Advanced security</li>
95
- <li>Custom integrations</li>
96
- </ul>
97
- <button>Learn More</button>
98
- </Card>
99
- ```
100
-
101
86
  ## HubSpot CMS Integration
102
87
 
103
88
  ### Field Definitions
104
89
 
105
- The Card component provides field definitions for styling configuration in HubSpot CMS modules.
90
+ The Card component uses `VariantSelectionField` from `@hubspot/cms-components/fields` to allow theme variant selection in the CMS editor.
106
91
 
107
92
  #### StyleFields.tsx
108
93
 
@@ -110,14 +95,14 @@ Configurable props for customizing field labels, names, and defaults:
110
95
 
111
96
  ```tsx
112
97
  <Card.StyleFields
113
- variantLabel="Card variant"
114
- variantName="variant"
115
- variantDefault="elevated"
98
+ cardVariantLabel="Card variant"
99
+ cardVariantName="cardVariant"
100
+ cardVariantDefault={{ variant_name: 'cardStyle1' }}
116
101
  />
117
102
  ```
118
103
 
119
104
  **Fields:**
120
- - `variant`: ChoiceField for selecting visual style (elevated, outlined, filled)
105
+ - `cardVariant`: VariantSelectionField for selecting theme variant (variantDefinitionName: "card")
121
106
 
122
107
  ### Module Usage Example
123
108
 
@@ -127,7 +112,7 @@ import Card from '@hubspot/cms-component-library/Card';
127
112
  export default function FeatureCardModule({ fieldValues }) {
128
113
  return (
129
114
  <Card
130
- variant={fieldValues.variant}
115
+ variant={fieldValues.cardVariant.variant_name}
131
116
  as="article"
132
117
  >
133
118
  <h3>{fieldValues.title}</h3>
@@ -147,19 +132,13 @@ FeatureCardModule.fields = (
147
132
 
148
133
  ## Styling
149
134
 
150
- ### CSS Variables
151
-
152
- The Card component uses CSS variables for theming and customization:
135
+ ### Theme Variant CSS Variables (provided by the variant system via `data-card-variant`)
153
136
 
154
- **Base Styles:**
155
- - `--hscl-card-padding`: Internal padding (default: 24px)
156
- - `--hscl-card-borderRadius`: Border radius (default: 8px)
157
- - `--hscl-card-backgroundColor`: Background color (default: #ffffff)
158
- - `--hscl-card-boxShadow`: Box shadow (default: none)
159
- - `--hscl-card-border`: Border style (default: none)
137
+ - `--hs-card-borderRadius`: Border radius
138
+ - `--hs-card-backgroundColor`: Background color
139
+ - `--hs-card-color`: Text color
140
+ - `--hs-card-border`: Border style
160
141
 
161
- **Hover States:**
162
- - `--hscl-card-boxShadow-hover`: Hover box shadow (inherits from base if not set)
163
142
 
164
143
  ## Accessibility
165
144
 
@@ -167,13 +146,13 @@ The Card component follows accessibility best practices:
167
146
 
168
147
  - **Semantic HTML**: Use the `as` prop to render appropriate semantic elements (`article` for blog posts, `section` for page sections, `div` for generic containers)
169
148
  - **Content Structure**: Ensure proper heading hierarchy within card content (e.g., if cards are in an h2 section, use h3 for card titles)
170
- - **Color Contrast**: Default styles meet WCAG AA contrast requirements; verify custom colors maintain sufficient contrast
149
+ - **Color Contrast**: Theme variants should meet WCAG AA contrast requirements; verify custom colors maintain sufficient contrast
171
150
  - **Focus Management**: Cards themselves are not interactive, but ensure interactive elements within cards (buttons, links) have proper focus styles
172
151
 
173
152
  ## Best Practices
174
153
 
175
154
  - **Choose semantic elements**: Use `as="article"` for self-contained content, `as="section"` for thematic groupings, and `as="div"` (default) for generic containers
176
- - **Border radius via theme settings**: Border radius is controlled by card shape settings in theme settings/variants, not an element-level field. Use the `borderRadius` prop only for programmatic overrides.
155
+ - **Border radius via theme variants**: Border radius is controlled by the variant system, not a direct prop.
177
156
  - **Override CSS variables**: Customize appearance using CSS variables rather than overriding class styles
178
157
  - **Grid layouts**: Use CSS Grid or Flexbox for card layouts rather than relying on card margins
179
158
  - **Content flexibility**: Cards are content-agnostic containers; structure internal content using appropriate semantic elements