@hubspot/cms-component-library 0.1.0-alpha.1 → 0.1.0-alpha.11

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 (82) hide show
  1. package/components/componentLibrary/Button/ContentFields.tsx +54 -0
  2. package/components/componentLibrary/Button/StyleFields.tsx +28 -0
  3. package/components/componentLibrary/Button/index.module.scss +48 -6
  4. package/components/componentLibrary/Button/index.tsx +103 -47
  5. package/components/componentLibrary/Button/llm.txt +405 -0
  6. package/components/componentLibrary/Button/types.ts +65 -0
  7. package/components/componentLibrary/Divider/ContentFields.tsx +63 -0
  8. package/components/componentLibrary/Divider/StyleFields.tsx +27 -0
  9. package/components/componentLibrary/Divider/index.module.scss +31 -0
  10. package/components/componentLibrary/Divider/index.tsx +75 -0
  11. package/components/componentLibrary/Divider/llm.txt +44 -0
  12. package/components/componentLibrary/Divider/types.ts +43 -0
  13. package/components/componentLibrary/Flex/index.module.scss +20 -0
  14. package/components/componentLibrary/Flex/index.tsx +64 -0
  15. package/components/componentLibrary/Flex/types.ts +63 -0
  16. package/components/componentLibrary/Grid/index.module.scss +71 -0
  17. package/components/componentLibrary/Grid/index.tsx +93 -0
  18. package/components/componentLibrary/Grid/types.ts +55 -0
  19. package/components/componentLibrary/Heading/ContentFields.tsx +36 -0
  20. package/components/componentLibrary/Heading/StyleFields.tsx +39 -0
  21. package/components/componentLibrary/Heading/index.module.scss +10 -8
  22. package/components/componentLibrary/Heading/index.tsx +40 -19
  23. package/components/componentLibrary/Heading/types.ts +35 -0
  24. package/components/componentLibrary/Icon/ContentFields.tsx +52 -0
  25. package/components/componentLibrary/Icon/index.module.scss +9 -0
  26. package/components/componentLibrary/Icon/index.tsx +42 -0
  27. package/components/componentLibrary/Icon/types.ts +35 -0
  28. package/components/componentLibrary/Image/ContentFields.tsx +32 -0
  29. package/components/componentLibrary/Image/index.module.scss +13 -0
  30. package/components/componentLibrary/Image/index.tsx +49 -0
  31. package/components/componentLibrary/Image/types.ts +23 -0
  32. package/components/componentLibrary/List/ContentFields.tsx +20 -0
  33. package/components/componentLibrary/List/ListItem/ContentFields.tsx +23 -0
  34. package/components/componentLibrary/List/ListItem/index.module.scss +18 -0
  35. package/components/componentLibrary/List/ListItem/index.tsx +53 -0
  36. package/components/componentLibrary/List/ListItem/types.ts +26 -0
  37. package/components/componentLibrary/List/StyleFields.tsx +21 -0
  38. package/components/componentLibrary/List/index.module.scss +5 -0
  39. package/components/componentLibrary/List/index.tsx +51 -0
  40. package/components/componentLibrary/List/types.ts +24 -0
  41. package/components/componentLibrary/_patterns/README.md +44 -0
  42. package/components/componentLibrary/_patterns/checklist-and-examples.md +202 -0
  43. package/components/componentLibrary/_patterns/component-structure.md +275 -0
  44. package/components/componentLibrary/_patterns/css-patterns.md +230 -0
  45. package/components/componentLibrary/_patterns/field-patterns.md +161 -0
  46. package/components/componentLibrary/_patterns/llm-txt.template.md +266 -0
  47. package/components/componentLibrary/_patterns/storybook-patterns.md +247 -0
  48. package/components/componentLibrary/_patterns/typescript-patterns.md +156 -0
  49. package/components/componentLibrary/utils/linkField.ts +55 -0
  50. package/components/componentLibrary/utils/types.ts +5 -0
  51. package/index.ts +1 -0
  52. package/package.json +5 -20
  53. package/cli/commands/customize.ts +0 -145
  54. package/cli/commands/help.ts +0 -56
  55. package/cli/commands/version.ts +0 -12
  56. package/cli/index.ts +0 -42
  57. package/cli/tests/commands.test.ts +0 -128
  58. package/cli/tests/get-file.test.ts +0 -82
  59. package/cli/tests/version-integration.test.ts +0 -39
  60. package/cli/utils/cli-metadata.ts +0 -9
  61. package/cli/utils/component-naming.ts +0 -76
  62. package/cli/utils/components.ts +0 -74
  63. package/cli/utils/file-operations.ts +0 -158
  64. package/cli/utils/logging.ts +0 -13
  65. package/cli/utils/prompts.ts +0 -80
  66. package/cli/utils/version.ts +0 -33
  67. package/components/componentLibrary/Button/scaffolds/fields.tsx.template +0 -70
  68. package/components/componentLibrary/Button/scaffolds/index.ts.template +0 -95
  69. package/components/componentLibrary/Heading/scaffolds/fields.tsx.template +0 -62
  70. package/components/componentLibrary/Heading/scaffolds/index.ts.template +0 -46
  71. package/components/componentLibrary/index.ts +0 -1
  72. package/components/componentLibrary/styles/_component-base.scss +0 -246
  73. package/components/componentLibrary/types/index.ts +0 -308
  74. package/components/componentLibrary/utils/chainApi/choiceFieldGenerator.tsx +0 -64
  75. package/components/componentLibrary/utils/chainApi/index.ts +0 -115
  76. package/components/componentLibrary/utils/chainApi/labelGenerator.ts +0 -76
  77. package/components/componentLibrary/utils/chainApi/stateManager.ts +0 -178
  78. package/components/componentLibrary/utils/createConditionalClasses.ts +0 -44
  79. package/components/componentLibrary/utils/createHsclComponent.tsx +0 -167
  80. package/components/componentLibrary/utils/propResolution/createCssVariables.ts +0 -58
  81. package/components/componentLibrary/utils/propResolution/propResolutionUtils.ts +0 -113
  82. package/components/componentLibrary/utils/storybook/standardArgs.ts +0 -607
