@nypl/design-system-react-components 0.25.4 → 0.25.8
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/CHANGELOG.md +52 -0
- package/dist/components/Breadcrumbs/BreadcrumbsTypes.d.ts +1 -0
- package/dist/components/Icons/IconSvgs.d.ts +1 -0
- package/dist/components/Icons/IconTypes.d.ts +1 -0
- package/dist/components/Image/ImageTypes.d.ts +3 -1
- package/dist/components/Link/LinkTypes.d.ts +1 -0
- package/dist/components/Notification/Notification.d.ts +2 -0
- package/dist/components/Select/Select.d.ts +2 -0
- package/dist/components/Toggle/Toggle.d.ts +47 -0
- package/dist/components/Toggle/ToggleSizes.d.ts +4 -0
- package/dist/components/VideoPlayer/VideoPlayer.d.ts +5 -3
- package/dist/design-system-react-components.cjs.development.js +921 -360
- package/dist/design-system-react-components.cjs.development.js.map +1 -1
- package/dist/design-system-react-components.cjs.production.min.js +1 -1
- package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
- package/dist/design-system-react-components.esm.js +917 -353
- package/dist/design-system-react-components.esm.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/theme/components/breadcrumb.d.ts +9 -0
- package/dist/theme/components/notification.d.ts +8 -4
- package/dist/theme/components/toggle.d.ts +68 -0
- package/dist/theme/foundations/spacing.d.ts +2 -0
- package/package.json +2 -2
- package/src/components/Accordion/Accordion.stories.mdx +1 -2
- package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +20 -3
- package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +20 -0
- package/src/components/Breadcrumbs/BreadcrumbsTypes.tsx +1 -0
- package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +198 -0
- package/src/components/Button/Button.tsx +0 -1
- package/src/components/Card/Card.stories.mdx +74 -7
- package/src/components/Card/Card.tsx +9 -8
- package/src/components/Card/__snapshots__/Card.test.tsx.snap +67 -35
- package/src/components/Chakra/Grid.stories.mdx +11 -14
- package/src/components/DatePicker/DatePicker.test.tsx +8 -6
- package/src/components/DatePicker/__snapshots__/DatePicker.test.tsx.snap +5 -4
- package/src/components/Icons/Icon.stories.mdx +3 -2
- package/src/components/Icons/IconSvgs.tsx +2 -0
- package/src/components/Icons/IconTypes.tsx +1 -0
- package/src/components/Image/Image.stories.mdx +152 -90
- package/src/components/Image/Image.test.tsx +10 -0
- package/src/components/Image/ImageTypes.ts +2 -0
- package/src/components/Image/__snapshots__/Image.test.tsx.snap +24 -8
- package/src/components/Label/Label.stories.mdx +1 -1
- package/src/components/Link/Link.stories.mdx +2 -3
- package/src/components/Link/Link.test.tsx +71 -0
- package/src/components/Link/Link.tsx +41 -9
- package/src/components/Link/LinkTypes.tsx +1 -0
- package/src/components/Link/__snapshots__/Link.test.tsx.snap +201 -0
- package/src/components/Notification/Notification.stories.mdx +36 -3
- package/src/components/Notification/Notification.test.tsx +62 -16
- package/src/components/Notification/Notification.tsx +17 -5
- package/src/components/Notification/__snapshots__/Notification.test.tsx.snap +117 -0
- package/src/components/Pagination/Pagination.stories.mdx +1 -2
- package/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap +42 -0
- package/src/components/ProgressIndicator/ProgressIndicator.stories.mdx +2 -3
- package/src/components/SearchBar/SearchBar.Test.tsx +64 -20
- package/src/components/SearchBar/SearchBar.stories.mdx +3 -4
- package/src/components/SearchBar/SearchBar.tsx +4 -1
- package/src/components/Select/Select.stories.mdx +132 -55
- package/src/components/Select/Select.test.tsx +2 -2
- package/src/components/Select/Select.tsx +6 -2
- package/src/components/Slider/Slider.stories.mdx +3 -2
- package/src/components/Slider/Slider.test.tsx +35 -0
- package/src/components/Slider/Slider.tsx +8 -2
- package/src/components/Template/Template.stories.mdx +1 -2
- package/src/components/Toggle/Toggle.stories.mdx +176 -0
- package/src/components/Toggle/Toggle.test.tsx +140 -0
- package/src/components/Toggle/Toggle.tsx +118 -0
- package/src/components/Toggle/ToggleSizes.tsx +4 -0
- package/src/components/Toggle/__snapshots__/Toggle.test.tsx.snap +255 -0
- package/src/components/VideoPlayer/VideoPlayer.stories.mdx +39 -18
- package/src/components/VideoPlayer/VideoPlayer.test.tsx +103 -1
- package/src/components/VideoPlayer/VideoPlayer.tsx +57 -17
- package/src/components/VideoPlayer/__snapshots__/VideoPlayer.test.tsx.snap +48 -0
- package/src/index.ts +8 -0
- package/src/theme/components/breadcrumb.ts +11 -1
- package/src/theme/components/card.ts +4 -5
- package/src/theme/components/global.ts +1 -1
- package/src/theme/components/icon.ts +2 -2
- package/src/theme/components/image.ts +8 -0
- package/src/theme/components/notification.ts +8 -6
- package/src/theme/components/toggle.ts +65 -0
- package/src/theme/foundations/spacing.ts +3 -0
- package/src/theme/index.ts +2 -0
- package/src/utils/componentCategories.ts +3 -1
|
@@ -35,13 +35,13 @@ describe("SearchBar Accessibility", () => {
|
|
|
35
35
|
it("passes axe accessibility test", async () => {
|
|
36
36
|
const { container } = render(
|
|
37
37
|
<SearchBar
|
|
38
|
+
helperErrorText={helperErrorText}
|
|
38
39
|
id="id"
|
|
40
|
+
invalidText={invalidText}
|
|
39
41
|
labelText="Searchbar"
|
|
40
42
|
onSubmit={jest.fn()}
|
|
41
43
|
selectProps={selectProps}
|
|
42
44
|
textInputProps={textInputProps}
|
|
43
|
-
helperErrorText={helperErrorText}
|
|
44
|
-
invalidText={invalidText}
|
|
45
45
|
/>
|
|
46
46
|
);
|
|
47
47
|
expect(await axe(container)).toHaveNoViolations();
|
|
@@ -55,11 +55,11 @@ describe("SearchBar", () => {
|
|
|
55
55
|
it("renders the basic form", () => {
|
|
56
56
|
render(
|
|
57
57
|
<SearchBar
|
|
58
|
+
helperErrorText={helperErrorText}
|
|
58
59
|
id="id"
|
|
59
60
|
labelText="searchbar"
|
|
60
61
|
onSubmit={searchBarSubmit}
|
|
61
62
|
textInputProps={textInputProps}
|
|
62
|
-
helperErrorText={helperErrorText}
|
|
63
63
|
/>
|
|
64
64
|
);
|
|
65
65
|
expect(screen.getByRole("search")).toBeInTheDocument();
|
|
@@ -74,12 +74,12 @@ describe("SearchBar", () => {
|
|
|
74
74
|
it("renders an optional Select component", () => {
|
|
75
75
|
render(
|
|
76
76
|
<SearchBar
|
|
77
|
+
helperErrorText={helperErrorText}
|
|
77
78
|
id="id"
|
|
78
79
|
labelText="searchbar"
|
|
79
80
|
onSubmit={searchBarSubmit}
|
|
80
81
|
selectProps={selectProps}
|
|
81
82
|
textInputProps={textInputProps}
|
|
82
|
-
helperErrorText={helperErrorText}
|
|
83
83
|
/>
|
|
84
84
|
);
|
|
85
85
|
expect(screen.getByRole("combobox")).toBeInTheDocument();
|
|
@@ -89,14 +89,14 @@ describe("SearchBar", () => {
|
|
|
89
89
|
it("renders the invalid text in the invalid state", () => {
|
|
90
90
|
render(
|
|
91
91
|
<SearchBar
|
|
92
|
+
helperErrorText={helperErrorText}
|
|
92
93
|
id="id"
|
|
94
|
+
invalidText={invalidText}
|
|
95
|
+
isInvalid
|
|
93
96
|
labelText="searchbar"
|
|
94
97
|
onSubmit={searchBarSubmit}
|
|
95
98
|
selectProps={selectProps}
|
|
96
99
|
textInputProps={textInputProps}
|
|
97
|
-
helperErrorText={helperErrorText}
|
|
98
|
-
invalidText={invalidText}
|
|
99
|
-
isInvalid
|
|
100
100
|
/>
|
|
101
101
|
);
|
|
102
102
|
expect(screen.getByText(invalidText)).toBeInTheDocument();
|
|
@@ -106,14 +106,14 @@ describe("SearchBar", () => {
|
|
|
106
106
|
it("does not render the default invalid text from the Select or TextInput components", () => {
|
|
107
107
|
render(
|
|
108
108
|
<SearchBar
|
|
109
|
+
helperErrorText={helperErrorText}
|
|
109
110
|
id="id"
|
|
111
|
+
invalidText={invalidText}
|
|
112
|
+
isInvalid
|
|
110
113
|
labelText="searchbar"
|
|
111
114
|
onSubmit={searchBarSubmit}
|
|
112
115
|
selectProps={selectProps}
|
|
113
116
|
textInputProps={textInputProps}
|
|
114
|
-
helperErrorText={helperErrorText}
|
|
115
|
-
invalidText={invalidText}
|
|
116
|
-
isInvalid
|
|
117
117
|
/>
|
|
118
118
|
);
|
|
119
119
|
expect(
|
|
@@ -124,12 +124,12 @@ describe("SearchBar", () => {
|
|
|
124
124
|
it("calls the callback function on submit ", () => {
|
|
125
125
|
render(
|
|
126
126
|
<SearchBar
|
|
127
|
-
|
|
127
|
+
helperErrorText={helperErrorText}
|
|
128
128
|
id="id"
|
|
129
|
+
labelText="searchBar"
|
|
129
130
|
onSubmit={searchBarSubmit}
|
|
130
131
|
selectProps={selectProps}
|
|
131
132
|
textInputProps={textInputProps}
|
|
132
|
-
helperErrorText={helperErrorText}
|
|
133
133
|
/>
|
|
134
134
|
);
|
|
135
135
|
expect(searchBarSubmit).toHaveBeenCalledTimes(0);
|
|
@@ -139,34 +139,65 @@ describe("SearchBar", () => {
|
|
|
139
139
|
expect(buttonCallback).toHaveBeenCalledTimes(1);
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
+
it("Renders 'required' in the placeholder text", () => {
|
|
143
|
+
const { rerender } = render(
|
|
144
|
+
<SearchBar
|
|
145
|
+
id="requiredState"
|
|
146
|
+
isDisabled
|
|
147
|
+
isRequired
|
|
148
|
+
labelText="searchbar"
|
|
149
|
+
onSubmit={jest.fn()}
|
|
150
|
+
textInputProps={textInputProps}
|
|
151
|
+
/>
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
expect(
|
|
155
|
+
screen.getByPlaceholderText("Item Search (Required)")
|
|
156
|
+
).not.toBeInTheDocument();
|
|
157
|
+
|
|
158
|
+
rerender(
|
|
159
|
+
<SearchBar
|
|
160
|
+
id="requiredState"
|
|
161
|
+
isDisabled
|
|
162
|
+
isRequired
|
|
163
|
+
labelText="searchbar"
|
|
164
|
+
onSubmit={jest.fn()}
|
|
165
|
+
textInputProps={textInputProps}
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
expect(
|
|
169
|
+
screen.getByPlaceholderText("Item Search (Required)")
|
|
170
|
+
).toBeInTheDocument();
|
|
171
|
+
});
|
|
172
|
+
|
|
142
173
|
it("Renders the UI snapshot correctly", () => {
|
|
143
174
|
const basic = renderer
|
|
144
175
|
.create(
|
|
145
176
|
<SearchBar
|
|
146
|
-
|
|
177
|
+
helperErrorText={helperErrorText}
|
|
178
|
+
id="basic"
|
|
147
179
|
labelText="searchbar"
|
|
148
180
|
onSubmit={jest.fn()}
|
|
149
181
|
textInputProps={textInputProps}
|
|
150
|
-
helperErrorText={helperErrorText}
|
|
151
182
|
/>
|
|
152
183
|
)
|
|
153
184
|
.toJSON();
|
|
154
185
|
const withSelect = renderer
|
|
155
186
|
.create(
|
|
156
187
|
<SearchBar
|
|
157
|
-
|
|
188
|
+
helperErrorText={helperErrorText}
|
|
189
|
+
id="withSelect"
|
|
158
190
|
labelText="searchbar"
|
|
159
191
|
onSubmit={jest.fn()}
|
|
160
192
|
selectProps={selectProps}
|
|
161
193
|
textInputProps={textInputProps}
|
|
162
|
-
helperErrorText={helperErrorText}
|
|
163
194
|
/>
|
|
164
195
|
)
|
|
165
196
|
.toJSON();
|
|
166
197
|
const withoutHelperText = renderer
|
|
167
198
|
.create(
|
|
168
199
|
<SearchBar
|
|
169
|
-
id="
|
|
200
|
+
id="withoutHelperText"
|
|
170
201
|
labelText="searchbar"
|
|
171
202
|
onSubmit={jest.fn()}
|
|
172
203
|
textInputProps={textInputProps}
|
|
@@ -176,22 +207,34 @@ describe("SearchBar", () => {
|
|
|
176
207
|
const invalidState = renderer
|
|
177
208
|
.create(
|
|
178
209
|
<SearchBar
|
|
179
|
-
id="
|
|
210
|
+
id="invalidState"
|
|
211
|
+
isInvalid
|
|
180
212
|
labelText="searchbar"
|
|
181
213
|
onSubmit={jest.fn()}
|
|
182
214
|
textInputProps={textInputProps}
|
|
183
|
-
isInvalid
|
|
184
215
|
/>
|
|
185
216
|
)
|
|
186
217
|
.toJSON();
|
|
187
218
|
const disabledState = renderer
|
|
188
219
|
.create(
|
|
189
220
|
<SearchBar
|
|
190
|
-
id="
|
|
221
|
+
id="disabledState"
|
|
222
|
+
isDisabled
|
|
191
223
|
labelText="searchbar"
|
|
192
224
|
onSubmit={jest.fn()}
|
|
193
225
|
textInputProps={textInputProps}
|
|
226
|
+
/>
|
|
227
|
+
)
|
|
228
|
+
.toJSON();
|
|
229
|
+
const requiredState = renderer
|
|
230
|
+
.create(
|
|
231
|
+
<SearchBar
|
|
232
|
+
id="requiredState"
|
|
194
233
|
isDisabled
|
|
234
|
+
isRequired
|
|
235
|
+
labelText="searchbar"
|
|
236
|
+
onSubmit={jest.fn()}
|
|
237
|
+
textInputProps={textInputProps}
|
|
195
238
|
/>
|
|
196
239
|
)
|
|
197
240
|
.toJSON();
|
|
@@ -201,5 +244,6 @@ describe("SearchBar", () => {
|
|
|
201
244
|
expect(withoutHelperText).toMatchSnapshot();
|
|
202
245
|
expect(invalidState).toMatchSnapshot();
|
|
203
246
|
expect(disabledState).toMatchSnapshot();
|
|
247
|
+
expect(requiredState).toMatchSnapshot();
|
|
204
248
|
});
|
|
205
249
|
});
|
|
@@ -19,8 +19,7 @@ import DSProvider from "../../theme/provider";
|
|
|
19
19
|
parameters={{
|
|
20
20
|
design: {
|
|
21
21
|
type: "figma",
|
|
22
|
-
url:
|
|
23
|
-
"https://www.figma.com/file/qShodlfNCJHb8n03IFyApM/Master?node-id=11689%3A423",
|
|
22
|
+
url: "https://www.figma.com/file/qShodlfNCJHb8n03IFyApM/Master?node-id=11689%3A423",
|
|
24
23
|
},
|
|
25
24
|
jest: ["SearchBar.test.tsx"],
|
|
26
25
|
}}
|
|
@@ -43,7 +42,7 @@ import DSProvider from "../../theme/provider";
|
|
|
43
42
|
| Component Version | DS Version |
|
|
44
43
|
| ----------------- | ---------- |
|
|
45
44
|
| Added | `0.0.4` |
|
|
46
|
-
| Latest | `0.25.
|
|
45
|
+
| Latest | `0.25.6` |
|
|
47
46
|
|
|
48
47
|
<Description of={SearchBar} />
|
|
49
48
|
|
|
@@ -312,7 +311,7 @@ function SearchBarValueExample() {
|
|
|
312
311
|
};
|
|
313
312
|
const onSubmit = (event) => {
|
|
314
313
|
event.preventDefault();
|
|
315
|
-
console.log(`onSubmit Select value: ${event.target.
|
|
314
|
+
console.log(`onSubmit Select value: ${event.target.selectName.value}`);
|
|
316
315
|
console.log(`onSubmit TextInput value ${event.target.textInputName.value}`);
|
|
317
316
|
};
|
|
318
317
|
return (
|
|
@@ -99,6 +99,9 @@ export default function SearchBar(props: SearchBarProps) {
|
|
|
99
99
|
const ariaDescribedby = helperErrorTextID;
|
|
100
100
|
const footnote = isInvalid ? invalidText : helperErrorText;
|
|
101
101
|
const finalAriaLabel = footnote ? `${labelText} - ${footnote}` : labelText;
|
|
102
|
+
const textInputPlaceholder = `${textInputProps?.placeholder} ${
|
|
103
|
+
isRequired ? "(Required)" : ""
|
|
104
|
+
}`;
|
|
102
105
|
// Render the `Select` component.
|
|
103
106
|
const selectElem = selectProps && (
|
|
104
107
|
<Select
|
|
@@ -120,7 +123,7 @@ export default function SearchBar(props: SearchBarProps) {
|
|
|
120
123
|
<TextInput
|
|
121
124
|
id={generateUUID()}
|
|
122
125
|
labelText={textInputProps?.labelText}
|
|
123
|
-
placeholder={
|
|
126
|
+
placeholder={textInputPlaceholder}
|
|
124
127
|
onChange={textInputProps?.onChange}
|
|
125
128
|
name={textInputProps?.name}
|
|
126
129
|
type={TextInputTypes.text}
|
|
@@ -9,6 +9,8 @@ import { withDesign } from "storybook-addon-designs";
|
|
|
9
9
|
|
|
10
10
|
import { VStack } from "@chakra-ui/react";
|
|
11
11
|
import Select from "./Select";
|
|
12
|
+
import Form from "../Form/Form";
|
|
13
|
+
import Button from "../Button/Button";
|
|
12
14
|
import { getCategory } from "../../utils/componentCategories";
|
|
13
15
|
import DSProvider from "../../theme/provider";
|
|
14
16
|
|
|
@@ -19,8 +21,7 @@ import DSProvider from "../../theme/provider";
|
|
|
19
21
|
parameters={{
|
|
20
22
|
design: {
|
|
21
23
|
type: "figma",
|
|
22
|
-
url:
|
|
23
|
-
"https://www.figma.com/file/qShodlfNCJHb8n03IFyApM/Master?node-id=11895%3A549",
|
|
24
|
+
url: "https://www.figma.com/file/qShodlfNCJHb8n03IFyApM/Master?node-id=11895%3A549",
|
|
24
25
|
},
|
|
25
26
|
jest: ["Select.test.tsx"],
|
|
26
27
|
}}
|
|
@@ -38,7 +39,7 @@ import DSProvider from "../../theme/provider";
|
|
|
38
39
|
| Component Version | DS Version |
|
|
39
40
|
| ----------------- | ---------- |
|
|
40
41
|
| Added | `0.7.0` |
|
|
41
|
-
| Latest | `0.25.
|
|
42
|
+
| Latest | `0.25.8` |
|
|
42
43
|
|
|
43
44
|
<Description of={Select} />
|
|
44
45
|
|
|
@@ -102,8 +103,8 @@ text within the `label` element.
|
|
|
102
103
|
<Story name="Labelling Variations">
|
|
103
104
|
<VStack align="stretch" spacing={8}>
|
|
104
105
|
<Select
|
|
105
|
-
labelText="What is your favorite color?"
|
|
106
106
|
helperText="Display the label"
|
|
107
|
+
labelText="What is your favorite color?"
|
|
107
108
|
name="color"
|
|
108
109
|
>
|
|
109
110
|
<option value="red">Red</option>
|
|
@@ -113,8 +114,8 @@ text within the `label` element.
|
|
|
113
114
|
<option value="white">White</option>
|
|
114
115
|
</Select>
|
|
115
116
|
<Select
|
|
116
|
-
labelText="What is your favorite color?"
|
|
117
117
|
helperText="Do not display the label"
|
|
118
|
+
labelText="What is your favorite color?"
|
|
118
119
|
name="color"
|
|
119
120
|
showLabel={false}
|
|
120
121
|
>
|
|
@@ -125,10 +126,10 @@ text within the `label` element.
|
|
|
125
126
|
<option value="white">White</option>
|
|
126
127
|
</Select>
|
|
127
128
|
<Select
|
|
128
|
-
labelText="What is your favorite color?"
|
|
129
129
|
helperText="Display the Required/Optional text"
|
|
130
|
-
name="color"
|
|
131
130
|
isRequired
|
|
131
|
+
labelText="What is your favorite color?"
|
|
132
|
+
name="color"
|
|
132
133
|
>
|
|
133
134
|
<option value="red">Red</option>
|
|
134
135
|
<option value="green">Green</option>
|
|
@@ -137,11 +138,11 @@ text within the `label` element.
|
|
|
137
138
|
<option value="white">White</option>
|
|
138
139
|
</Select>
|
|
139
140
|
<Select
|
|
140
|
-
labelText="What is your favorite color?"
|
|
141
141
|
helperText="Do not display the Required/Optional text"
|
|
142
|
+
isRequired
|
|
143
|
+
labelText="What is your favorite color?"
|
|
142
144
|
name="color"
|
|
143
145
|
showOptReqLabel={false}
|
|
144
|
-
isRequired
|
|
145
146
|
>
|
|
146
147
|
<option value="red">Red</option>
|
|
147
148
|
<option value="green">Green</option>
|
|
@@ -158,11 +159,11 @@ text within the `label` element.
|
|
|
158
159
|
<Canvas>
|
|
159
160
|
<DSProvider>
|
|
160
161
|
<Select
|
|
161
|
-
labelText="What is your favorite color?"
|
|
162
162
|
helperText="This is the helper text."
|
|
163
163
|
invalidText="This is the error text :("
|
|
164
|
-
name="color"
|
|
165
164
|
isInvalid
|
|
165
|
+
labelText="What is your favorite color?"
|
|
166
|
+
name="color"
|
|
166
167
|
>
|
|
167
168
|
<option value="red">Red</option>
|
|
168
169
|
<option value="green">Green</option>
|
|
@@ -178,11 +179,11 @@ text within the `label` element.
|
|
|
178
179
|
<Canvas>
|
|
179
180
|
<DSProvider>
|
|
180
181
|
<Select
|
|
181
|
-
labelText="What is your favorite color?"
|
|
182
182
|
helperText="This is the helper text."
|
|
183
183
|
invalidText="This is the error text :("
|
|
184
|
-
name="color"
|
|
185
184
|
isDisabled
|
|
185
|
+
labelText="What is your favorite color?"
|
|
186
|
+
name="color"
|
|
186
187
|
>
|
|
187
188
|
<option value="red">Red</option>
|
|
188
189
|
<option value="green">Green</option>
|
|
@@ -198,57 +199,133 @@ text within the `label` element.
|
|
|
198
199
|
### Controlled Component using `value` and `onChange` props
|
|
199
200
|
|
|
200
201
|
If your application uses controlled React components and the DS `Select`
|
|
201
|
-
component must be controlled, you can
|
|
202
|
+
component must be controlled, you can pass and extract the value through the
|
|
202
203
|
`value` and `onChange` props. This will be called every time a new `option`
|
|
203
204
|
value is selected.
|
|
204
205
|
|
|
206
|
+
Try it out: open up the browser's console to see new values being logged on
|
|
207
|
+
each change.
|
|
208
|
+
|
|
205
209
|
```jsx
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
</
|
|
210
|
+
export function SelectControlledExample() {
|
|
211
|
+
const [value, setValue] = React.useState();
|
|
212
|
+
const onChange = (e) => {
|
|
213
|
+
// This will return the value selected through the event object.
|
|
214
|
+
console.log(e.target.value);
|
|
215
|
+
setValue(e.target.value);
|
|
216
|
+
};
|
|
217
|
+
return (
|
|
218
|
+
<Select
|
|
219
|
+
helperText="This is the helper text."
|
|
220
|
+
labelText="What is your favorite color?"
|
|
221
|
+
name="color"
|
|
222
|
+
onChange={onChange}
|
|
223
|
+
value={value}
|
|
224
|
+
>
|
|
225
|
+
<option value="red">Red</option>
|
|
226
|
+
<option value="green">Green</option>
|
|
227
|
+
<option value="blue">Blue</option>
|
|
228
|
+
<option value="black">Black</option>
|
|
229
|
+
<option value="white">White</option>
|
|
230
|
+
</Select>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
226
233
|
```
|
|
227
234
|
|
|
235
|
+
export function SelectControlledExample() {
|
|
236
|
+
const [value, setValue] = React.useState();
|
|
237
|
+
const onChange = (e) => {
|
|
238
|
+
// This will return the value selected through the event object.
|
|
239
|
+
console.log("Controlled value:", e.target.value);
|
|
240
|
+
setValue(e.target.value);
|
|
241
|
+
};
|
|
242
|
+
return (
|
|
243
|
+
<Select
|
|
244
|
+
helperText="This is the helper text."
|
|
245
|
+
labelText="What is your favorite color?"
|
|
246
|
+
name="color"
|
|
247
|
+
onChange={onChange}
|
|
248
|
+
value={value}
|
|
249
|
+
>
|
|
250
|
+
<option value="red">Red</option>
|
|
251
|
+
<option value="green">Green</option>
|
|
252
|
+
<option value="blue">Blue</option>
|
|
253
|
+
<option value="black">Black</option>
|
|
254
|
+
<option value="white">White</option>
|
|
255
|
+
</Select>
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
<Canvas>
|
|
260
|
+
<DSProvider>
|
|
261
|
+
<SelectControlledExample />
|
|
262
|
+
</DSProvider>
|
|
263
|
+
</Canvas>
|
|
264
|
+
|
|
228
265
|
### Uncontrolled Component using `ref`s
|
|
229
266
|
|
|
230
267
|
If your application uses uncontrolled components, you can pass a React `ref`
|
|
231
|
-
prop to the DS Select component to get the selected value from the DOM.
|
|
268
|
+
prop to the DS Select component to get the selected value from the DOM. Note
|
|
269
|
+
that this example uses a `Form` and a `Button` to submit the form, only then
|
|
270
|
+
will the value be available.
|
|
232
271
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
// ...
|
|
236
|
-
<Select
|
|
237
|
-
labelText="What is your favorite color?"
|
|
238
|
-
helperText="This is the helper text."
|
|
239
|
-
name="color"
|
|
240
|
-
>
|
|
241
|
-
<option value="red">Red</option>
|
|
242
|
-
<option value="green">Green</option>
|
|
243
|
-
<option value="blue">Blue</option>
|
|
244
|
-
<option value="black">Black</option>
|
|
245
|
-
<option value="white">White</option>
|
|
246
|
-
</Select>
|
|
272
|
+
Try it out: open up the browser's console to see new values being logged on
|
|
273
|
+
each change.
|
|
247
274
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
275
|
+
```jsx
|
|
276
|
+
export function SelectUncontrolledExample() {
|
|
277
|
+
const selectRef = React.createRef();
|
|
278
|
+
const onSubmit = () => {
|
|
279
|
+
const selectValue = selectRef.current.value;
|
|
280
|
+
console.log("Using uncontrolled ref:", selectValue);
|
|
281
|
+
};
|
|
282
|
+
return (
|
|
283
|
+
<Form>
|
|
284
|
+
<Select
|
|
285
|
+
helperText="This is the helper text."
|
|
286
|
+
labelText="What is your favorite color?"
|
|
287
|
+
name="color"
|
|
288
|
+
ref={selectRef}
|
|
289
|
+
>
|
|
290
|
+
<option value="red">Red</option>
|
|
291
|
+
<option value="green">Green</option>
|
|
292
|
+
<option value="blue">Blue</option>
|
|
293
|
+
<option value="black">Black</option>
|
|
294
|
+
<option value="white">White</option>
|
|
295
|
+
</Select>
|
|
296
|
+
<Button onClick={onSubmit}>Submit</Button>
|
|
297
|
+
</Form>
|
|
298
|
+
);
|
|
299
|
+
}
|
|
254
300
|
```
|
|
301
|
+
|
|
302
|
+
export function SelectUncontrolledExample() {
|
|
303
|
+
const selectRef = React.createRef();
|
|
304
|
+
const onSubmit = () => {
|
|
305
|
+
const selectValue = selectRef.current.value;
|
|
306
|
+
console.log("Using uncontrolled ref:", selectValue);
|
|
307
|
+
};
|
|
308
|
+
return (
|
|
309
|
+
<Form>
|
|
310
|
+
<Select
|
|
311
|
+
helperText="This is the helper text."
|
|
312
|
+
labelText="What is your favorite color?"
|
|
313
|
+
name="color"
|
|
314
|
+
ref={selectRef}
|
|
315
|
+
>
|
|
316
|
+
<option value="red">Red</option>
|
|
317
|
+
<option value="green">Green</option>
|
|
318
|
+
<option value="blue">Blue</option>
|
|
319
|
+
<option value="black">Black</option>
|
|
320
|
+
<option value="white">White</option>
|
|
321
|
+
</Select>
|
|
322
|
+
<Button onClick={onSubmit}>Submit</Button>
|
|
323
|
+
</Form>
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
<Canvas>
|
|
328
|
+
<DSProvider>
|
|
329
|
+
<SelectUncontrolledExample />
|
|
330
|
+
</DSProvider>
|
|
331
|
+
</Canvas>
|
|
@@ -198,7 +198,7 @@ describe("Select", () => {
|
|
|
198
198
|
});
|
|
199
199
|
|
|
200
200
|
it("calls the onChange callback function", () => {
|
|
201
|
-
let value = "
|
|
201
|
+
let value = "";
|
|
202
202
|
const changeCallback = (e) => {
|
|
203
203
|
value = e.target.value;
|
|
204
204
|
};
|
|
@@ -208,7 +208,7 @@ describe("Select", () => {
|
|
|
208
208
|
</Select>
|
|
209
209
|
);
|
|
210
210
|
|
|
211
|
-
expect(value).toEqual("
|
|
211
|
+
expect(value).toEqual("");
|
|
212
212
|
|
|
213
213
|
fireEvent.change(screen.getByRole("combobox"), {
|
|
214
214
|
target: { value: "blue" },
|
|
@@ -38,6 +38,8 @@ export interface SelectProps {
|
|
|
38
38
|
/** The callback function to get the selected value.
|
|
39
39
|
* Should be passed along with `value` for controlled components. */
|
|
40
40
|
onChange?: (event: React.FormEvent) => void;
|
|
41
|
+
/** Placeholder text in the select element. */
|
|
42
|
+
placeholder?: string;
|
|
41
43
|
/** Offers the ability to hide the helper/invalid text. */
|
|
42
44
|
showHelperInvalidText?: boolean;
|
|
43
45
|
/** Offers the ability to show the select's label onscreen or hide it. Refer
|
|
@@ -72,11 +74,12 @@ const Select = React.forwardRef<
|
|
|
72
74
|
labelText,
|
|
73
75
|
name,
|
|
74
76
|
onChange,
|
|
77
|
+
placeholder,
|
|
75
78
|
showHelperInvalidText = true,
|
|
76
79
|
showLabel = true,
|
|
77
80
|
showOptReqLabel = true,
|
|
78
81
|
type = SelectTypes.Default,
|
|
79
|
-
value,
|
|
82
|
+
value = "",
|
|
80
83
|
} = props;
|
|
81
84
|
const ariaAttributes = {};
|
|
82
85
|
const optReqFlag = isRequired ? "Required" : "Optional";
|
|
@@ -87,7 +90,7 @@ const Select = React.forwardRef<
|
|
|
87
90
|
const footnote = isInvalid ? finalInvalidText : helperText;
|
|
88
91
|
// To control the `Select` component, both `onChange` and `value`
|
|
89
92
|
// must be passed.
|
|
90
|
-
const controlledProps = onChange
|
|
93
|
+
const controlledProps = onChange ? { onChange, value } : {};
|
|
91
94
|
|
|
92
95
|
if (!showLabel) {
|
|
93
96
|
ariaAttributes["aria-label"] =
|
|
@@ -126,6 +129,7 @@ const Select = React.forwardRef<
|
|
|
126
129
|
isDisabled={isDisabled}
|
|
127
130
|
isInvalid={isInvalid}
|
|
128
131
|
name={name}
|
|
132
|
+
placeholder={placeholder}
|
|
129
133
|
ref={ref}
|
|
130
134
|
{...controlledProps}
|
|
131
135
|
{...ariaAttributes}
|
|
@@ -40,7 +40,7 @@ import DSProvider from "../../theme/provider";
|
|
|
40
40
|
| Component Version | DS Version |
|
|
41
41
|
| ----------------- | ---------- |
|
|
42
42
|
| Added | `0.25.4` |
|
|
43
|
-
| Latest | `0.25.
|
|
43
|
+
| Latest | `0.25.8` |
|
|
44
44
|
|
|
45
45
|
<Description of={Slider} />
|
|
46
46
|
|
|
@@ -439,7 +439,8 @@ Pass a callback function to the `onChange` prop to get the current number value
|
|
|
439
439
|
of the `Slider` component or an array of two numbers when it is a range slider.
|
|
440
440
|
Internally, the `Slider` component handles the state of the current selected
|
|
441
441
|
value or values. Once the value(s) is updated, the `onChange` callback will be
|
|
442
|
-
called and the values will be passed.
|
|
442
|
+
called and the values will be passed. If no `onChange` callback is provided,
|
|
443
|
+
you won't be able to get the updated value(s) of the `Slider` component.
|
|
443
444
|
|
|
444
445
|
#### Single Slider Value
|
|
445
446
|
|
|
@@ -294,6 +294,26 @@ describe("Slider", () => {
|
|
|
294
294
|
expect(input).toHaveValue(100);
|
|
295
295
|
});
|
|
296
296
|
|
|
297
|
+
it("doesn't crash if no onChange callback function is passed", () => {
|
|
298
|
+
let currentValue = 0;
|
|
299
|
+
render(
|
|
300
|
+
<Slider
|
|
301
|
+
defaultValue={50}
|
|
302
|
+
helperText="Component helper text."
|
|
303
|
+
invalidText="Component error text :("
|
|
304
|
+
labelText="Label"
|
|
305
|
+
/>
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
const input = screen.getByRole("spinbutton");
|
|
309
|
+
fireEvent.change(input, {
|
|
310
|
+
target: { value: "42" },
|
|
311
|
+
});
|
|
312
|
+
// While we change the slider input value, since there is no onChange
|
|
313
|
+
// function, there is no way to update this local `currentValue` variable.
|
|
314
|
+
expect(currentValue).toEqual(0);
|
|
315
|
+
});
|
|
316
|
+
|
|
297
317
|
it("gets the current value through the onChange callback function", () => {
|
|
298
318
|
let currentValue = 0;
|
|
299
319
|
function onChange(value) {
|
|
@@ -495,6 +515,21 @@ describe("Slider", () => {
|
|
|
495
515
|
);
|
|
496
516
|
});
|
|
497
517
|
|
|
518
|
+
it("renders with min and max values as the default values if no `defaultValue` array is passed", () => {
|
|
519
|
+
render(
|
|
520
|
+
<Slider
|
|
521
|
+
helperText="Component helper text."
|
|
522
|
+
invalidText="Component error text :("
|
|
523
|
+
isRangeSlider
|
|
524
|
+
labelText="Label"
|
|
525
|
+
max={80}
|
|
526
|
+
min={30}
|
|
527
|
+
/>
|
|
528
|
+
);
|
|
529
|
+
expect(screen.getByText("30")).toBeInTheDocument();
|
|
530
|
+
expect(screen.getByText("80")).toBeInTheDocument();
|
|
531
|
+
});
|
|
532
|
+
|
|
498
533
|
it("renders the invalid state if the start and end values are wrong", () => {
|
|
499
534
|
// The start value is bigger than the end value.
|
|
500
535
|
render(
|
|
@@ -97,8 +97,14 @@ export default function Slider(props: React.PropsWithChildren<SliderProps>) {
|
|
|
97
97
|
showValues = true,
|
|
98
98
|
step = 1,
|
|
99
99
|
} = props;
|
|
100
|
+
// For the RangeSlider, if the defaultValue is not an array, then we set
|
|
101
|
+
// the defaultValue to an array with the min and max values.
|
|
102
|
+
const rangeSliderDefault =
|
|
103
|
+
typeof defaultValue === "number" ? [min, max] : defaultValue;
|
|
104
|
+
// We need to set the default value correctly for both types of sliders.
|
|
105
|
+
const finalDevaultValue = isRangeSlider ? rangeSliderDefault : defaultValue;
|
|
100
106
|
const [currentValue, setCurrentValue] = React.useState<typeof defaultValue>(
|
|
101
|
-
|
|
107
|
+
finalDevaultValue
|
|
102
108
|
);
|
|
103
109
|
let finalIsInvalid = isInvalid;
|
|
104
110
|
// In the Range Slider, if the first value is bigger than the second value,
|
|
@@ -127,7 +133,7 @@ export default function Slider(props: React.PropsWithChildren<SliderProps>) {
|
|
|
127
133
|
onChange: (val) => setCurrentValue(val),
|
|
128
134
|
// Call the passed in `onChange` function prop to get the
|
|
129
135
|
// *final* value once a user stops dragging the slider.
|
|
130
|
-
onChangeEnd: (val) => onChange(val),
|
|
136
|
+
onChangeEnd: (val) => onChange && onChange(val),
|
|
131
137
|
step,
|
|
132
138
|
};
|
|
133
139
|
// Props that the two `TextInput` components use.
|