@thecb/components 12.1.0-beta.12 → 12.1.0-beta.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thecb/components",
3
- "version": "12.1.0-beta.12",
3
+ "version": "12.1.0-beta.13",
4
4
  "description": "Common lib for CityBase react components",
5
5
  "main": "dist/index.cjs.js",
6
6
  "typings": "dist/index.d.ts",
@@ -110,6 +110,7 @@ const Checkbox = forwardRef(
110
110
  checkboxExtraStyles,
111
111
  hasIconOverride = false,
112
112
  icon: Icon,
113
+ customAriaLabel,
113
114
  ...rest
114
115
  },
115
116
  ref
@@ -122,9 +123,16 @@ const Checkbox = forwardRef(
122
123
  }
123
124
  };
124
125
 
125
- const titleId = title ? `checkboxlabel-${name}` : undefined;
126
- const ariaLabelledById = labelledById ?? titleId;
127
- const ariaLabel = ariaLabelledById ? undefined : name;
126
+ const normalizeName = name ? name.replace(/\s+/g, "-") : "";
127
+ const checkboxId = `checkbox-${normalizeName}`;
128
+ const titleId = title ? `checkboxlabel-${normalizeName}` : undefined;
129
+ const ariaLabelledById = customAriaLabel
130
+ ? undefined
131
+ : labelledById ?? titleId;
132
+ const ariaLabel = ariaLabelledById ? undefined : customAriaLabel ?? name;
133
+ const errorMessageNormalized = error
134
+ ? `${normalizeName}-error-message`
135
+ : undefined;
128
136
 
