@hashicorp/react-components 1.1.10 → 1.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.
Files changed (173) hide show
  1. package/README.md +1 -1
  2. package/package.json +8 -13
  3. package/postcss.config.js +1 -1
  4. package/src/components/nav-panel/components/flight-icon/index.tsx +53 -0
  5. package/src/components/nav-panel/components/flight-icon/style.module.css +3 -0
  6. package/src/components/nav-panel/components/link/cloud-fill.svg +3 -0
  7. package/src/components/nav-panel/components/link/index.tsx +139 -0
  8. package/src/components/nav-panel/components/link/layers-fill.svg +5 -0
  9. package/src/components/nav-panel/components/link/shield-alert-fill.svg +3 -0
  10. package/src/components/nav-panel/components/link/style.module.css +64 -0
  11. package/src/components/nav-panel/components/link/zap-fill.svg +3 -0
  12. package/src/components/nav-panel/components/link-list/index.tsx +12 -64
  13. package/src/components/nav-panel/components/link-list/style.module.css +1 -50
  14. package/src/components/nav-panel/components/panel/column/style.module.css +2 -2
  15. package/src/components/nav-panel/components/panel/root/style.module.css +5 -5
  16. package/src/components/nav-panel/components/promo/index.tsx +35 -15
  17. package/src/components/nav-panel/components/promo/style.module.css +32 -28
  18. package/src/components/nav-panel/components/text/index.tsx +34 -0
  19. package/src/components/nav-panel/product-panel/index.tsx +71 -20
  20. package/src/components/nav-panel/product-panel/style.module.css +111 -53
  21. package/src/components/nav-panel/standard-panel/index.tsx +3 -0
  22. package/src/components/nav-panel/standard-panel/style.module.css +2 -2
  23. package/src/lib/get-localized-link-props/index.test.ts +30 -0
  24. package/src/lib/get-localized-link-props/index.ts +45 -0
  25. package/src/lib/parse-url/index.test.ts +57 -2
  26. package/src/lib/parse-url/index.ts +97 -13
  27. package/src/lib/send-posthog-event/index.ts +22 -0
  28. package/src/lib/supported-locales/index.ts +10 -0
  29. package/src/lib/track-nav-click-event/index.ts +5 -5
  30. package/src/lib/v/index.ts +9 -4
  31. package/tsconfig.json +1 -2
  32. package/.eslintrc.js +0 -4
  33. package/.stylelintrc.js +0 -3
  34. package/src/components/actions/index.tsx +0 -107
  35. package/src/components/actions/style.module.css +0 -28
  36. package/src/components/actions/types.ts +0 -73
  37. package/src/components/call-to-action/index.tsx +0 -205
  38. package/src/components/call-to-action/styles/variant-centered.module.css +0 -93
  39. package/src/components/call-to-action/styles/variant-compact-grid.module.css +0 -88
  40. package/src/components/call-to-action/styles/variant-compact.module.css +0 -91
  41. package/src/components/call-to-action/styles/variant-links.module.css +0 -85
  42. package/src/components/card/README.md +0 -11
  43. package/src/components/card/card.tsx +0 -45
  44. package/src/components/card/index.test.tsx +0 -69
  45. package/src/components/card/index.tsx +0 -14
  46. package/src/components/card/newsroom-card/index.test.tsx +0 -39
  47. package/src/components/card/newsroom-card/index.tsx +0 -37
  48. package/src/components/card/newsroom-card/style.module.css +0 -12
  49. package/src/components/card/partner-card/index.test.tsx +0 -57
  50. package/src/components/card/partner-card/index.tsx +0 -69
  51. package/src/components/card/partner-card/style.module.css +0 -24
  52. package/src/components/card/person-card/index.test.tsx +0 -71
  53. package/src/components/card/person-card/index.tsx +0 -93
  54. package/src/components/card/person-card/style.module.css +0 -33
  55. package/src/components/card/primitives.tsx +0 -176
  56. package/src/components/card/promo-card/index.tsx +0 -51
  57. package/src/components/card/resource-card/index.test.tsx +0 -48
  58. package/src/components/card/resource-card/index.tsx +0 -37
  59. package/src/components/card/style.module.css +0 -145
  60. package/src/components/card/types.ts +0 -66
  61. package/src/components/card/unified-card/index.tsx +0 -64
  62. package/src/components/consent-manager/README.md +0 -73
  63. package/src/components/consent-manager/components/banner/banner.module.css +0 -23
  64. package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
  65. package/src/components/consent-manager/components/banner/banner.tsx +0 -73
  66. package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
  67. package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
  68. package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
  69. package/src/components/consent-manager/img/icn_close.tsx +0 -19
  70. package/src/components/consent-manager/index.test.tsx +0 -334
  71. package/src/components/consent-manager/index.tsx +0 -186
  72. package/src/components/consent-manager/loader/README.md +0 -29
  73. package/src/components/consent-manager/loader/categories.ts +0 -22
  74. package/src/components/consent-manager/loader/index.tsx +0 -94
  75. package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
  76. package/src/components/consent-manager/loader/presets/oss.ts +0 -10
  77. package/src/components/consent-manager/loader/services.ts +0 -45
  78. package/src/components/consent-manager/scripts/custom.tsx +0 -59
  79. package/src/components/consent-manager/scripts/segment.tsx +0 -87
  80. package/src/components/consent-manager/style.module.css +0 -9
  81. package/src/components/consent-manager/types.ts +0 -55
  82. package/src/components/consent-manager/util/cookies.test.ts +0 -75
  83. package/src/components/consent-manager/util/cookies.ts +0 -70
  84. package/src/components/consent-manager/util/integrations.test.ts +0 -115
  85. package/src/components/consent-manager/util/integrations.ts +0 -110
  86. package/src/components/intro/index.tsx +0 -82
  87. package/src/components/intro/style.module.css +0 -67
  88. package/src/components/intro/types.ts +0 -44
  89. package/src/components/marketo-form/CHANGELOG.md +0 -122
  90. package/src/components/marketo-form/README.md +0 -1
  91. package/src/components/marketo-form/contexts/FormMetadata.ts +0 -11
  92. package/src/components/marketo-form/docs.mdx +0 -197
  93. package/src/components/marketo-form/fixtures/index.ts +0 -185
  94. package/src/components/marketo-form/form/index.tsx +0 -369
  95. package/src/components/marketo-form/index.test.tsx +0 -320
  96. package/src/components/marketo-form/index.ts +0 -11
  97. package/src/components/marketo-form/package.original.json +0 -30
  98. package/src/components/marketo-form/partials/error-message/index.tsx +0 -12
  99. package/src/components/marketo-form/partials/error-message/style.module.css +0 -13
  100. package/src/components/marketo-form/partials/field/index.tsx +0 -90
  101. package/src/components/marketo-form/partials/field-wrapper/index.tsx +0 -26
  102. package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +0 -32
  103. package/src/components/marketo-form/partials/fields/email-field/index.tsx +0 -35
  104. package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +0 -21
  105. package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +0 -37
  106. package/src/components/marketo-form/partials/fields/htmltext-field/index.tsx +0 -21
  107. package/src/components/marketo-form/partials/fields/htmltext-field/style.module.css +0 -18
  108. package/src/components/marketo-form/partials/fields/name-field/index.tsx +0 -19
  109. package/src/components/marketo-form/partials/fields/name-field/style.module.css +0 -13
  110. package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +0 -48
  111. package/src/components/marketo-form/partials/fields/select-field/index.tsx +0 -39
  112. package/src/components/marketo-form/partials/fields/select-field/style.module.css +0 -5
  113. package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +0 -30
  114. package/src/components/marketo-form/partials/fields/text-field/index.tsx +0 -30
  115. package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +0 -29
  116. package/src/components/marketo-form/partials/label/index.tsx +0 -24
  117. package/src/components/marketo-form/partials/label/style.module.css +0 -12
  118. package/src/components/marketo-form/partials/visibility-rule/index.tsx +0 -84
  119. package/src/components/marketo-form/props.js +0 -66
  120. package/src/components/marketo-form/server/api-routes.ts +0 -109
  121. package/src/components/marketo-form/server/client.ts +0 -98
  122. package/src/components/marketo-form/server/index.ts +0 -8
  123. package/src/components/marketo-form/types.ts +0 -268
  124. package/src/components/marketo-form/utils.test.tsx +0 -103
  125. package/src/components/marketo-form/utils.ts +0 -449
  126. package/src/components/next-steps/index.tsx +0 -137
  127. package/src/components/next-steps/style.module.css +0 -270
  128. package/src/components/next-steps/types.ts +0 -63
  129. package/src/components/product-badge/index.test.tsx +0 -11
  130. package/src/components/product-badge/index.tsx +0 -42
  131. package/src/components/product-badge/style.module.css +0 -76
  132. package/src/components/products-used/index.tsx +0 -84
  133. package/src/components/products-used/style.module.css +0 -87
  134. package/src/components/products-used/types.ts +0 -31
  135. package/src/components/related-content/index.test.tsx +0 -74
  136. package/src/components/related-content/index.tsx +0 -56
  137. package/src/components/related-content/style.module.css +0 -89
  138. package/src/components/related-content/types.ts +0 -21
  139. package/src/components/subnav/helpers/areBasePathsMatching.ts +0 -13
  140. package/src/components/subnav/helpers/traverse/index.ts +0 -42
  141. package/src/components/subnav/helpers/useHeightRef.ts +0 -42
  142. package/src/components/subnav/helpers/useNavRef.ts +0 -30
  143. package/src/components/subnav/helpers/useOverflowRef.ts +0 -85
  144. package/src/components/subnav/helpers/useStuckRef.ts +0 -51
  145. package/src/components/subnav/index.tsx +0 -199
  146. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.test.ts +0 -26
  147. package/src/components/subnav/partials/CtaLinks/github-stars-link/formatStarCount/index.ts +0 -22
  148. package/src/components/subnav/partials/CtaLinks/github-stars-link/index.tsx +0 -87
  149. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.test.ts +0 -29
  150. package/src/components/subnav/partials/CtaLinks/github-stars-link/parseGithubUrl/index.ts +0 -32
  151. package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +0 -85
  152. package/src/components/subnav/partials/CtaLinks/icons/github-logo.js +0 -20
  153. package/src/components/subnav/partials/CtaLinks/icons/github.svg.js +0 -7
  154. package/src/components/subnav/partials/CtaLinks/icons/star.js +0 -20
  155. package/src/components/subnav/partials/CtaLinks/index.tsx +0 -130
  156. package/src/components/subnav/partials/CtaLinks/style.module.css +0 -45
  157. package/src/components/subnav/partials/DropdownTrigger/index.tsx +0 -35
  158. package/src/components/subnav/partials/DropdownTrigger/style.module.css +0 -36
  159. package/src/components/subnav/partials/MenuItemsDefault/index.tsx +0 -151
  160. package/src/components/subnav/partials/MenuItemsDefault/style.module.css +0 -91
  161. package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +0 -139
  162. package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +0 -82
  163. package/src/components/subnav/partials/TitleLink/index.tsx +0 -113
  164. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +0 -9
  165. package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +0 -9
  166. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-dark.ts +0 -23
  167. package/src/components/subnav/partials/TitleLink/mktg-logos/all-primary-logos_on-light.ts +0 -23
  168. package/src/components/subnav/partials/TitleLink/style.module.css +0 -43
  169. package/src/components/subnav/partials/nav-item-text/index.tsx +0 -37
  170. package/src/components/subnav/partials/nav-item-text/style.module.css +0 -15
  171. package/src/components/subnav/style.module.css +0 -68
  172. package/src/components/subnav/subnav-consts.ts +0 -1
  173. package/src/components/subnav/theme.module.css +0 -50
