@hubspot/cms-component-library 0.3.4 → 0.3.5

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.
@@ -1,31 +1,13 @@
1
- import { TextField, ChoiceField } from '@hubspot/cms-components/fields';
1
+ import { TextField } 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
- iconLabel = 'Icon',
9
- iconName = 'icon',
10
- iconDefault = 'chevron',
11
8
  }: ContentFieldsProps) => {
12
9
  return (
13
- <>
14
- <ChoiceField
15
- label={iconLabel}
16
- name={iconName}
17
- display="buttons"
18
- choices={[
19
- ['chevron', 'Chevron'],
20
- ['plus', 'Plus'],
21
- ['caret', 'Caret'],
22
- ]}
23
- preset="expand_icon"
24
- required={false}
25
- default={iconDefault}
26
- />
27
- <TextField label={titleLabel} name={titleName} default={titleDefault} />
28
- </>
10
+ <TextField label={titleLabel} name={titleName} default={titleDefault} />
29
11
  );
30
12
  };
31
13
 
@@ -0,0 +1,26 @@
1
+ import { ChoiceField } from '@hubspot/cms-components/fields';
2
+ import type { StyleFieldsProps } from './types.js';
3
+
4
+ const StyleFields = ({
5
+ iconLabel = 'Icon',
6
+ iconName = 'icon',
7
+ iconDefault = 'chevron',
8
+ }: StyleFieldsProps) => {
9
+ return (
10
+ <ChoiceField
11
+ label={iconLabel}
12
+ name={iconName}
13
+ display="buttons"
14
+ choices={[
15
+ ['caret', 'Caret'],
16
+ ['chevron', 'Chevron'],
17
+ ['plus', 'Plus'],
18
+ ]}
19
+ preset="expand_icon"
20
+ required={false}
21
+ default={iconDefault}
22
+ />
23
+ );
24
+ };
25
+
26
+ export default StyleFields;
@@ -1,5 +1,6 @@
1
1
  import styles from './index.module.scss';
2
2
  import ContentFields from './ContentFields.js';
3
+ import StyleFields from './StyleFields.js';
3
4
  import cx from '../../utils/classname.js';
4
5
  import { AccordionTitleProps } from './types.js';
5
6
  import { ChevronIcon, PlusIcon, MinusIcon, CaretIcon } from './icons.js';