@@ -0,0 +1,54 @@
1
+ import { TextField, LinkField } from '@hubspot/cms-components/fields';
2
+ import Icon from '../Icon/index.js';
3
+ import { ContentFieldsProps } from './types.js';
4
+
5
+ export default function ContentFields(props: ContentFieldsProps) {
6
+ const {
7
+ buttonTextLabel = 'Button Text',
8
+ buttonTextName = 'buttonText',
9
+ buttonTextDefault = 'Click me',
10
+ buttonLinkLabel = 'Button Link',
11
+ buttonLinkName = 'buttonLink',
12
+ buttonLinkDefault = {
13
+ url: {
14
+ type: 'EXTERNAL',
15
+ content_id: null,
16
+ href: 'https://www.hubspot.com',
17
+ },
18
+ },
19
+ showButtonLink = true,
20
+ iconLabel,
21
+ iconName,
22
+ iconDefault,
23
+ showIconLabel = 'Show Button Icon',
24
+ showIconName,
25
+ showIconDefault,
26
+ } = props;
27
+
28
+ const iconContentFieldsProps = {
29
+ iconLabel,
30
+ iconName,
31
+ iconDefault,
32
+ showIconLabel,
33
+ showIconName,
34
+ showIconDefault,
35
+ };
36
+
37
+ return (
38
+ <>
39
+ <TextField
40
+ label={buttonTextLabel}
41
+ name={buttonTextName}
42
+ default={buttonTextDefault}
43
+ />
44
+ {showButtonLink && (
45
+ <LinkField
46
+ label={buttonLinkLabel}
47
+ name={buttonLinkName}
48
+ default={buttonLinkDefault}
49
+ />
50
+ )}
51
+ <Icon.ContentFields addIconToggle={true} {...iconContentFieldsProps} />
52
+ </>
53
+ );
54
+ }
@@ -0,0 +1,28 @@
1
+ import { ChoiceField } from '@hubspot/cms-components/fields';
2
+
3
+ export default function StyleFields(props: {
4
+ buttonVariantLabel?: string;
5
+ buttonVariantName?: string;
6
+ buttonVariantDefault?: string;
7
+ }) {
8
+ const {
9
+ buttonVariantLabel = 'Button Variant',
10
+ buttonVariantName = 'buttonVariant',
11
+ buttonVariantDefault = 'primary',
12
+ } = props;
13
+
14
+ return (
15
+ <>
16
+ <ChoiceField
17
+ label={buttonVariantLabel}
18
+ name={buttonVariantName}
19
+ choices={[
20
+ ['primary', 'Primary'],
21
+ ['secondary', 'Secondary'],
22
+ ['tertiary', 'Tertiary'],
23
+ ]}
24
+ default={buttonVariantDefault}
25
+ />
26
+ </>
27
+ );
28
+ }
@@ -1,9 +1,51 @@
1
- @use '../styles/_component-base';
1
+ // CSS variables that can be mapped to theme settings
2
+ .button {
3
+ display: inline-flex;
4
+ flex-direction: row;
5
+ align-items: center;
6
+ justify-content: center;
7
+ text-decoration: none;
8
+ gap: var(--hscl-button-gap, 8px);
9
+ background-color: var(--hscl-button-backgroundColor);
10
+ color: var(--hscl-button-color);
11
+ padding: var(--hscl-button-paddingBlock) var(--hscl-button-paddingInline);
12
+ border-radius: var(--hscl-button-borderRadius);
13
+ border: var(--hscl-button-borderWidth) solid var(--hscl-button-borderColor);
14
+ font-size: var(--hscl-button-fontSize);
15
+ font-weight: var(--hscl-button-fontWeight);
16
+ cursor: pointer;
17
+ transition: all 0.2s ease;
18
+ text-decoration: none;
19
+
20
+ &: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
+ text-decoration: none;
26
+ }
27
+
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);
35
+ }
36
+
37
+ &:disabled {
38
+ opacity: 0.5;
39
+ cursor: not-allowed;
40
+ }
2
41
 