129
137
  return (
130
138
  <Box
@@ -137,7 +145,7 @@ const Checkbox = forwardRef(
137
145
  aria-invalid={error}
138
146
  aria-label={ariaLabel}
139
147
  aria-labelledby={ariaLabelledById}
140
- aria-describedby={error ? `${name}-error-message` : undefined}
148
+ aria-describedby={errorMessageNormalized}
141
149
  onFocus={() => setFocused(true)}
142
150
  onBlur={() => setFocused(false)}
143
151
  onKeyDown={e => handleClick(e, onChange)}
@@ -155,7 +163,7 @@ const Checkbox = forwardRef(
155
163
  <CheckboxLabelContainer data-qa={dataQa}>
156
164
  <CheckboxContainer data-qa="Checkbox">
157
165
  <HiddenCheckbox
158
- id={`checkbox-${name}`}
166
+ id={checkboxId}
159
167
  disabled={disabled}
160
168
  name={name}
161
169
  checked={checked}
@@ -21,6 +21,7 @@ const meta = {
21
21
  extraStyles: undefined,
22
22
  textExtraStyles: undefined,
23
23
  labelledById: undefined,
24
+ customAriaLabel: undefined,
24
25
  dataQa: null
25
26
  },
26
27
  argTypes: {
@@ -52,6 +53,13 @@ const meta = {
52
53
  type: { summary: "string" }
53
54
  }
54
55
  },
56
+ customAriaLabel: {
57
+ table: {
58
+ description:
59
+ "Overrides the default aria-label derived from `name` or `labelledById`",
60
+ type: { summary: "string" }
61
+ }
62
+ },
55
63
  extraStyles: {
56
64
  table: {
57
65
  type: { summary: "string" }
@@ -147,3 +155,20 @@ export const Hidden = {
147
155
  },
148
156
  render: args => <CheckboxWithHooks {...args} />
149
157
  };
158
+
159
+ export const CustomAriaLabel = {
160
+ args: {
161
+ title: "Save to wallet (optional).",
162
+ customAriaLabel: "Save to wallet (optional).",
163
+ name: "save to wallet"
164
+ },
165
+ render: args => <CheckboxWithHooks {...args} />
166
+ };
167
+
168
+ export const SpacesInName = {
169
+ args: {
170
+ title: "Accept terms and conditions",
171
+ name: "accept terms and conditions"
172
+ },
173
+ render: args => <RequiredCheckbox {...args} />
174
+ };
@@ -14,7 +14,6 @@ import {
14
14
  } from "../../atoms/form-layouts";
15
15
  import AccountAndRoutingModal from "../account-and-routing-modal";
16
16
  import { noop } from "../../../util/general";
17
- import { Cluster, Cover } from "../../atoms/layouts";
18
17
  import TermsAndConditions from "../terms-and-conditions";
19
18
 
20
19
  const PaymentFormACH = ({
@@ -172,29 +171,42 @@ const PaymentFormACH = ({
172
171
  hidden={hideDefaultPayment}
173
172
  />
174
173
  )}
175
- {(showWalletCheckbox || showTerms) && (
176
- <Cluster childGap={"4px"} align="center" overflow>
177
- {showWalletCheckbox && (
178
- <Checkbox
179
- name="bank checkbox"
180
- dataQa="Save checking account to wallet"
181
- title="Save checking account to wallet."
182
- checked={walletCheckboxMarked}
183
- onChange={saveToWallet}
184
- />
185
- )}
186
- {showTerms && (
187
- <Cover singleChild>
188
- <TermsAndConditions
189
- version="v2"
190
- showCheckbox={false}
191
- description="View"
192
- terms={termsContent}
193
- initialFocusSelector={".modal-close-button"}
194
- />
195
- </Cover>
196
- )}
197
- </Cluster>
174
+ {showWalletCheckbox && (
175
+ <Checkbox
176
+ name="bank checkbox"
177
+ dataQa="Save checking account to wallet"
178
+ customAriaLabel="Save checking account to wallet (optional)."
179
+ title={
180
+ <>
181
+ Save checking account to wallet (optional).{" "}
182
+ {showTerms && (
183
+ <span
184
+ onClick={e => e.stopPropagation()}
185
+ style={{ display: "inline" }}
186
+ >
187
+ <TermsAndConditions
188
+ version="v2"
189
+ showCheckbox={false}
190
+ description="View "
191
+ terms={termsContent}
192
+ initialFocusSelector={".modal-close-button"}
193
+ />
194
+ </span>
195
+ )}
196
+ </>
197
+ }
198
+ checked={walletCheckboxMarked}
199
+ onChange={saveToWallet}
200
+ />
201
+ )}
202
+ {!showWalletCheckbox && showTerms && (
203
+ <TermsAndConditions
204
+ version="v2"
205
+ showCheckbox={false}
206
+ description="View "
207
+ terms={termsContent}
208
+ initialFocusSelector=".modal-close-button"
209
+ />
198
210
  )}
199
211
  </FormInputColumn>
200
212
  </FormContainer>
@@ -196,29 +196,42 @@ const PaymentFormCard = ({
196
196
  />
197
197
  </Box>
198
198
  )}
199
- {(showWalletCheckbox || showTerms) && (
200
- <Cluster childGap={"4px"} align="center" overflow>
201
- {showWalletCheckbox && (
202
- <Checkbox
203
- name="credit card checkbox"
204
- dataQa="Save credit card to wallet"
205
- title="Save credit card to wallet."
206
- checked={walletCheckboxMarked}
207
- onChange={saveToWallet}
208
- />
209
- )}
210
- {showTerms && (
211
- <Cover singleChild>
212
- <TermsAndConditions
213
- version="v2"
214
- showCheckbox={false}
215
- description="View"
216
- terms={termsContent}
217
- initialFocusSelector={".modal-close-button"}
218
- />
219
- </Cover>
220
- )}
221
- </Cluster>
199
+ {showWalletCheckbox && (
200
+ <Checkbox
201
+ name="credit card checkbox"
202
+ dataQa="Save credit card to wallet"
203
+ customAriaLabel="Save credit card to wallet (optional)."
204
+ title={
205
+ <>
206
+ Save credit card to wallet (optional).{" "}
207
+ {showTerms && (
208
+ <span
209
+ onClick={e => e.stopPropagation()}
210
+ style={{ display: "inline" }}
211
+ >
212
+ <TermsAndConditions
213
+ version="v2"
214
+ showCheckbox={false}
215
+ description="View "
216
+ terms={termsContent}
217
+ initialFocusSelector={".modal-close-button"}
218
+ />
219
+ </span>
220
+ )}
221
+ </>
222
+ }
223
+ checked={walletCheckboxMarked}
224
+ onChange={saveToWallet}
225
+ />
226
+ )}
227
+ {!showWalletCheckbox && showTerms && (
228
+ <TermsAndConditions
229
+ version="v2"
230
+ showCheckbox={false}
231
+ description="View "
232
+ terms={termsContent}
233
+ initialFocusSelector=".modal-close-button"
234
+ />
222
235
  )}
223
236
  </FormInputColumn>
224
237
  </FormContainer>
@@ -1,4 +1,5 @@
1
1
  import React, { useState } from "react";
2
+ import styled from "styled-components";
2
3
  import Checkbox from "../../atoms/checkbox";
3
4
  import { Box, Stack, Cluster } from "../../atoms/layouts";
4
5
  import Text from "../../atoms/text";
@@ -12,6 +13,15 @@ import { generateShadows } from "../../../util/generateShadows";
12
13
  import { useScrollTo } from "../../../hooks";
13
14
 
14
15
  const TermsAndConditionsTitleDivId = "terms-and-conditions-title";
16
+ const InlineTermsWrapper = styled.span`
17
+ display: inline;
18
+ > div {
19
+ display: inline;
20
+ }
21
+ .modal-trigger {
22
+ display: inline !important;
23
+ }
24
+ `;
15
25
 
16
26
  const TermsAndConditionsControlV2 = ({
17
27
  showCheckbox = true,
@@ -42,6 +52,25 @@ const TermsAndConditionsControlV2 = ({
42
52
  }
43
53
  };
44
54
 
55
+ if (!showCheckbox && displayInline) {
56
+ return (
57
+ <InlineTermsWrapper id={TermsAndConditionsTitleDivId}>
58
+ {description && <Text color={CHARADE_GREY}>{description}</Text>}
59
+ {terms && (
60
+ <TermsAndConditionsModal
61
+ link={linkText}
62
+ terms={terms}
63
+ isOpen={showTerms}
64
+ toggleOpen={toggleTerms}
65
+ linkVariant={modalVariant}
66
+ title={modalTitle}
67
+ initialFocusSelector={initialFocusSelector}
68
+ />
69
+ )}
70
+ </InlineTermsWrapper>
71
+ );
72
+ }
73
+
45
74
  return (
46
75
  <Box
47
76
  padding={displayInline ? "0" : "1.5rem"}
@@ -0,0 +1,166 @@
1
+ import TermsAndConditionsControlV2 from "./TermsAndConditionsControlV2";
2
+ import React, { useState } from "react";
3
+
4
+ const sampleTerms =
5
+ "By using this service, you agree to the terms and conditions set forth by the provider. All payments are subject to review.";
6
+
7
+ const meta = {
8
+ title: "Molecules/TermsAndConditionsControlV2",
9
+ component: TermsAndConditionsControlV2,
10
+ parameters: {
11
+ layout: "centered"
12
+ },
13
+ tags: ["!autodocs"],
14
+ args: {
15
+ showCheckbox: true,
16
+ isChecked: false,
17
+ hasError: false,
18
+ errorMessage: "Please accept Terms and Conditions",
19
+ description: "I agree to the",
20
+ linkText: "Terms and Conditions",
21
+ terms: sampleTerms,
22
+ id: "terms-and-conditions",
23
+ displayInline: true,
24
+ modalVariant: "default",
25
+ checkboxMargin: "4px 8px 4px 4px",
26
+ modalTitle: "Terms and Conditions",
27
+ initialFocusSelector: ".modal-close-button",
28
+ isRequired: false
29
+ },
30
+ argTypes: {
31
+ showCheckbox: {
32
+ description: "Whether to show the checkbox",
33
+ table: {
34
+ type: { summary: "boolean" },
35
+ defaultValue: { summary: true }
36
+ }
37
+ },
38
+ isChecked: {
39
+ table: {
40
+ type: { summary: "boolean" },
41
+ defaultValue: { summary: false }
42
+ }
43
+ },
44
+ hasError: {
45
+ description: "Whether the checkbox is in an error state",
46
+ table: {
47
+ type: { summary: "boolean" },
48
+ defaultValue: { summary: false }
49
+ }
50
+ },
51
+ errorMessage: {
52
+ table: {
53
+ type: { summary: "string" },
54
+ defaultValue: { summary: "Please accept Terms and Conditions" }
55
+ }
56
+ },
57
+ description: {
58
+ description: "Text displayed before the terms link",
59
+ table: {
60
+ type: { summary: "string" },
61
+ defaultValue: { summary: '""' }
62
+ }
63
+ },
64
+ linkText: {
65
+ description: "Text for the modal trigger link",
66
+ table: {
67
+ type: { summary: "string" },
68
+ defaultValue: { summary: "Terms and Conditions" }
69
+ }
70
+ },
71
+ terms: {
72
+ description: "Terms content displayed inside the modal",
73
+ table: {
74
+ type: { summary: "string" }
75
+ }
76
+ },
77
+ displayInline: {
78
+ description:
79
+ "When true with showCheckbox=false, renders inline terms using InlineTermsWrapper",
80
+ table: {
81
+ type: { summary: "boolean" },
82
+ defaultValue: { summary: true }
83
+ }
84
+ },
85
+ modalVariant: {
86
+ table: {
87
+ type: { summary: "string" },
88
+ defaultValue: { summary: "default" }
89
+ }
90
+ },
91
+ id: {
92
+ table: {
93
+ type: { summary: "string" },
94
+ defaultValue: { summary: "terms-and-conditions" }
95
+ }
96
+ },
97
+ checkboxMargin: {
98
+ table: {
99
+ type: { summary: "string" },
100
+ defaultValue: { summary: "4px 8px 4px 4px" }
101
+ }
102
+ },
103
+ modalTitle: {
104
+ table: {
105
+ type: { summary: "string" },
106
+ defaultValue: { summary: "Terms and Conditions" }
107
+ }
108
+ },
109
+ initialFocusSelector: {
110
+ table: {
111
+ type: { summary: "string" },
112
+ defaultValue: { summary: '""' }
113
+ }
114
+ },
115
+ isRequired: {
116
+ table: {
117
+ type: { summary: "boolean" },
118
+ defaultValue: { summary: false }
119
+ }
120
+ }
121
+ }
122
+ };
123
+
124
+ const TermsWithCheckbox = props => {
125
+ const [isChecked, setIsChecked] = useState(false);
126
+
127
+ return (
128
+ <TermsAndConditionsControlV2
129
+ {...props}
130
+ isChecked={isChecked}
131
+ onCheck={() => setIsChecked(!isChecked)}
132
+ />
133
+ );
134
+ };
135
+
136
+ export default meta;
137
+
138
+ export const Default = {
139
+ render: args => <TermsWithCheckbox {...args} />
140
+ };
141
+
142
+ export const InlineWithoutCheckbox = {
143
+ args: {
144
+ showCheckbox: false,
145
+ displayInline: true,
146
+ description: "View "
147
+ },
148
+ render: args => <TermsAndConditionsControlV2 {...args} />
149
+ };
150
+
151
+ export const NonInlineWithoutCheckbox = {
152
+ args: {
153
+ showCheckbox: false,
154
+ displayInline: false,
155
+ description: "View "
156
+ },
157
+ render: args => <TermsAndConditionsControlV2 {...args} />
158
+ };
159
+
160
+ export const WithError = {
161
+ args: {
162
+ hasError: true,
163
+ isRequired: true
164
+ },
165
+ render: args => <TermsWithCheckbox {...args} hasError={!args.isChecked} />
166
+ };