@hubspot/cms-component-library 0.1.0-beta.1 → 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.
- package/components/componentLibrary/Accordion/AccordionContent/ContentFields.tsx +5 -3
- package/components/componentLibrary/Accordion/AccordionItem/StyleFields.tsx +5 -3
- package/components/componentLibrary/Accordion/AccordionItem/index.module.scss +2 -2
- package/components/componentLibrary/Accordion/AccordionItem/index.tsx +3 -3
- package/components/componentLibrary/Accordion/AccordionTitle/ContentFields.tsx +5 -3
- package/components/componentLibrary/Accordion/AccordionTitle/index.module.scss +2 -2
- package/components/componentLibrary/Accordion/stories/Accordion.stories.tsx +80 -1
- package/components/componentLibrary/Accordion/stories/AccordionDecorator.tsx +14 -14
- package/components/componentLibrary/Button/ContentFields.tsx +5 -3
- package/components/componentLibrary/Button/StyleFields.tsx +5 -3
- package/components/componentLibrary/Button/index.module.scss +22 -14
- package/components/componentLibrary/Button/index.tsx +6 -6
- package/components/componentLibrary/Button/stories/Button.AsButton.stories.tsx +30 -1
- package/components/componentLibrary/Button/stories/Button.AsLink.stories.tsx +38 -1
- package/components/componentLibrary/Button/stories/ButtonDecorator.tsx +1 -1
- package/components/componentLibrary/Card/StyleFields.tsx +5 -3
- package/components/componentLibrary/Card/stories/Card.stories.tsx +46 -1
- package/components/componentLibrary/Card/stories/CardDecorator.tsx +1 -1
- package/components/componentLibrary/Divider/ContentFields.tsx +5 -3
- package/components/componentLibrary/Divider/StyleFields.tsx +5 -3
- package/components/componentLibrary/Divider/index.module.scss +6 -6
- package/components/componentLibrary/Divider/index.tsx +7 -3
- package/components/componentLibrary/Divider/stories/Divider.stories.tsx +44 -50
- package/components/componentLibrary/Divider/stories/{DividerDecorator.module.css → DividerDecorator.module.scss} +5 -4
- package/components/componentLibrary/Divider/stories/DividerDecorator.tsx +1 -1
- package/components/componentLibrary/Divider/types.ts +3 -1
- package/components/componentLibrary/Drawer/hooks/index.tsx +13 -0
- package/components/componentLibrary/Drawer/index.module.scss +94 -0
- package/components/componentLibrary/Drawer/index.tsx +131 -0
- package/components/componentLibrary/Drawer/llm.txt +416 -0
- package/components/componentLibrary/Drawer/stories/Drawer.stories.tsx +512 -0
- package/components/componentLibrary/Drawer/stories/DrawerDecorator.module.scss +8 -0
- package/components/componentLibrary/Drawer/stories/DrawerDecorator.tsx +18 -0
- package/components/componentLibrary/Drawer/types.ts +25 -0
- package/components/componentLibrary/Flex/stories/FlexDecorator.tsx +1 -1
- package/components/componentLibrary/Flex/types.ts +3 -1
- package/components/componentLibrary/Grid/stories/Grid.stories.tsx +454 -152
- package/components/componentLibrary/Grid/stories/GridDecorator.tsx +2 -2
- package/components/componentLibrary/Heading/ContentFields.tsx +5 -3
- package/components/componentLibrary/Heading/StyleFields.tsx +11 -9
- package/components/componentLibrary/Heading/index.tsx +3 -3
- package/components/componentLibrary/Heading/llm.txt +8 -8
- package/components/componentLibrary/Heading/stories/Heading.stories.tsx +3 -3
- package/components/componentLibrary/Heading/stories/HeadingDecorator.tsx +1 -1
- package/components/componentLibrary/Heading/types.ts +4 -4
- package/components/componentLibrary/Icon/ContentFields.tsx +5 -3
- package/components/componentLibrary/Icon/stories/Icon.stories.tsx +1 -1
- package/components/componentLibrary/Icon/stories/IconDecorator.tsx +1 -1
- package/components/componentLibrary/Image/ContentFields.tsx +5 -3
- package/components/componentLibrary/Image/index.tsx +4 -4
- package/components/componentLibrary/Image/llm.txt +17 -17
- package/components/componentLibrary/Image/stories/Image.stories.tsx +61 -18
- package/components/componentLibrary/Image/stories/ImageDecorator.tsx +1 -1
- package/components/componentLibrary/Image/types.ts +2 -2
- package/components/componentLibrary/LanguageSwitcher/ContentFields.tsx +18 -0
- package/components/componentLibrary/LanguageSwitcher/LanguageOptions.module.scss +37 -0
- package/components/componentLibrary/LanguageSwitcher/LanguageOptions.tsx +65 -0
- package/components/componentLibrary/LanguageSwitcher/StyleFields.tsx +48 -0
- package/components/componentLibrary/LanguageSwitcher/_dummyData.tsx +247 -0
- package/components/componentLibrary/LanguageSwitcher/assets/Globe.tsx +16 -0
- package/components/componentLibrary/LanguageSwitcher/index.module.scss +58 -0
- package/components/componentLibrary/LanguageSwitcher/index.tsx +125 -0
- package/components/componentLibrary/LanguageSwitcher/llm.txt +380 -0
- package/components/componentLibrary/LanguageSwitcher/stories/LanguageSwitcher.stories.tsx +349 -0
- package/components/componentLibrary/LanguageSwitcher/stories/LanguageSwitcherDecorator.module.scss +5 -0
- package/components/componentLibrary/LanguageSwitcher/stories/LanguageSwitcherDecorator.tsx +8 -0
- package/components/componentLibrary/LanguageSwitcher/types.ts +48 -0
- package/components/componentLibrary/LanguageSwitcher/utils.tsx +38 -0
- package/components/componentLibrary/Link/ContentFields.tsx +5 -3
- package/components/componentLibrary/Link/StyleFields.tsx +5 -3
- package/components/componentLibrary/Link/index.module.scss +10 -0
- package/components/componentLibrary/Link/index.tsx +24 -14
- package/components/componentLibrary/Link/stories/Link.stories.tsx +35 -5
- package/components/componentLibrary/Link/stories/LinkDecorator.tsx +11 -1
- package/components/componentLibrary/Link/types.ts +22 -13
- package/components/componentLibrary/List/ContentFields.tsx +5 -3
- package/components/componentLibrary/List/ListItem/ContentFields.tsx +6 -17
- package/components/componentLibrary/List/ListItem/index.module.scss +1 -13
- package/components/componentLibrary/List/ListItem/index.tsx +3 -30
- package/components/componentLibrary/List/ListItem/types.ts +1 -16
- package/components/componentLibrary/List/StyleFields.tsx +15 -18
- package/components/componentLibrary/List/index.module.scss +3 -0
- package/components/componentLibrary/List/index.tsx +5 -2
- package/components/componentLibrary/List/llm.txt +73 -103
- package/components/componentLibrary/List/stories/List.stories.tsx +56 -80
- package/components/componentLibrary/List/stories/ListDecorator.tsx +3 -6
- package/components/componentLibrary/List/types.ts +1 -3
- package/components/componentLibrary/Logo/_dummyLogoData.ts +12 -0
- package/components/componentLibrary/Logo/assets/hubspot-logo.png +0 -0
- package/components/componentLibrary/Logo/index.module.scss +22 -0
- package/components/componentLibrary/Logo/index.tsx +73 -0
- package/components/componentLibrary/Logo/llm.txt +262 -0
- package/components/componentLibrary/Logo/stories/Logo.stories.tsx +88 -0
- package/components/componentLibrary/Logo/stories/LogoDecorator.module.scss +10 -0
- package/components/componentLibrary/Logo/stories/LogoDecorator.tsx +8 -0
- package/components/componentLibrary/Logo/types.tsx +16 -0
- package/components/componentLibrary/Menu/ContentFields.tsx +16 -0
- package/components/componentLibrary/Menu/MenuItem/Chevron/index.module.scss +6 -0
- package/components/componentLibrary/Menu/MenuItem/Chevron/index.tsx +17 -0
- package/components/componentLibrary/Menu/MenuItem/index.module.scss +7 -0
- package/components/componentLibrary/Menu/MenuItem/index.tsx +266 -0
- package/components/componentLibrary/Menu/MenuItem/types.ts +17 -0
- package/components/componentLibrary/Menu/NavigationMenu/ContentFields.tsx +20 -0
- package/components/componentLibrary/Menu/NavigationMenu/index.tsx +18 -0
- package/components/componentLibrary/Menu/NavigationMenu/islands/NavigationMenuIsland.tsx +95 -0
- package/components/componentLibrary/Menu/NavigationMenu/islands/index.module.scss +100 -0
- package/components/componentLibrary/Menu/NavigationMenu/islands/types.ts +19 -0
- package/components/componentLibrary/Menu/NavigationMenu/llm.txt +197 -0
- package/components/componentLibrary/Menu/NavigationMenu/stories/NavigationMenu.stories.tsx +286 -0
- package/components/componentLibrary/Menu/NavigationMenu/stories/NavigationMenuDecorator.module.scss +15 -0
- package/components/componentLibrary/Menu/NavigationMenu/stories/NavigationMenuDecorator.tsx +12 -0
- package/components/componentLibrary/Menu/NavigationMenu/types.ts +3 -0
- package/components/componentLibrary/Menu/VerticalMenu/ContentFields.tsx +20 -0
- package/components/componentLibrary/Menu/VerticalMenu/index.tsx +18 -0
- package/components/componentLibrary/Menu/VerticalMenu/islands/index.module.scss +53 -0
- package/components/componentLibrary/Menu/VerticalMenu/islands/verticalMenuIsland.tsx +78 -0
- package/components/componentLibrary/Menu/VerticalMenu/llm.txt +177 -0
- package/components/componentLibrary/Menu/VerticalMenu/stories/VerticalMenu.stories.tsx +242 -0
- package/components/componentLibrary/Menu/VerticalMenu/stories/VerticalMenuDecorator.module.scss +19 -0
- package/components/componentLibrary/Menu/VerticalMenu/stories/VerticalMenuDecorator.tsx +12 -0
- package/components/componentLibrary/Menu/VerticalMenu/types.ts +21 -0
- package/components/componentLibrary/Menu/_dummyMenuData.js +1346 -0
- package/components/componentLibrary/Menu/types.ts +56 -0
- package/components/componentLibrary/Menu/utils/transformMenuData.ts +11 -0
- package/components/componentLibrary/_patterns/README.md +15 -17
- package/components/componentLibrary/_patterns/checklist-and-examples.md +17 -17
- package/components/componentLibrary/_patterns/component-structure.md +21 -23
- package/components/componentLibrary/_patterns/css-patterns.md +170 -18
- package/components/componentLibrary/_patterns/field-patterns.md +97 -27
- package/components/componentLibrary/_patterns/function-declaration-patterns.md +281 -0
- package/components/componentLibrary/_patterns/llm-txt.template.md +4 -2
- package/components/componentLibrary/_patterns/prop-naming-patterns.md +208 -0
- package/components/componentLibrary/_patterns/storybook-patterns.md +25 -8
- package/components/componentLibrary/_patterns/typescript-patterns.md +6 -3
- package/package.json +4 -2
- /package/components/componentLibrary/Button/stories/{ButtonDecorator.module.css → ButtonDecorator.module.scss} +0 -0
- /package/components/componentLibrary/Card/stories/{CardDecorator.module.css → CardDecorator.module.scss} +0 -0
- /package/components/componentLibrary/Flex/stories/{FlexDecorator.module.css → FlexDecorator.module.scss} +0 -0
- /package/components/componentLibrary/Grid/stories/{GridDecorator.module.css → GridDecorator.module.scss} +0 -0
- /package/components/componentLibrary/Heading/stories/{HeadingDecorator.module.css → HeadingDecorator.module.scss} +0 -0
- /package/components/componentLibrary/Icon/stories/{IconDecorator.module.css → IconDecorator.module.scss} +0 -0
- /package/components/componentLibrary/Image/stories/{ImageDecorator.module.css → ImageDecorator.module.scss} +0 -0
- /package/components/componentLibrary/Image/stories/assets/{catSmile.jpg → cat-smile.jpg} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { RichTextField } from '@hubspot/cms-components/fields';
|
|
2
2
|
import type { ContentFieldsProps } from './types.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const ContentFields = ({
|
|
5
5
|
contentLabel = 'Content',
|
|
6
6
|
contentName = 'content',
|
|
7
7
|
contentDefault = '<p>Accordion content goes here. You can add multiple lines of text.</p>',
|
|
8
|
-
}: ContentFieldsProps) {
|
|
8
|
+
}: ContentFieldsProps) => {
|
|
9
9
|
return (
|
|
10
10
|
// Todo: consider migrating over field library
|
|
11
11
|
<RichTextField
|
|
@@ -14,4 +14,6 @@ export default function ContentFields({
|
|
|
14
14
|
default={contentDefault}
|
|
15
15
|
/>
|
|
16
16
|
);
|
|
17
|
-
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default ContentFields;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ChoiceField } from '@hubspot/cms-components/fields';
|
|
2
2
|
import type { StyleFieldsProps } from './types.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const StyleFields = ({
|
|
5
5
|
variantLabel = 'Variant',
|
|
6
6
|
variantName = 'variant',
|
|
7
7
|
variantDefault = 'variant1',
|
|
8
|
-
}: StyleFieldsProps) {
|
|
8
|
+
}: StyleFieldsProps) => {
|
|
9
9
|
return (
|
|
10
10
|
<ChoiceField
|
|
11
11
|
label={variantLabel}
|
|
@@ -22,4 +22,6 @@ export default function StyleFields({
|
|
|
22
22
|
default={variantDefault}
|
|
23
23
|
/>
|
|
24
24
|
);
|
|
25
|
-
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default StyleFields;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
.accordionItem {
|
|
2
|
-
border: var(--hscl-accordion-
|
|
2
|
+
border: var(--hscl-accordion-borderWidth, 1px) solid
|
|
3
3
|
var(--hscl-accordion-borderColor, #e0e0e0);
|
|
4
4
|
border-radius: var(--hscl-accordion-borderRadius, 4px);
|
|
5
5
|
background-color: var(--hscl-accordion-backgroundColor, transparent);
|
|
6
|
-
color: var(--hscl-accordion-
|
|
6
|
+
color: var(--hscl-accordion-color, inherit);
|
|
7
7
|
overflow: hidden;
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -17,10 +17,10 @@ const AccordionItemComponent = ({
|
|
|
17
17
|
? mapVariantToCssVars('--hscl-accordion', variant, [
|
|
18
18
|
'borderColor',
|
|
19
19
|
'borderRadius',
|
|
20
|
-
'
|
|
20
|
+
'borderWidth',
|
|
21
21
|
'backgroundColor',
|
|
22
|
-
'
|
|
23
|
-
'icon-
|
|
22
|
+
'color',
|
|
23
|
+
'icon-fill',
|
|
24
24
|
])
|
|
25
25
|
: {};
|
|
26
26
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { TextField, ChoiceField } from '@hubspot/cms-components/fields';
|
|
2
2
|
import type { ContentFieldsProps } from './types.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const ContentFields = ({
|
|
5
5
|
titleLabel = 'Title',
|
|
6
6
|
titleName = 'title',
|
|
7
7
|
titleDefault = 'Accordion Title',
|
|
8
8
|
iconLabel = 'Icon',
|
|
9
9
|
iconName = 'icon',
|
|
10
10
|
iconDefault = 'chevron',
|
|
11
|
-
}: ContentFieldsProps) {
|
|
11
|
+
}: ContentFieldsProps) => {
|
|
12
12
|
return (
|
|
13
13
|
<>
|
|
14
14
|
<ChoiceField
|
|
@@ -26,4 +26,6 @@ export default function ContentFields({
|
|
|
26
26
|
<TextField label={titleLabel} name={titleName} default={titleDefault} />
|
|
27
27
|
</>
|
|
28
28
|
);
|
|
29
|
-
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default ContentFields;
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
.accordionTitleText {
|
|
16
16
|
font-size: var(--hscl-accordion-title-fontSize, 24px);
|
|
17
17
|
font-weight: var(--hscl-accordion-title-fontWeight, 600);
|
|
18
|
-
margin-inline-end: var(--hscl-accordion-title-
|
|
18
|
+
margin-inline-end: var(--hscl-accordion-title-marginInlineEnd, 16px);
|
|
19
19
|
flex: 1;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.accordionIcon {
|
|
23
23
|
flex-shrink: 0;
|
|
24
24
|
align-self: center;
|
|
25
|
-
fill: var(--hscl-accordion-icon-
|
|
25
|
+
fill: var(--hscl-accordion-icon-fill, currentColor);
|
|
26
26
|
margin-inline-start: auto;
|
|
27
27
|
transition: transform 0.3s ease;
|
|
28
28
|
display: block;
|
|
@@ -6,7 +6,7 @@ import Accordion, {
|
|
|
6
6
|
} from '../index.js';
|
|
7
7
|
import { AccordionProps } from '../types.js';
|
|
8
8
|
import { withAccordionStyles } from './AccordionDecorator.js';
|
|
9
|
-
import { SBContainer } from '@sb-utils
|
|
9
|
+
import { SBContainer, SBFocusWrapper } from '@sb-utils';
|
|
10
10
|
|
|
11
11
|
const meta: Meta<AccordionProps> = {
|
|
12
12
|
title: 'Component Library/Accordion',
|
|
@@ -462,3 +462,82 @@ export const EdgeCases: Story = {
|
|
|
462
462
|
</SBContainer>
|
|
463
463
|
),
|
|
464
464
|
};
|
|
465
|
+
|
|
466
|
+
export const InteractionStates: Story = {
|
|
467
|
+
name: 'Interaction States',
|
|
468
|
+
render: () => (
|
|
469
|
+
<SBContainer flex direction="column" gap="large" width="800px">
|
|
470
|
+
<SBContainer addBackground>
|
|
471
|
+
<h4>Keyboard Navigation</h4>
|
|
472
|
+
<p>
|
|
473
|
+
<strong>Try:</strong> Press Tab to focus on accordion titles, then
|
|
474
|
+
press Enter or Space to expand/collapse them
|
|
475
|
+
</p>
|
|
476
|
+
<Accordion>
|
|
477
|
+
<AccordionItem>
|
|
478
|
+
<AccordionTitle>First accordion item</AccordionTitle>
|
|
479
|
+
<AccordionContent>
|
|
480
|
+
<p>
|
|
481
|
+
Accordion titles (summary elements) are natively keyboard
|
|
482
|
+
accessible. Tab to focus, Enter/Space to toggle.
|
|
483
|
+
</p>
|
|
484
|
+
</AccordionContent>
|
|
485
|
+
</AccordionItem>
|
|
486
|
+
<AccordionItem>
|
|
487
|
+
<AccordionTitle>Second accordion item</AccordionTitle>
|
|
488
|
+
<AccordionContent>
|
|
489
|
+
<p>
|
|
490
|
+
Focus rings appear automatically when navigating with the
|
|
491
|
+
keyboard, providing clear visual feedback.
|
|
492
|
+
</p>
|
|
493
|
+
</AccordionContent>
|
|
494
|
+
</AccordionItem>
|
|
495
|
+
<AccordionItem>
|
|
496
|
+
<AccordionTitle>Third accordion item</AccordionTitle>
|
|
497
|
+
<AccordionContent>
|
|
498
|
+
<p>
|
|
499
|
+
This demonstrates how users can navigate through all accordion
|
|
500
|
+
items using only the keyboard.
|
|
501
|
+
</p>
|
|
502
|
+
</AccordionContent>
|
|
503
|
+
</AccordionItem>
|
|
504
|
+
</Accordion>
|
|
505
|
+
</SBContainer>
|
|
506
|
+
|
|
507
|
+
<SBContainer addBackground>
|
|
508
|
+
<h4>Focus State</h4>
|
|
509
|
+
<p>
|
|
510
|
+
In production, this focus outline appears when navigating with the
|
|
511
|
+
keyboard (Tab key). This Storybook demo auto-applies the focus state
|
|
512
|
+
to show how it looks.
|
|
513
|
+
</p>
|
|
514
|
+
<SBFocusWrapper>
|
|
515
|
+
<Accordion>
|
|
516
|
+
<AccordionItem>
|
|
517
|
+
<AccordionTitle>Focused accordion item</AccordionTitle>
|
|
518
|
+
<AccordionContent>
|
|
519
|
+
<p>
|
|
520
|
+
This accordion title automatically receives focus to
|
|
521
|
+
demonstrate the focus ring appearance.
|
|
522
|
+
</p>
|
|
523
|
+
</AccordionContent>
|
|
524
|
+
</AccordionItem>
|
|
525
|
+
</Accordion>
|
|
526
|
+
</SBFocusWrapper>
|
|
527
|
+
</SBContainer>
|
|
528
|
+
|
|
529
|
+
<SBContainer addBackground>
|
|
530
|
+
<h4>Hover State</h4>
|
|
531
|
+
<p>Hover over accordion titles to see the hover effect</p>
|
|
532
|
+
<Accordion>
|
|
533
|
+
<AccordionItem>
|
|
534
|
+
<AccordionTitle>Hover over this title</AccordionTitle>
|
|
535
|
+
<AccordionContent>
|
|
536
|
+
<p>The title shows a subtle background change on hover.</p>
|
|
537
|
+
</AccordionContent>
|
|
538
|
+
</AccordionItem>
|
|
539
|
+
</Accordion>
|
|
540
|
+
</SBContainer>
|
|
541
|
+
</SBContainer>
|
|
542
|
+
),
|
|
543
|
+
};
|
|
@@ -2,36 +2,36 @@ import type { Decorator } from '@storybook/react';
|
|
|
2
2
|
import type { CSSVariables } from '../../utils/types.js';
|
|
3
3
|
|
|
4
4
|
const defaultAccordionStyles: CSSVariables = {
|
|
5
|
-
'--hscl-listItem-
|
|
6
|
-
'--hscl-listItem-
|
|
5
|
+
'--hscl-listItem-color-primary': '#33475b',
|
|
6
|
+
'--hscl-listItem-color-secondary': '#516f90',
|
|
7
7
|
|
|
8
8
|
'--hscl-accordion-variant1-borderColor': '#e0e0e0',
|
|
9
9
|
'--hscl-accordion-variant1-borderRadius': '4px',
|
|
10
|
-
'--hscl-accordion-variant1-
|
|
10
|
+
'--hscl-accordion-variant1-borderWidth': '1px',
|
|
11
11
|
'--hscl-accordion-variant1-backgroundColor': 'transparent',
|
|
12
|
-
'--hscl-accordion-variant1-
|
|
13
|
-
'--hscl-accordion-variant1-icon-
|
|
12
|
+
'--hscl-accordion-variant1-color': '#33475b',
|
|
13
|
+
'--hscl-accordion-variant1-icon-fill': '#33475b',
|
|
14
14
|
|
|
15
15
|
'--hscl-accordion-variant2-borderColor': '#cbd6e2',
|
|
16
16
|
'--hscl-accordion-variant2-borderRadius': '8px',
|
|
17
|
-
'--hscl-accordion-variant2-
|
|
17
|
+
'--hscl-accordion-variant2-borderWidth': '1px',
|
|
18
18
|
'--hscl-accordion-variant2-backgroundColor': '#f5f8fa',
|
|
19
|
-
'--hscl-accordion-variant2-
|
|
20
|
-
'--hscl-accordion-variant2-icon-
|
|
19
|
+
'--hscl-accordion-variant2-color': '#33475b',
|
|
20
|
+
'--hscl-accordion-variant2-icon-fill': '#516f90',
|
|
21
21
|
|
|
22
22
|
'--hscl-accordion-variant3-borderColor': '#ff7a59',
|
|
23
23
|
'--hscl-accordion-variant3-borderRadius': '0',
|
|
24
|
-
'--hscl-accordion-variant3-
|
|
24
|
+
'--hscl-accordion-variant3-borderWidth': '2px',
|
|
25
25
|
'--hscl-accordion-variant3-backgroundColor': 'transparent',
|
|
26
|
-
'--hscl-accordion-variant3-
|
|
27
|
-
'--hscl-accordion-variant3-icon-
|
|
26
|
+
'--hscl-accordion-variant3-color': '#33475b',
|
|
27
|
+
'--hscl-accordion-variant3-icon-fill': '#ff7a59',
|
|
28
28
|
|
|
29
29
|
'--hscl-accordion-variant4-borderColor': '#33475b',
|
|
30
30
|
'--hscl-accordion-variant4-borderRadius': '12px',
|
|
31
|
-
'--hscl-accordion-variant4-
|
|
31
|
+
'--hscl-accordion-variant4-borderWidth': '1px',
|
|
32
32
|
'--hscl-accordion-variant4-backgroundColor': '#eaf0f6',
|
|
33
|
-
'--hscl-accordion-variant4-
|
|
34
|
-
'--hscl-accordion-variant4-icon-
|
|
33
|
+
'--hscl-accordion-variant4-color': '#33475b',
|
|
34
|
+
'--hscl-accordion-variant4-icon-fill': '#33475b',
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
export const withAccordionStyles: Decorator = Story => (
|
|
@@ -2,7 +2,7 @@ import { TextField, LinkField } from '@hubspot/cms-components/fields';
|
|
|
2
2
|
import Icon from '../Icon/index.js';
|
|
3
3
|
import { ContentFieldsProps } from './types.js';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const ContentFields = ({
|
|
6
6
|
buttonTextLabel = 'Button text',
|
|
7
7
|
buttonTextName = 'buttonText',
|
|
8
8
|
buttonTextDefault = 'Click me',
|
|
@@ -22,7 +22,7 @@ export default function ContentFields({
|
|
|
22
22
|
showIconLabel = 'Show button icon',
|
|
23
23
|
showIconName,
|
|
24
24
|
showIconDefault,
|
|
25
|
-
}: ContentFieldsProps) {
|
|
25
|
+
}: ContentFieldsProps) => {
|
|
26
26
|
const iconContentFieldsProps = {
|
|
27
27
|
iconLabel,
|
|
28
28
|
iconName,
|
|
@@ -49,4 +49,6 @@ export default function ContentFields({
|
|
|
49
49
|
<Icon.ContentFields addIconToggle={true} {...iconContentFieldsProps} />
|
|
50
50
|
</>
|
|
51
51
|
);
|
|
52
|
-
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default ContentFields;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ChoiceField } 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
|
-
}: StyleFieldsProps) {
|
|
8
|
+
}: StyleFieldsProps) => {
|
|
9
9
|
return (
|
|
10
10
|
<>
|
|
11
11
|
<ChoiceField
|
|
@@ -20,4 +20,6 @@ export default function StyleFields({
|
|
|
20
20
|
/>
|
|
21
21
|
</>
|
|
22
22
|
);
|
|
23
|
-
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default StyleFields;
|
|
@@ -17,21 +17,32 @@
|
|
|
17
17
|
transition: all 0.2s ease;
|
|
18
18
|
text-decoration: none;
|
|
19
19
|
|
|
20
|
+
@media (prefers-reduced-motion: reduce) {
|
|
21
|
+
transition: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
20
24
|
&:hover {
|
|
21
|
-
background-color: var(--hscl-button-backgroundColor-hover);
|
|
22
|
-
color: var(--hscl-button-color-hover);
|
|
23
|
-
border-width: var(--hscl-button-borderWidth-hover);
|
|
24
|
-
border-color: var(--hscl-button-borderColor-hover);
|
|
25
|
+
background-color: var(--hscl-button-backgroundColor-hover, var(--hscl-button-backgroundColor));
|
|
26
|
+
color: var(--hscl-button-color-hover, var(--hscl-button-color));
|
|
27
|
+
border-width: var(--hscl-button-borderWidth-hover, var(--hscl-button-borderWidth));
|
|
28
|
+
border-color: var(--hscl-button-borderColor-hover, var(--hscl-button-borderColor));
|
|
25
29
|
text-decoration: none;
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
&:focus {
|
|
29
|
-
background-color: var(--hscl-button-backgroundColor-focus);
|
|
30
|
-
color: var(--hscl-button-color-focus);
|
|
31
|
-
border-width: var(--hscl-button-borderWidth-focus);
|
|
32
|
-
border-color: var(--hscl-button-borderColor-focus);
|
|
33
|
-
outline: var(--hscl-button-outlineWidth-focus) solid var(--hscl-button-outlineColor-focus);
|
|
34
|
-
outline-offset: var(--hscl-button-outlineOffset-focus);
|
|
32
|
+
&:focus-visible {
|
|
33
|
+
background-color: var(--hscl-button-backgroundColor-focus, var(--hscl-button-backgroundColor));
|
|
34
|
+
color: var(--hscl-button-color-focus, var(--hscl-button-color));
|
|
35
|
+
border-width: var(--hscl-button-borderWidth-focus, var(--hscl-button-borderWidth));
|
|
36
|
+
border-color: var(--hscl-button-borderColor-focus, var(--hscl-button-borderColor));
|
|
37
|
+
outline: var(--hscl-button-outlineWidth-focus, 2px) solid var(--hscl-button-outlineColor-focus, currentColor);
|
|
38
|
+
outline-offset: var(--hscl-button-outlineOffset-focus, 2px);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&:active {
|
|
42
|
+
background-color: var(--hscl-button-backgroundColor-active, var(--hscl-button-backgroundColor));
|
|
43
|
+
color: var(--hscl-button-color-active, var(--hscl-button-color));
|
|
44
|
+
border-width: var(--hscl-button-borderWidth-active, var(--hscl-button-borderWidth));
|
|
45
|
+
border-color: var(--hscl-button-borderColor-active, var(--hscl-button-borderColor));
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
&:disabled {
|
|
@@ -39,7 +50,6 @@
|
|
|
39
50
|
cursor: not-allowed;
|
|
40
51
|
}
|
|
41
52
|
|
|
42
|
-
|
|
43
53
|
svg {
|
|
44
54
|
display: inline-flex;
|
|
45
55
|
align-items: center;
|
|
@@ -47,5 +57,3 @@
|
|
|
47
57
|
fill: var(--hscl-button-icon-fill);
|
|
48
58
|
}
|
|
49
59
|
}
|
|
50
|
-
|
|
51
|
-
|
|
@@ -56,7 +56,7 @@ const ButtonComponent = ({
|
|
|
56
56
|
);
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
const renderButton = ({
|
|
60
60
|
onClick,
|
|
61
61
|
disabled = false,
|
|
62
62
|
children,
|
|
@@ -67,7 +67,7 @@ const ButtonComponent = ({
|
|
|
67
67
|
iconPurpose,
|
|
68
68
|
iconTitle,
|
|
69
69
|
...rest
|
|
70
|
-
}: Omit<ButtonAsButtonProps, 'buttonType'> & Partial<BaseButtonProps>) {
|
|
70
|
+
}: Omit<ButtonAsButtonProps, 'buttonType'> & Partial<BaseButtonProps>) => {
|
|
71
71
|
const iconProps = {
|
|
72
72
|
iconFieldPath,
|
|
73
73
|
iconSize,
|
|
@@ -81,9 +81,9 @@ const ButtonComponent = ({
|
|
|
81
81
|
<RenderWithIcon {...iconProps}>{children}</RenderWithIcon>
|
|
82
82
|
</button>
|
|
83
83
|
);
|
|
84
|
-
}
|
|
84
|
+
};
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
const renderLink = ({
|
|
87
87
|
href = '',
|
|
88
88
|
target = '_self',
|
|
89
89
|
rel = '',
|
|
@@ -95,7 +95,7 @@ const ButtonComponent = ({
|
|
|
95
95
|
iconPurpose,
|
|
96
96
|
iconTitle,
|
|
97
97
|
...rest
|
|
98
|
-
}: Omit<ButtonAsLinkProps, 'buttonType'> & Partial<BaseButtonProps>) {
|
|
98
|
+
}: Omit<ButtonAsLinkProps, 'buttonType'> & Partial<BaseButtonProps>) => {
|
|
99
99
|
const iconProps = {
|
|
100
100
|
iconFieldPath,
|
|
101
101
|
iconSize,
|
|
@@ -109,7 +109,7 @@ const ButtonComponent = ({
|
|
|
109
109
|
<RenderWithIcon {...iconProps}>{children}</RenderWithIcon>
|
|
110
110
|
</a>
|
|
111
111
|
);
|
|
112
|
-
}
|
|
112
|
+
};
|
|
113
113
|
|
|
114
114
|
// TypeScript properly discriminates based on buttonType
|
|
115
115
|
if (buttonType === 'button') return renderButton(rest);
|
|
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
2
2
|
import Button from '../index.js';
|
|
3
3
|
import { ButtonAsButtonProps } from '../types.js';
|
|
4
4
|
import { withButtonStyles } from './ButtonDecorator.js';
|
|
5
|
-
import { SBContainer } from '@sb-utils
|
|
5
|
+
import { SBContainer, SBFocusWrapper } from '@sb-utils';
|
|
6
6
|
|
|
7
7
|
const meta: Meta<ButtonAsButtonProps> = {
|
|
8
8
|
title: 'Component Library/Button/As Button',
|
|
@@ -64,3 +64,32 @@ export const DisabledStates: Story = {
|
|
|
64
64
|
</SBContainer>
|
|
65
65
|
),
|
|
66
66
|
};
|
|
67
|
+
|
|
68
|
+
export const InteractionStates: Story = {
|
|
69
|
+
name: 'Interaction States',
|
|
70
|
+
render: () => (
|
|
71
|
+
<SBContainer flex direction="column" gap="large">
|
|
72
|
+
<SBContainer addBackground>
|
|
73
|
+
<h4>Hover State</h4>
|
|
74
|
+
<p>Hover over the button to see the hover effect</p>
|
|
75
|
+
<Button buttonType="button" variant="primary">
|
|
76
|
+
Hover me
|
|
77
|
+
</Button>
|
|
78
|
+
</SBContainer>
|
|
79
|
+
|
|
80
|
+
<SBContainer addBackground>
|
|
81
|
+
<h4>Focus State</h4>
|
|
82
|
+
<p>
|
|
83
|
+
In production, this focus outline appears when navigating with the
|
|
84
|
+
keyboard (Tab key). This Storybook demo auto-applies the focus state
|
|
85
|
+
to show how it looks.
|
|
86
|
+
</p>
|
|
87
|
+
<SBFocusWrapper>
|
|
88
|
+
<Button buttonType="button" variant="primary">
|
|
89
|
+
Focused button
|
|
90
|
+
</Button>
|
|
91
|
+
</SBFocusWrapper>
|
|
92
|
+
</SBContainer>
|
|
93
|
+
</SBContainer>
|
|
94
|
+
),
|
|
95
|
+
};
|
|
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
2
2
|
import Button from '../index.js';
|
|
3
3
|
import { ButtonAsLinkProps } from '../types.js';
|
|
4
4
|
import { withButtonStyles } from './ButtonDecorator.js';
|
|
5
|
-
import { SBContainer } from '@sb-utils
|
|
5
|
+
import { SBContainer, SBFocusWrapper } from '@sb-utils';
|
|
6
6
|
|
|
7
7
|
const meta: Meta<ButtonAsLinkProps> = {
|
|
8
8
|
title: 'Component Library/Button/As Link',
|
|
@@ -68,3 +68,40 @@ export const LinkTargets: Story = {
|
|
|
68
68
|
</SBContainer>
|
|
69
69
|
),
|
|
70
70
|
};
|
|
71
|
+
|
|
72
|
+
export const InteractionStates: Story = {
|
|
73
|
+
name: 'Interaction States',
|
|
74
|
+
render: () => (
|
|
75
|
+
<SBContainer flex direction="column" gap="large">
|
|
76
|
+
<SBContainer addBackground>
|
|
77
|
+
<h4>Hover State</h4>
|
|
78
|
+
<p>Hover over the button to see the hover effect</p>
|
|
79
|
+
<Button
|
|
80
|
+
buttonType="link"
|
|
81
|
+
href="https://www.hubspot.com"
|
|
82
|
+
variant="primary"
|
|
83
|
+
>
|
|
84
|
+
Hover me
|
|
85
|
+
</Button>
|
|
86
|
+
</SBContainer>
|
|
87
|
+
|
|
88
|
+
<SBContainer addBackground>
|
|
89
|
+
<h4>Focus State</h4>
|
|
90
|
+
<p>
|
|
91
|
+
In production, this focus outline appears when navigating with the
|
|
92
|
+
keyboard (Tab key). This Storybook demo auto-applies the focus state
|
|
93
|
+
to show how it looks.
|
|
94
|
+
</p>
|
|
95
|
+
<SBFocusWrapper>
|
|
96
|
+
<Button
|
|
97
|
+
buttonType="link"
|
|
98
|
+
href="https://www.hubspot.com"
|
|
99
|
+
variant="primary"
|
|
100
|
+
>
|
|
101
|
+
Focused button
|
|
102
|
+
</Button>
|
|
103
|
+
</SBFocusWrapper>
|
|
104
|
+
</SBContainer>
|
|
105
|
+
</SBContainer>
|
|
106
|
+
),
|
|
107
|
+
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { ChoiceField, NumberField } from '@hubspot/cms-components/fields';
|
|
2
2
|
import { StyleFieldsProps } from './types.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const StyleFields = ({
|
|
5
5
|
variantLabel = 'Card Variant',
|
|
6
6
|
variantName = 'variant',
|
|
7
7
|
variantDefault = 'elevated',
|
|
8
8
|
borderRadiusLabel = 'Border Radius',
|
|
9
9
|
borderRadiusName = 'borderRadius',
|
|
10
10
|
borderRadiusDefault = 8,
|
|
11
|
-
}: StyleFieldsProps) {
|
|
11
|
+
}: StyleFieldsProps) => {
|
|
12
12
|
return (
|
|
13
13
|
<>
|
|
14
14
|
<ChoiceField
|
|
@@ -31,4 +31,6 @@ export default function StyleFields({
|
|
|
31
31
|
/>
|
|
32
32
|
</>
|
|
33
33
|
);
|
|
34
|
-
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default StyleFields;
|
|
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
2
2
|
import Card from '../index.js';
|
|
3
3
|
import { CardProps } from '../types.js';
|
|
4
4
|
import { withCardStyles } from './CardDecorator.js';
|
|
5
|
-
import { SBContainer } from '@sb-utils
|
|
5
|
+
import { SBContainer, SBFocusWrapper } from '@sb-utils';
|
|
6
6
|
|
|
7
7
|
const CardDivider = () => (
|
|
8
8
|
<hr
|
|
@@ -212,3 +212,48 @@ export const EdgeCases: Story = {
|
|
|
212
212
|
</SBContainer>
|
|
213
213
|
),
|
|
214
214
|
};
|
|
215
|
+
|
|
216
|
+
export const InteractionStates: Story = {
|
|
217
|
+
name: 'Interaction States (Wrapped in Link)',
|
|
218
|
+
render: () => (
|
|
219
|
+
<SBContainer flex direction="column" gap="large">
|
|
220
|
+
<SBContainer addBackground>
|
|
221
|
+
<h4>Clickable Card</h4>
|
|
222
|
+
<p>
|
|
223
|
+
Card wrapped in a link becomes clickable and shows hover/focus states
|
|
224
|
+
</p>
|
|
225
|
+
<a href="https://www.hubspot.com" style={{ textDecoration: 'none' }}>
|
|
226
|
+
<Card borderRadius={8}>
|
|
227
|
+
<CardHeading>Clickable Feature Card</CardHeading>
|
|
228
|
+
<CardDivider />
|
|
229
|
+
<CardContent>
|
|
230
|
+
This entire card is wrapped in a link. Click anywhere on the card
|
|
231
|
+
to navigate.
|
|
232
|
+
</CardContent>
|
|
233
|
+
</Card>
|
|
234
|
+
</a>
|
|
235
|
+
</SBContainer>
|
|
236
|
+
|
|
237
|
+
<SBContainer addBackground>
|
|
238
|
+
<h4>Focus State</h4>
|
|
239
|
+
<p>
|
|
240
|
+
In production, this focus outline appears when navigating with the
|
|
241
|
+
keyboard (Tab key). This Storybook demo auto-applies the focus state
|
|
242
|
+
to show how it looks.
|
|
243
|
+
</p>
|
|
244
|
+
<SBFocusWrapper>
|
|
245
|
+
<a href="https://www.hubspot.com" style={{ textDecoration: 'none' }}>
|
|
246
|
+
<Card borderRadius={8}>
|
|
247
|
+
<CardHeading>Focused Card</CardHeading>
|
|
248
|
+
<CardDivider />
|
|
249
|
+
<CardContent>
|
|
250
|
+
This card shows the focus outline when navigating with the
|
|
251
|
+
keyboard.
|
|
252
|
+
</CardContent>
|
|
253
|
+
</Card>
|
|
254
|
+
</a>
|
|
255
|
+
</SBFocusWrapper>
|
|
256
|
+
</SBContainer>
|
|
257
|
+
</SBContainer>
|
|
258
|
+
),
|
|
259
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ChoiceField, NumberField } from '@hubspot/cms-components/fields';
|
|
2
2
|
import { ContentFieldsProps } from './types.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const ContentFields = ({
|
|
5
5
|
orientationLabel = 'Orientation',
|
|
6
6
|
orientationName = 'orientation',
|
|
7
7
|
orientationDefault = 'horizontal',
|
|
@@ -14,7 +14,7 @@ export default function ContentFields({
|
|
|
14
14
|
thicknessLabel = 'Thickness',
|
|
15
15
|
thicknessName = 'thickness',
|
|
16
16
|
thicknessDefault = 1,
|
|
17
|
-
}: ContentFieldsProps) {
|
|
17
|
+
}: ContentFieldsProps) => {
|
|
18
18
|
return (
|
|
19
19
|
<>
|
|
20
20
|
<ChoiceField
|
|
@@ -58,4 +58,6 @@ export default function ContentFields({
|
|
|
58
58
|
/>
|
|
59
59
|
</>
|
|
60
60
|
);
|
|
61
|
-
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default ContentFields;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ChoiceField } from '@hubspot/cms-components/fields';
|
|
2
2
|
import { StyleFieldsProps } from './types.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const StyleFields = ({
|
|
5
5
|
borderStyleLabel = 'Border style',
|
|
6
6
|
borderStyleName = 'borderStyle',
|
|
7
7
|
borderStyleDefault = 'solid',
|
|
8
|
-
}: StyleFieldsProps) {
|
|
8
|
+
}: StyleFieldsProps) => {
|
|
9
9
|
return (
|
|
10
10
|
<>
|
|
11
11
|
<ChoiceField
|
|
@@ -22,4 +22,6 @@ export default function StyleFields({
|
|
|
22
22
|
/>
|
|
23
23
|
</>
|
|
24
24
|
);
|
|
25
|
-
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default StyleFields;
|