3
- @layer hscl-library {
4
- .button {
5
42
 
6
- @include component-base.hscl-component-conditional('button');
7
- @include component-base.hscl-component-hover-conditional('button');
43
+ svg {
44
+ display: inline-flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ fill: var(--hscl-button-icon-fill);
8
48
  }
9
- }
49
+ }
50
+
51
+
@@ -1,69 +1,120 @@
1
- /* eslint-disable */
2
-
3
- import createHsclComponent from '../utils/createHsclComponent.js';
4
1
  import styles from './index.module.scss';
5
- import { BaseAndInternalComponentProps } from '../types/index.js';
6
-
7
- // Base props shared by all variants
8
- type BaseButtonProps = BaseAndInternalComponentProps & {
9
- disabled?: boolean;
10
- children?: React.ReactNode;
11
- };
12
-
13
- // Button variant props
14
- type ButtonVariantProps = {
15
- buttonType: 'button';
16
- onClick?: () => void;
17
- };
2
+ import Icon from '../Icon/index.js';
3
+ import ContentFields from './ContentFields.js';
4
+ import StyleFields from './StyleFields.js';
5
+ import cx from '../utils/classname.js';
6
+ import {
7
+ ButtonProps,
8
+ ButtonAsButtonProps,
9
+ ButtonAsLinkProps,
10
+ BaseButtonProps,
11
+ RenderWithIconProps,
12
+ } from './types.js';
18
13
 