@@ -1,19 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import TextField from '../text-field'
7
- import type { MarketoFormField, MarketoFormTextField } from '../../../types'
8
- import styles from './style.module.css'
9
-
10
- const NameFields = ({ fields }: { fields: MarketoFormField[] }) => {
11
- return (
12
- <div className={styles.name}>
13
- <TextField field={fields[0] as MarketoFormTextField} />
14
- <TextField field={fields[1] as MarketoFormTextField} />
15
- </div>
16
- )
17
- }
18
-
19
- export default NameFields
@@ -1,13 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- .name {
7
- display: grid;
8
- grid-gap: 8px;
9
- @media (--medium-up) {
10
- grid-gap: 32px;
11
- grid-template-columns: 1fr 1fr;
12
- }
13
- }
@@ -1,48 +0,0 @@
1
- import { useFormContext } from 'react-hook-form'
2
- import RadioCard, {
3
- RadioCardGroup,
4
- } from '@hashicorp/react-design-system-components/src/components/form/radio-card'
5
- import FieldWrapper from '../../field-wrapper'
6
- import type { MarketoFormRadioButtonsField } from '../../../types'
7
-
8
- const RadioCardField = ({ field }: { field: MarketoFormRadioButtonsField }) => {
9
- const {
10
- register,
11
- watch,
12
- formState: { errors },
13
- } = useFormContext()
14
- const error = errors[field.id]?.message as string
15
- const currentSelection = watch(field.id)
16
-
17
- return (
18
- <FieldWrapper fieldId={field.id}>
19
- <RadioCardGroup
20
- error={error}
21
- layout="vertical"
22
- isRequired={field.required}
23
- legend={field.label}
24
- id={field.id}
25
- aria-describedby={error && `error-${field.id}-error`}
26
- >
27
- {field.fieldMetaData.values.map(({ label, value }) => (
28
- <RadioCard
29
- controlPosition="left"
30
- key={value}
31
- label={label}
32
- field={{
33
- ...register(field.id, { required: field.validationMessage }),
34
- checked: currentSelection === value,
35
- value,
36
- name: field.id,
37
- required: field.required,
38
- 'aria-invalid': Boolean(errors[field.id]),
39
- 'aria-describedby': error && `error-${field.id}-error`,
40
- }}
41
- />
42
- ))}
43
- </RadioCardGroup>
44
- </FieldWrapper>
45
- )
46
- }
47
-
48
- export default RadioCardField
@@ -1,39 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import { useFormContext } from 'react-hook-form'
7
- import Select from '@hashicorp/react-design-system-components/src/components/form/select'
8
- import FieldWrapper from '../../field-wrapper'
9
- import { formattedLabel, useErrorMessage } from '../../../utils'
10
- import type { MarketoFormSelectField } from '../../../types'
11
- import s from './style.module.css'
12
-
13
- const SelectField = ({ field }: { field: MarketoFormSelectField }) => {
14
- const { register } = useFormContext()
15
- const error = useErrorMessage(field.id)
16
-
17
- return (
18
- <FieldWrapper fieldId={field.id}>
19
- <Select
20
- field={{ ...register(field.id) }}
21
- size="large"
22
- label={formattedLabel(field)}
23
- error={error}
24
- isRequired={field.required}
25
- className={s.selectConstrainWidth}
26
- >
27
- {field.fieldMetaData.values
28
- ? field.fieldMetaData.values.map(({ label, value }) => (
29
- <option key={label} value={value}>
30
- {label}
31
- </option>
32
- ))
33
- : []}
34
- </Select>
35
- </FieldWrapper>
36
- )
37
- }
38
-
39
- export default SelectField
@@ -1,5 +0,0 @@
1
- .selectConstrainWidth {
2
- & select {
3
- width: 100%;
4
- }
5
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import { useFormContext } from 'react-hook-form'
7
- import TextInput from '@hashicorp/react-design-system-components/src/components/form/text-input'
8
- import FieldWrapper from '../../field-wrapper'
9
- import { formattedLabel, useErrorMessage } from '../../../utils'
10
- import type { MarketoFormTelephoneField } from '../../../types'
11
-
12
- const TelephoneField = ({ field }: { field: MarketoFormTelephoneField }) => {
13
- const { register } = useFormContext()
14
- const error = useErrorMessage(field.id)
15
-
16
- return (
17
- <FieldWrapper fieldId={field.id}>
18
- <TextInput
19
- label={formattedLabel(field)}
20
- type="tel"
21
- field={{ ...register(field.id), placeholder: field.hintText }}
22
- size="large"
23
- error={error}
24
- isRequired={field.required}
25
- />
26
- </FieldWrapper>
27
- )
28
- }
29
-
30
- export default TelephoneField
@@ -1,30 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import { useFormContext } from 'react-hook-form'
7
- import TextInput from '@hashicorp/react-design-system-components/src/components/form/text-input'
8
- import FieldWrapper from '../../field-wrapper'
9
- import { formattedLabel, useErrorMessage } from '../../../utils'
10
- import type { MarketoFormTextField } from '../../../types'
11
-
12
- const Index = ({ field }: { field: MarketoFormTextField }) => {
13
- const { register } = useFormContext()
14
- const error = useErrorMessage(field.id)
15
-
16
- return (
17
- <FieldWrapper fieldId={field.id}>
18
- <TextInput
19
- label={formattedLabel(field)}
20
- type="text"
21
- field={{ ...register(field.id), placeholder: field.hintText }}
22
- size="large"
23
- error={error}
24
- isRequired={field.required}
25
- />
26
- </FieldWrapper>
27
- )
28
- }
29
-
30
- export default Index
@@ -1,29 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import { useFormContext } from 'react-hook-form'
7
- import Textarea from '@hashicorp/react-design-system-components/src/components/form/textarea'
8
- import FieldWrapper from '../../field-wrapper'
9
- import { formattedLabel, useErrorMessage } from '../../../utils'
10
- import type { MarketoFormTextAreaField } from '../../../types'
11
-
12
- const Index = ({ field }: { field: MarketoFormTextAreaField }) => {
13
- const { register } = useFormContext()
14
- const error = useErrorMessage(field.id)
15
-
16
- return (
17
- <FieldWrapper fieldId={field.id}>
18
- <Textarea
19
- label={formattedLabel(field)}
20
- field={{ ...register(field.id), placeholder: field.hintText }}
21
- size="large"
22
- error={error}
23
- isRequired={field.required}
24
- />
25
- </FieldWrapper>
26
- )
27
- }
28
-
29
- export default Index
@@ -1,24 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import clsx from 'clsx'
7
- import s from './style.module.css'
8
-
9
- interface LabelProps {
10
- label: string
11
- fieldName: string
12
- className?: string
13
- }
14
-
15
- export default function Label({ label, fieldName, className }: LabelProps) {
16
- return (
17
- <label
18
- htmlFor={fieldName}
19
- className={clsx(className && className, s.label)}
20
- >
21
- {label}
22
- </label>
23
- )
24
- }
@@ -1,12 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- .label {
7
- color: var(--gray-3);
8
- composes: g-type-label from global;
9
- display: block;
10
- padding-bottom: 8px;
11
- text-transform: uppercase;
12
- }
@@ -1,84 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import { useMemo } from 'react'
7
- import { useFormContext } from 'react-hook-form'
8
- import Field from '../field'
9
- import type {
10
- MarketoFormField,
11
- MarketoFormComponents,
12
- VisibilityRule as VisibilityRuleType,
13
- } from '../../types'
14
-
15
- function ruleApplies(rule: VisibilityRuleType, value: any): boolean {
16
- switch (rule.operator) {
17
- case 'is':
18
- return (
19
- rule.values.includes(value) ||
20
- (value === false && rule.values.includes('no')) ||
21
- (value === true && rule.values.includes('yes'))
22
- )
23
- case 'isNot':
24
- return !rule.values.includes(value)
25
- case 'isEmpty':
26
- return value === null || typeof value === 'undefined' || value === ''
27
- default:
28
- return false
29
- }
30
- }
31
-
32
- const FieldWithVisibilityRule = ({
33
- field,
34
- components,
35
- }: {
36
- field: MarketoFormField
37
- components?: MarketoFormComponents
38
- }) => {
39
- const { watch } = useFormContext()
40
-
41
- // Currently we only support the first defined rule.
42
- const value = watch(field.visibilityRules!.rules![0].subjectField)
43
-
44
- const hasMatchingRule = useMemo(() => {
45
- return field.visibilityRules!.rules!.some((rule) =>
46
- ruleApplies(rule, value)
47
- )
48
- }, [field, value])
49
-
50
- if (
51
- hasMatchingRule &&
52
- (field.visibilityRules!.ruleType === 'show' ||
53
- field.visibilityRules!.ruleType === 'hide')
54
- ) {
55
- return field.visibilityRules!.ruleType === 'show' ? (
56
- <Field field={field} components={components} />
57
- ) : null
58
- }
59
-
60
- // If the ruleType is show, that means the field is hidden by default.
61
- return field.visibilityRules!.ruleType === 'show' ? null : (
62
- <Field field={field} components={components} />
63
- )
64
- }
65
-
66
- const VisibilityRule = ({
67
- field,
68
- components,
69
- }: {
70
- field: MarketoFormField
71
- components?: MarketoFormComponents
72
- }) => {
73
- if (
74
- field.visibilityRules &&
75
- (field.visibilityRules.ruleType === 'show' ||
76
- field.visibilityRules.ruleType === 'hide')
77
- ) {
78
- return <FieldWithVisibilityRule field={field} components={components} />
79
- }
80
-
81
- return <Field field={field} components={components} />
82
- }
83
-
84
- export default VisibilityRule
@@ -1,66 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- module.exports = {
7
- formId: {
8
- type: 'number',
9
- required: true,
10
- description:
11
- 'The numeric ID of the Marketo form that this component is rendering.',
12
- },
13
- marketoForm: {
14
- type: 'object',
15
- required: true,
16
- description:
17
- 'The API response containing the fields of the form this component should render.',
18
- },
19
- groups: {
20
- type: 'object',
21
- description:
22
- 'Mapping of fields that should be rendered with a single component.',
23
- },
24
- components: {
25
- type: 'object',
26
- description: 'Custom components to use instead of the built-in components',
27
- properties: {
28
- text: {
29
- type: 'React.ComponentType',
30
- description: 'Component to use for text fields',
31
- },
32
- email: {
33
- type: 'React.ComponentType',
34
- description: 'Component to use for email fields',
35
- },
36
- select: {
37
- type: 'React.ComponentType',
38
- description: 'Component to use for select fields',
39
- },
40
- checkbox: {
41
- type: 'React.ComponentType',
42
- description: 'Component to use for checkbox fields',
43
- },
44
- hidden: {
45
- type: 'React.ComponentType',
46
- description: 'Component to use for hidden fields',
47
- },
48
- },
49
- },
50
- submitTitle: {
51
- type: 'string',
52
- description: 'Title to use for the submit button',
53
- },
54
- className: {
55
- type: 'string',
56
- description: 'Additional classNames passed to the form element.',
57
- },
58
- onSubmitSuccess: {
59
- type: 'function',
60
- description: 'Callback function invoked on submission success',
61
- },
62
- onSubmitFailure: {
63
- type: 'function',
64
- description: 'Callback function invoked on submission failure',
65
- },
66
- }
@@ -1,109 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import * as client from './client'
7
- import { includesSkippedRecords } from '../utils'
8
- import type { SubmissionFilter, MarketoSubmissionResponse } from '../types'
9
- import type { NextApiRequest, NextApiResponse } from 'next'
10
-
11
- async function notifyError(body: unknown, err: unknown) {
12
- if (process.env.MARKETO_ERROR_ZAPIER_WEBHOOK) {
13
- try {
14
- await fetch(process.env.MARKETO_ERROR_ZAPIER_WEBHOOK, {
15
- method: 'POST',
16
- headers: {
17
- 'Content-Type': 'application/json',
18
- },
19
- body: JSON.stringify({ body, err }, null, 2),
20
- })
21
- } catch (err) {
22
- console.error({ body, err })
23
- }
24
- }
25
-
26
- return Promise.resolve()
27
- }
28
-
29
- function isE2ETest(req: NextApiRequest): boolean {
30
- // running e2e tests locally
31
- if (process.env.E2E_TESTS === 'true') {
32
- return true
33
- }
34
-
35
- // running e2e tests against a Vercel preview
36
- if (
37
- 'input' in req.body &&
38
- req.body.input.length > 0 &&
39
- req.body.input[0].leadFormFields.email === 'daniela.rod@example.com'
40
- ) {
41
- return true
42
- }
43
-
44
- return false
45
- }
46
-
47
- async function submitForm(
48
- req: NextApiRequest,
49
- res: NextApiResponse,
50
- {
51
- submissionFilter,
52
- }: {
53
- submissionFilter?: SubmissionFilter
54
- }
55
- ) {
56
- // Don't submit forms to the Marketo API when using E2E tests.
57
- if (isE2ETest(req)) {
58
- res.status(200).json({
59
- requestId: '7d85#181a7ae5e56',
60
- result: [
61
- {
62
- id: 25325329,
63
- status: 'updated',
64
- },
65
- ],
66
- success: true,
67
- })
68
- return
69
- }
70
-
71
- try {
72
- const passesSubmissionFilter = submissionFilter
73
- ? await submissionFilter(req)
74
- : true
75
- if (!passesSubmissionFilter) {
76
- // trick spammers into thinking their form submitted successfully
77
- res.status(200).json({ success: true })
78
- return
79
- }
80
- const marketoRes = await client.submitForm(req.body)
81
- const form = (await marketoRes.json()) as MarketoSubmissionResponse
82
- if (!form.success || includesSkippedRecords(form)) {
83
- await notifyError(req.body, form)
84
- }
85
- res.status(marketoRes.status).json(form)
86
- } catch (err) {
87
- await notifyError(req.body, err)
88
- res.status(500).json({ error: 'internal server error' })
89
- throw err
90
- }
91
- }
92
-
93
- export function buildApiRoutes({
94
- submissionFilter,
95
- }: {
96
- submissionFilter?: SubmissionFilter
97
- } = {}) {
98
- return async function apiRoutes(req: NextApiRequest, res: NextApiResponse) {
99
- const route = Array.isArray(req.query.marketo)
100
- ? req.query.marketo[0]
101
- : req.query.marketo
102
- switch (route) {
103
- case 'submit':
104
- return submitForm(req, res, { submissionFilter })
105
- default:
106
- return res.status(404).json({ error: 'not found' })
107
- }
108
- }
109
- }
@@ -1,98 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import moize from 'moize'
7
- import type {
8
- MarketoFormFieldsResponse,
9
- MarketoFormMetadataResponse,
10
- MarketoFormAPIResponse,
11
- } from '../types'
12
-
13
- interface MarketoTokenResponse {
14
- access_token: string
15
- }
16
-
17
- export async function getToken(): Promise<MarketoTokenResponse> {
18
- const url = new URL(`${process.env.MARKETO_IDENTITY}/oauth/token`)
19
- url.searchParams.append('grant_type', 'client_credentials')
20
- url.searchParams.append('client_id', process.env.MARKETO_CLIENT_ID!)
21
- url.searchParams.append('client_secret', process.env.MARKETO_CLIENT_SECRET!)
22
- const res = await fetch(url.toString())
23
- return await res.json()
24
- }
25
-
26
- export async function getForm(formId: number) {
27
- return await fetch(`https://content.hashicorp.com/api/marketo?id=${formId}`)
28
- }
29
-
30
- export async function getDraftFormProps(formId: number) {
31
- const { access_token } = await getToken()
32
-
33
- const fieldsResponse = await fetch(
34
- `${process.env.MARKETO_ENDPOINT}/asset/v1/form/${formId}/fields.json?status=draft`,
35
- {
36
- headers: {
37
- 'Content-Type': 'application/json',
38
- Authorization: `Bearer ${access_token}`,
39
- },
40
- }
41
- )
42
-
43
- const metadataResponse = await fetch(
44
- `${process.env.MARKETO_ENDPOINT}/asset/v1/form/${formId}.json?status=draft`,
45
- {
46
- headers: {
47
- 'Content-Type': 'application/json',
48
- Authorization: `Bearer ${access_token}`,
49
- },
50
- }
51
- )
52
-
53
- const [fields, metadata] = await Promise.all([
54
- fieldsResponse.json(),
55
- metadataResponse.json(),
56
- ])
57
-
58
- return { fields, metadata }
59
- }
60
-
61
- export async function getFormProps(
62
- id: number
63
- ): Promise<MarketoFormAPIResponse> {
64
- const res = await getForm(id)
65
- if (res.status !== 200) {
66
- throw new Error(
67
- `[marketo-form] non-200 status code when requesting form ${id}: ${res.status}`
68
- )
69
- }
70
-
71
- const form = (await res.json()) as {
72
- result: {
73
- fields: MarketoFormFieldsResponse
74
- metadata: MarketoFormMetadataResponse
75
- }
76
- }
77
-
78
- return form.result
79
- }
80
- export const memoizedGetFormProps = moize(getFormProps, {
81
- isPromise: true,
82
- maxAge: 60 * 1000, // 60 seconds
83
- })
84
-
85
- export async function submitForm(body: unknown) {
86
- const { access_token } = await getToken()
87
- return await fetch(
88
- `${process.env.MARKETO_ENDPOINT}/v1/leads/submitForm.json`,
89
- {
90
- method: 'POST',
91
- headers: {
92
- 'Content-Type': 'application/json',
93
- Authorization: `Bearer ${access_token}`,
94
- },
95
- body: JSON.stringify(body),
96
- }
97
- )
98
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Copyright (c) HashiCorp, Inc.
3
- * SPDX-License-Identifier: MPL-2.0
4
- */
5
-
6
- import { buildApiRoutes } from './api-routes'
7
-
8
- export { buildApiRoutes }