@@ -39,9 +40,11 @@ const AccordionTitleComponent = ({
39
40
 
40
41
  type AccordionTitleComponentType = typeof AccordionTitleComponent & {
41
42
  ContentFields: typeof ContentFields;
43
+ StyleFields: typeof StyleFields;
42
44
  };
43
45
 
44
46
  const AccordionTitle = AccordionTitleComponent as AccordionTitleComponentType;
45
47
  AccordionTitle.ContentFields = ContentFields;
48
+ AccordionTitle.StyleFields = StyleFields;
46
49
 
47
50
  export default AccordionTitle;
@@ -11,6 +11,9 @@ export type ContentFieldsProps = {
11
11
  titleLabel?: string;
12
12
  titleName?: string;
13
13
  titleDefault?: string;
14
+ };
15
+
16
+ export type StyleFieldsProps = {
14
17
  iconLabel?: string;
15
18
  iconName?: string;
16
19
  iconDefault?: AccordionIconType;
@@ -52,7 +52,8 @@ Accordion/
52
52
  ├── AccordionTitle/
53
53
  │ ├── index.tsx # AccordionTitle component
54
54
  │ ├── types.ts # AccordionTitle TypeScript types
55
- │ ├── ContentFields.tsx # HubSpot field definitions for title/icon
55
+ │ ├── ContentFields.tsx # HubSpot field definitions for title text
56
+ │ ├── StyleFields.tsx # HubSpot field definitions for icon
56
57
  │ ├── icons.tsx # SVG icon components (Chevron, Plus, Minus)
57
58
  │ └── index.module.scss # CSS module for title styling
58
59
  ├── AccordionContent/
@@ -228,13 +229,25 @@ Configurable props for variant selection:
228
229
 
229
230
  #### AccordionTitle.ContentFields
230
231
 
231
- Configurable props for title text and icon:
232
+ Configurable props for title text:
232
233
 
233
234
  ```tsx
234
235
  <AccordionTitle.ContentFields
235
236
  titleName="title"
236
237
  titleLabel="Title"
237
238
  titleDefault="Accordion Title"
239
+ />
240
+ ```
241
+
242
+ **Fields:**
243
+ - `title`: TextField for accordion title text
244
+
245
+ #### AccordionTitle.StyleFields
246
+
247
+ Configurable props for icon style:
248
+
249
+ ```tsx
250
+ <AccordionTitle.StyleFields
238
251
  iconName="icon"
239
252
  iconLabel="Icon"
240
253
  iconDefault="chevron"
@@ -242,7 +255,6 @@ Configurable props for title text and icon:
242
255
  ```
243
256
 
244
257
  **Fields:**
245
- - `title`: TextField for accordion title text
246
258
  - `icon`: ChoiceField for selecting icon type (caret, chevron, plus)
247
259
 
248
260
  #### AccordionContent.ContentFields
@@ -275,11 +287,11 @@ import { AccordionIconType } from '@hubspot/cms-component-library/Accordion/Acco
275
287
  type FAQModuleProps = {
276
288
  style?: {
277
289
  variant?: AccordionVariant;
290
+ icon?: AccordionIconType;
278
291
  };
279
292
  accordionItems?: Array<{
280
293
  title?: string;
281
294
  content?: string;
282
- icon?: AccordionIconType;
283
295
  }>;
284
296
  };
285
297
 
@@ -288,10 +300,11 @@ export const Component = ({
288
300
  accordionItems = [],
289
301
  }: FAQModuleProps) => {
290
302
  const variant = style?.variant;
303
+ const icon = style?.icon;
291
304
 
292
305
  return (
293
306
  <Accordion>
294
- {accordionItems.map(({ title, content, icon }, index) => (
307
+ {accordionItems.map(({ title, content }, index) => (
295
308
  <AccordionItem key={index} variant={variant}>
296
309
  <AccordionTitle icon={icon}>{title}</AccordionTitle>
297
310
  <AccordionContent>{content}</AccordionContent>
@@ -326,7 +339,6 @@ import {
326
339
  const defaultItem = {
327
340
  title: 'Accordion Title',
328
341
  content: '<p>Accordion content goes here. You can add multiple lines of text.</p>',
329
- icon: 'chevron',
330
342
  };
331
343
 
332
344
  export const fields = (
@@ -342,6 +354,7 @@ export const fields = (
342
354
  </RepeatedFieldGroup>
343
355
  <FieldGroup label="Style" name="style" tab="STYLE">
344
356
  <AccordionItem.StyleFields />
357
+ <AccordionTitle.StyleFields />
345
358
  </FieldGroup>
346
359
  </ModuleFields>
347
360
  );
@@ -0,0 +1,19 @@
1
+ import { FormField } from '@hubspot/cms-components/fields';
2
+ import { ContentFieldsProps } from './types.js';
3
+
4
+ const ContentFields = ({
5
+ formIdLabel = 'Form',
6
+ formIdName = 'form',
7
+ formIdDefault = {},
8
+ }: ContentFieldsProps) => {
9
+ return (
10
+ <FormField
11
+ label={formIdLabel}
12
+ name={formIdName}
13
+ embedVersions={['v4']}
14
+ default={formIdDefault}
15
+ />
16
+ );
17
+ };
18
+
19
+ export default ContentFields;
@@ -0,0 +1,18 @@
1
+ // @ts-expect-error -- ?island not typed
2
+ import FormIsland from './islands/FormIsland.js?island';
3
+ import { FormProps } from './types.js';
4
+ import { Island } from '@hubspot/cms-components';
5
+ import ContentFields from './ContentFields.js';
6
+
7
+ const FormComponent = (props: FormProps) => {
8
+ return <Island module={FormIsland} {...props} />;
9
+ };
10
+
11
+ type FormComponentType = typeof FormComponent & {
12
+ ContentFields: typeof ContentFields;
13
+ };
14
+
15
+ const Form = FormComponent as FormComponentType;
16
+ Form.ContentFields = ContentFields;
17
+
18
+ export default Form;
@@ -0,0 +1,54 @@
1
+ import { useEffect } from 'react';
2
+ import { FormProps, InternalFormProps } from '../types.js';
3
+ import { getHubID } from '@hubspot/cms-components';
4
+
5
+ const getScriptSrc = (portalId: number, env: string) => {
6
+ const host = env === 'qa' ? 'js.hsformsqa.net' : 'js.hsforms.net';
7
+ return `https://${host}/forms/embed/${portalId}.js`;
8
+ };
9
+
10
+ const FormIsland = ({ formId, env }: FormProps & InternalFormProps) => {
11
+ const portalId = getHubID();
12
+ const resolvedEnv = env === 'qa' ? env : 'prod';
13
+
14
+ useEffect(() => {
15
+ if (!formId || !portalId) {
16
+ return;
17
+ }
18
+
19
+ const scriptSrc = getScriptSrc(portalId, resolvedEnv);
20
+ const existingScript = document.querySelector(`script[src="${scriptSrc}"]`);
21
+
22
+ if (existingScript) {
23
+ return;
24
+ }
25
+
26
+ const script = document.createElement('script');
27
+ script.src = scriptSrc;
28
+ document.head.appendChild(script);
29
+
30
+ return () => {
31
+ script.remove();
32
+ };
33
+ }, [formId, portalId, resolvedEnv]);
34
+
35
+ if (!formId || !portalId) {
36
+ return null;
37
+ }
38
+
39
+ /*
40
+ <script src="https://js.hsformsqa.net/forms/embed/102771136.js" defer></script>
41
+ <div class="hs-form-frame" data-env="qa" data-region="na1" data-form-id="53e5b258-4526-4012-9274-8bbe23ab2d09" data-portal-id="102771136"></div>
42
+ */
43
+
44
+ return (
45
+ <div
46
+ className="hs-form-frame"
47
+ data-form-id={formId}
48
+ data-portal-id={portalId}
49
+ data-env={resolvedEnv}
50
+ />
51
+ );
52
+ };
53
+
54
+ export default FormIsland;
@@ -0,0 +1,3 @@
1
+ .form {
2
+ width: var(--hscl-form-width, 100%);
3
+ }
@@ -0,0 +1,13 @@
1
+ import { FormFieldDefaults } from '@hubspot/cms-components/fields';
2
+ export type InternalFormProps = {
3
+ env?: 'qa' | 'prod';
4
+ };
5
+ export type FormProps = {
6
+ formId: string;
7
+ };
8
+
9
+ export type ContentFieldsProps = {
10
+ formIdLabel?: string;
11
+ formIdName?: string;
12
+ formIdDefault?: typeof FormFieldDefaults;
13
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cms-component-library",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "HubSpot CMS React component library for building CMS modules",
5
5
  "license": "Apache-2.0",
6
6
  "exports": {