19
- // Link variant props
20
- type LinkVariantProps = {
21
- buttonType: 'link';
22
- href?: string;
23
- target?: string;
24
- rel?: string;
25
- };
26
-
27
- // Main component props using discriminated union
28
- export type ButtonProps = BaseButtonProps &
29
- (ButtonVariantProps | LinkVariantProps);
30
-
31
- const componentName = 'button';
32
-
33
- const Component = (props: ButtonProps) => {
34
- // Extract shared/base props that are always consumed
14
+ const ButtonComponent = (props: ButtonProps) => {
35
15
  const {
36
16
  buttonType = 'link',
37
- hsclInternal: { hsclProcessedClasses, hsclProcessedStyles },
17
+ variant = 'primary',
18
+ className = '',
19
+ style = {},
38
20
  ...rest
39
21
  } = props;
40
22
 
41
- // Shared props for both elements
23
+ const variantClass = styles[`hscl-button-${variant}`]; // !todo: not used atm but keeping for when we need to add variant system.
24
+ const defaultClasses = cx(styles.button, variantClass);
42
25
  const sharedProps = {
43
- className: hsclProcessedClasses,
44
- style: hsclProcessedStyles,
26
+ className: cx(defaultClasses, className),
27
+ style: style,
28
+ };
29
+
30
+ const RenderWithIcon = ({
31
+ iconFieldPath,
32
+ iconSize,
33
+ showIcon,
34
+ iconPurpose,
35
+ iconTitle,
36
+ iconPosition = 'right',
37
+ children,
38
+ }: RenderWithIconProps) => {
39
+ if (!iconFieldPath) return <>{children}</>;
40
+
41
+ const icon = (
42
+ <Icon
43
+ fieldPath={iconFieldPath}
44
+ height={iconSize}
45
+ className={styles.icon}
46
+ showIcon={showIcon}
47
+ purpose={iconPurpose}
48
+ title={iconTitle}
49
+ />
50
+ );
51
+
52
+ return (
53
+ <>
54
+ {iconPosition === 'left' && icon}
55
+ {children}
56
+ {iconPosition === 'right' && icon}
57
+ </>
58
+ );
45
59
  };
46
60
 
47
61
  function renderButton(
48
- props: Omit<ButtonVariantProps, 'buttonType' | 'hsclInternal'> &
49
- Partial<BaseButtonProps>
62
+ props: Omit<ButtonAsButtonProps, 'buttonType'> & Partial<BaseButtonProps>
50
63
  ) {
51
- const { onClick, disabled = false, children, ...rest } = props;
64
+ const {
65
+ onClick,
66
+ disabled = false,
67
+ children,
68
+ iconPosition = 'right',
69
+ iconFieldPath,
70
+ iconSize = 18,
71
+ showIcon,
72
+ iconPurpose,
73
+ iconTitle,
74
+ ...rest
75
+ } = props;
76
+ const iconProps = {
77
+ iconFieldPath,
78
+ iconSize,
79
+ showIcon,
80
+ iconPurpose,
81
+ iconTitle,
82
+ iconPosition,
83
+ };
52
84
  return (
53
85
  <button {...sharedProps} onClick={onClick} disabled={disabled} {...rest}>
54
- {children}
86
+ <RenderWithIcon {...iconProps}>{children}</RenderWithIcon>
55
87
  </button>
56
88
  );
57
89
  }
58
90
 
59
91
  function renderLink(
60
- props: Omit<LinkVariantProps, 'buttonType' | 'hsclInternal'> &
61
- Partial<BaseButtonProps>
92
+ props: Omit<ButtonAsLinkProps, 'buttonType'> & Partial<BaseButtonProps>
62
93
  ) {
63
- const { href = '', target = '_self', rel = '', children, ...rest } = props;
94
+ const {
95
+ href = '',
96
+ target = '_self',
97
+ rel = '',
98
+ children,
99
+ iconPosition = 'right',
100
+ iconFieldPath,
101
+ iconSize = 18,
102
+ showIcon,
103
+ iconPurpose,
104
+ iconTitle,
105
+ ...rest
106
+ } = props;
107
+ const iconProps = {
108
+ iconFieldPath,
109
+ iconSize,
110
+ showIcon,
111
+ iconPurpose,
112
+ iconTitle,
113
+ iconPosition,
114
+ };
64
115
  return (
65
116
  <a {...sharedProps} href={href} target={target} rel={rel} {...rest}>
66
- {children}
117
+ <RenderWithIcon {...iconProps}>{children}</RenderWithIcon>
67
118
  </a>
68
119
  );
69
120
  }
@@ -75,9 +126,14 @@ const Component = (props: ButtonProps) => {
75
126
  return renderLink(rest);
76
127
  };
77
128
 
78
- Component.hsclComponentName = componentName;
79
- Component.cssModule = styles;
129
+ // Create compound component with proper typing
130
+ type ButtonComponentType = typeof ButtonComponent & {
131
+ ContentFields: typeof ContentFields;
132
+ StyleFields: typeof StyleFields;
133
+ };
80
134
 
81
- const Button = createHsclComponent(Component);
135
+ const Button = ButtonComponent as ButtonComponentType;
136
+ Button.ContentFields = ContentFields;
137
+ Button.StyleFields = StyleFields;
82
138
 
83
139
  export default Button;