@nypl/design-system-react-components 0.25.0 → 0.25.1

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 (236) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/components/Accordion/Accordion.d.ts +14 -14
  3. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +11 -14
  4. package/dist/components/Breadcrumbs/BreadcrumbsTypes.d.ts +6 -0
  5. package/dist/components/Button/ButtonTypes.d.ts +2 -1
  6. package/dist/components/Card/Card.d.ts +1 -1
  7. package/dist/components/Card/CardTypes.d.ts +2 -2
  8. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +43 -0
  9. package/dist/components/CheckboxGroup/CheckboxGroupLayoutTypes.d.ts +4 -0
  10. package/dist/components/DatePicker/DatePicker.d.ts +3 -3
  11. package/dist/components/Form/Form.d.ts +13 -8
  12. package/dist/components/Form/FormTypes.d.ts +2 -8
  13. package/dist/components/Grid/GridTypes.d.ts +9 -0
  14. package/dist/components/Grid/SimpleGrid.d.ts +14 -0
  15. package/dist/components/Heading/Heading.d.ts +4 -4
  16. package/dist/components/Hero/Hero.d.ts +19 -14
  17. package/dist/components/Hero/HeroTypes.d.ts +10 -5
  18. package/dist/components/Icons/Icon.d.ts +13 -16
  19. package/dist/components/Icons/IconTypes.d.ts +78 -64
  20. package/dist/components/Label/Label.d.ts +5 -17
  21. package/dist/components/Link/Link.d.ts +8 -12
  22. package/dist/components/SearchBar/SearchBar.d.ts +45 -27
  23. package/dist/components/Select/Select.d.ts +32 -35
  24. package/dist/components/Select/SelectTypes.d.ts +4 -0
  25. package/dist/components/SkeletonLoader/SkeletonLoader.d.ts +1 -1
  26. package/dist/components/SkeletonLoader/SkeletonLoaderTypes.d.ts +2 -2
  27. package/dist/components/StatusBadge/StatusBadge.d.ts +8 -6
  28. package/dist/components/StatusBadge/StatusBadgeTypes.d.ts +5 -0
  29. package/dist/components/Template/Template.d.ts +91 -0
  30. package/dist/components/Text/Text.d.ts +16 -0
  31. package/dist/components/Text/TextTypes.d.ts +6 -0
  32. package/dist/components/TextInput/TextInput.d.ts +32 -31
  33. package/dist/components/TextInput/TextInputTypes.d.ts +5 -0
  34. package/dist/design-system-react-components.cjs.development.js +2597 -1170
  35. package/dist/design-system-react-components.cjs.development.js.map +1 -1
  36. package/dist/design-system-react-components.cjs.production.min.js +1 -1
  37. package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
  38. package/dist/design-system-react-components.esm.js +2580 -1173
  39. package/dist/design-system-react-components.esm.js.map +1 -1
  40. package/dist/index.d.ts +8 -1
  41. package/dist/styles.css +1 -1
  42. package/dist/theme/components/accordion.d.ts +25 -0
  43. package/dist/theme/components/breadcrumb.d.ts +90 -0
  44. package/dist/theme/components/button.d.ts +17 -7
  45. package/dist/theme/components/checkbox.d.ts +7 -7
  46. package/dist/theme/components/customCheckboxGroup.d.ts +18 -0
  47. package/dist/theme/components/customRadioGroup.d.ts +4 -3
  48. package/dist/theme/components/global.d.ts +55 -0
  49. package/dist/theme/components/globalMixins.d.ts +15 -0
  50. package/dist/theme/components/heading.d.ts +50 -20
  51. package/dist/theme/components/hero.d.ts +492 -0
  52. package/dist/theme/components/icon.d.ts +13 -0
  53. package/dist/theme/components/label.d.ts +16 -0
  54. package/dist/theme/components/link.d.ts +45 -0
  55. package/dist/theme/components/radio.d.ts +8 -7
  56. package/dist/theme/components/searchBar.d.ts +20 -0
  57. package/dist/theme/components/select.d.ts +58 -0
  58. package/dist/theme/components/statusBadge.d.ts +25 -0
  59. package/dist/theme/components/tabs.d.ts +9 -9
  60. package/dist/theme/components/template.d.ts +105 -0
  61. package/dist/theme/components/text.d.ts +20 -0
  62. package/dist/theme/components/textInput.d.ts +105 -0
  63. package/dist/theme/foundations/global.d.ts +3 -0
  64. package/dist/theme/foundations/shadows.d.ts +4 -0
  65. package/dist/utils/utils.d.ts +6 -0
  66. package/package.json +3 -2
  67. package/src/components/Accordion/Accordion.stories.mdx +227 -33
  68. package/src/components/Accordion/Accordion.test.tsx +135 -19
  69. package/src/components/Accordion/Accordion.tsx +81 -56
  70. package/src/components/Autosuggest/Autosuggest.stories.mdx +1 -1
  71. package/src/components/Autosuggest/Autosuggest.stories.tsx +1 -1
  72. package/src/components/Autosuggest/_Autosuggest.scss +2 -2
  73. package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +46 -52
  74. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +31 -25
  75. package/src/components/Breadcrumbs/Breadcrumbs.tsx +71 -73
  76. package/src/components/Breadcrumbs/BreadcrumbsTypes.tsx +6 -0
  77. package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +100 -0
  78. package/src/components/Button/Button.stories.mdx +31 -27
  79. package/src/components/Button/Button.test.tsx +17 -5
  80. package/src/components/Button/ButtonTypes.tsx +1 -0
  81. package/src/components/Button/_Button.scss +3 -27
  82. package/src/components/Button/__snapshots__/Button.test.tsx.snap +11 -0
  83. package/src/components/Card/Card.stories.mdx +24 -20
  84. package/src/components/Card/Card.test.tsx +13 -19
  85. package/src/components/Card/Card.tsx +1 -1
  86. package/src/components/Card/CardTypes.tsx +2 -2
  87. package/src/components/Card/_Card.scss +1 -1
  88. package/src/components/CardEdition/CardEdition.stories.tsx +11 -6
  89. package/src/components/CardEdition/CardEdition.test.tsx +23 -31
  90. package/src/components/CardEdition/_CardEdition.scss +2 -2
  91. package/src/components/Chakra/Center.stories.mdx +31 -14
  92. package/src/components/Chakra/Grid.stories.mdx +79 -0
  93. package/src/components/Chakra/Stack.stories.mdx +4 -4
  94. package/src/components/Checkbox/Checkbox.tsx +9 -12
  95. package/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap +2 -5
  96. package/src/components/CheckboxGroup/CheckboxGroup.stories.mdx +249 -0
  97. package/src/components/CheckboxGroup/CheckboxGroup.test.tsx +345 -0
  98. package/src/components/CheckboxGroup/CheckboxGroup.tsx +148 -0
  99. package/src/components/CheckboxGroup/CheckboxGroupLayoutTypes.tsx +4 -0
  100. package/src/components/CheckboxGroup/__snapshots__/CheckboxGroup.test.tsx.snap +1360 -0
  101. package/src/components/DatePicker/DatePicker.test.tsx +4 -4
  102. package/src/components/DatePicker/DatePicker.tsx +13 -13
  103. package/src/components/DatePicker/_DatePicker.scss +1 -0
  104. package/src/components/Form/Form.stories.mdx +46 -21
  105. package/src/components/Form/Form.test.tsx +58 -45
  106. package/src/components/Form/Form.tsx +49 -21
  107. package/src/components/Form/FormTypes.tsx +3 -8
  108. package/src/components/Form/__snapshots__/Form.test.tsx.snap +24 -14
  109. package/src/components/Grid/GridTypes.tsx +9 -0
  110. package/src/components/Grid/SimpleGrid.stories.mdx +275 -0
  111. package/src/components/Grid/SimpleGrid.test.tsx +66 -0
  112. package/src/components/Grid/SimpleGrid.tsx +37 -0
  113. package/src/components/Grid/__snapshots__/SimpleGrid.test.tsx.snap +8 -0
  114. package/src/components/Heading/Heading.stories.mdx +1 -0
  115. package/src/components/Heading/Heading.tsx +12 -6
  116. package/src/components/HelperErrorText/_HelperErrorText.scss +1 -1
  117. package/src/components/Hero/Hero.stories.mdx +188 -121
  118. package/src/components/Hero/Hero.test.tsx +537 -107
  119. package/src/components/Hero/Hero.tsx +79 -92
  120. package/src/components/Hero/HeroTypes.tsx +17 -5
  121. package/src/components/Hero/__snapshots__/Hero.test.tsx.snap +307 -0
  122. package/src/components/HorizontalRule/_HorizontalRule.scss +1 -1
  123. package/src/components/Icons/Icon.stories.mdx +83 -74
  124. package/src/components/Icons/Icon.test.tsx +30 -22
  125. package/src/components/Icons/Icon.tsx +63 -61
  126. package/src/components/Icons/IconTypes.tsx +80 -64
  127. package/src/components/Input/_Input.scss +2 -2
  128. package/src/components/Label/Label.stories.mdx +28 -7
  129. package/src/components/Label/Label.test.tsx +43 -12
  130. package/src/components/Label/Label.tsx +21 -34
  131. package/src/components/Label/__snapshots__/Label.test.tsx.snap +41 -0
  132. package/src/components/Link/Link.stories.mdx +41 -41
  133. package/src/components/Link/Link.test.tsx +33 -44
  134. package/src/components/Link/Link.tsx +114 -100
  135. package/src/components/List/List.stories.mdx +0 -2
  136. package/src/components/List/List.stories.tsx +5 -5
  137. package/src/components/List/_List.scss +3 -3
  138. package/src/components/Modal/_Modal.scss +1 -1
  139. package/src/components/Notification/Notification.stories.mdx +12 -1
  140. package/src/components/Notification/Notification.test.tsx +3 -16
  141. package/src/components/Notification/Notification.tsx +9 -10
  142. package/src/components/Notification/_Notification.scss +4 -4
  143. package/src/components/Pagination/Pagination.test.tsx +16 -10
  144. package/src/components/RadioGroup/RadioGroup.stories.mdx +1 -1
  145. package/src/components/RadioGroup/RadioGroup.tsx +2 -10
  146. package/src/components/SearchBar/SearchBar.Test.tsx +151 -16
  147. package/src/components/SearchBar/SearchBar.stories.mdx +189 -219
  148. package/src/components/SearchBar/SearchBar.tsx +151 -46
  149. package/src/components/Select/Select.stories.mdx +188 -170
  150. package/src/components/Select/Select.test.tsx +125 -380
  151. package/src/components/Select/Select.tsx +118 -165
  152. package/src/components/Select/SelectTypes.tsx +4 -0
  153. package/src/components/SkeletonLoader/SkeletonLoader.stories.mdx +13 -25
  154. package/src/components/SkeletonLoader/SkeletonLoader.test.tsx +7 -7
  155. package/src/components/SkeletonLoader/SkeletonLoader.tsx +4 -2
  156. package/src/components/SkeletonLoader/SkeletonLoaderTypes.tsx +2 -2
  157. package/src/components/SkeletonLoader/_SkeletonLoader.scss +3 -3
  158. package/src/components/StatusBadge/StatusBadge.stories.mdx +91 -0
  159. package/src/components/StatusBadge/StatusBadge.test.tsx +35 -7
  160. package/src/components/StatusBadge/StatusBadge.tsx +24 -25
  161. package/src/components/StatusBadge/StatusBadgeTypes.tsx +5 -0
  162. package/src/components/StatusBadge/__snapshots__/StatusBadge.test.tsx.snap +28 -0
  163. package/src/components/StyleGuide/Bidirectionality.stories.mdx +16 -16
  164. package/src/components/StyleGuide/Buttons.stories.mdx +15 -15
  165. package/src/components/StyleGuide/Colors.stories.mdx +336 -0
  166. package/src/components/StyleGuide/Iconography.stories.mdx +88 -90
  167. package/src/components/StyleGuide/UIDocCard.tsx +1 -1
  168. package/src/components/Tabs/Tabs.tsx +7 -9
  169. package/src/components/Template/Template.stories.mdx +574 -0
  170. package/src/components/Template/Template.test.tsx +124 -0
  171. package/src/components/Template/Template.tsx +226 -0
  172. package/src/components/Text/Text.stories.mdx +70 -0
  173. package/src/components/Text/Text.test.tsx +63 -0
  174. package/src/components/Text/Text.tsx +55 -0
  175. package/src/components/Text/TextTypes.tsx +6 -0
  176. package/src/components/Text/__snapshots__/Text.test.tsx.snap +33 -0
  177. package/src/components/TextInput/TextInput.stories.mdx +89 -90
  178. package/src/components/TextInput/TextInput.test.tsx +65 -86
  179. package/src/components/TextInput/TextInput.tsx +101 -95
  180. package/src/components/TextInput/TextInputTypes.tsx +6 -0
  181. package/src/components/VideoPlayer/_VideoPlayer.scss +1 -1
  182. package/src/docs/Chakra.stories.mdx +4 -4
  183. package/src/docs/Intro.stories.mdx +15 -13
  184. package/src/index.ts +20 -0
  185. package/src/styles/01-colors/_colors-brand.scss +6 -0
  186. package/src/styles/01-colors/_colors-utility.scss +14 -12
  187. package/src/styles/base/_04-base.scss +2 -1
  188. package/src/styles/base/_place-holder.scss +1 -1
  189. package/src/styles.scss +10 -12
  190. package/src/theme/components/accordion.ts +30 -0
  191. package/src/theme/components/breadcrumb.ts +77 -0
  192. package/src/theme/components/button.ts +77 -63
  193. package/src/theme/components/checkbox.ts +15 -27
  194. package/src/theme/components/customCheckboxGroup.ts +12 -0
  195. package/src/theme/components/customRadioGroup.ts +4 -10
  196. package/src/theme/components/global.ts +71 -0
  197. package/src/theme/components/globalMixins.ts +16 -0
  198. package/src/theme/components/heading.ts +15 -8
  199. package/src/theme/components/hero.ts +239 -0
  200. package/src/theme/components/icon.ts +79 -0
  201. package/src/theme/components/label.ts +17 -0
  202. package/src/theme/components/link.ts +47 -0
  203. package/src/theme/components/radio.ts +20 -31
  204. package/src/theme/components/searchBar.ts +21 -0
  205. package/src/theme/components/select.ts +50 -0
  206. package/src/theme/components/statusBadge.ts +27 -0
  207. package/src/theme/components/tabs.ts +72 -69
  208. package/src/theme/components/template.ts +114 -0
  209. package/src/theme/components/text.ts +31 -0
  210. package/src/theme/components/textInput.ts +61 -0
  211. package/src/theme/foundations/colors.ts +29 -13
  212. package/src/theme/foundations/global.ts +3 -0
  213. package/src/theme/foundations/shadows.ts +5 -0
  214. package/src/theme/index.ts +37 -7
  215. package/src/utils/componentCategories.ts +8 -2
  216. package/src/utils/utils.ts +13 -0
  217. package/dist/components/Accordion/Accordion.stories.d.ts +0 -6
  218. package/dist/components/StatusBadge/StatusBadge.stories.d.ts +0 -8
  219. package/dist/components/StyleGuide/Colors.stories.d.ts +0 -25
  220. package/dist/components/Template/Template.stories.d.ts +0 -30
  221. package/src/components/Accordion/Accordion.stories.tsx +0 -66
  222. package/src/components/Accordion/_Accordion.scss +0 -81
  223. package/src/components/Breadcrumbs/_Breadcrumbs.scss +0 -97
  224. package/src/components/Form/_Form.scss +0 -67
  225. package/src/components/Hero/_Hero.scss +0 -256
  226. package/src/components/Icons/_Icons.scss +0 -116
  227. package/src/components/Label/_Label.scss +0 -22
  228. package/src/components/Link/_Link.scss +0 -73
  229. package/src/components/SearchBar/_SearchBar.scss +0 -16
  230. package/src/components/Select/_Select.scss +0 -82
  231. package/src/components/StatusBadge/StatusBadge.stories.tsx +0 -34
  232. package/src/components/StatusBadge/_StatusBadge.scss +0 -23
  233. package/src/components/StyleGuide/Colors.stories.tsx +0 -289
  234. package/src/components/Template/Template.stories.tsx +0 -86
  235. package/src/components/Template/_Template.scss +0 -63
  236. package/src/components/TextInput/_TextInput.scss +0 -59
@@ -2,20 +2,12 @@ import {
2
2
  Meta,
3
3
  Story,
4
4
  ArgsTable,
5
- Preview,
5
+ Canvas,
6
6
  Description,
7
7
  } from "@storybook/addon-docs/blocks";
8
8
  import { withDesign } from "storybook-addon-designs";
9
9
 
10
10
  import SearchBar from "./SearchBar";
11
- import Select from "../Select/Select";
12
- import HelperErrorText from "../HelperErrorText/HelperErrorText";
13
- import Button from "../Button/Button";
14
- import { ButtonTypes } from "../Button/ButtonTypes";
15
- import Icon from "../Icons/Icon";
16
- import { IconNames } from "../Icons/IconTypes";
17
- import Input from "../Input/Input";
18
- import { InputTypes } from "../Input/InputTypes";
19
11
  import * as stories from "../Autosuggest/Autosuggest.stories.tsx";
20
12
  import { getCategory } from "../../utils/componentCategories";
21
13
  import DSProvider from "../../theme/provider";
@@ -33,9 +25,16 @@ import DSProvider from "../../theme/provider";
33
25
  jest: ["SearchBar.test.tsx"],
34
26
  }}
35
27
  argTypes={{
36
- blockName: {
37
- table: { disable: true },
38
- },
28
+ action: { table: { disable: true } },
29
+ ariaLabel: { table: { disable: true } },
30
+ buttonOnClick: { table: { disable: true } },
31
+ className: { table: { disable: true } },
32
+ id: { table: { disable: true } },
33
+ method: { table: { disable: true } },
34
+ onSubmit: { table: { disable: true } },
35
+ selectProps: { table: { disable: true } },
36
+ textInputProps: { table: { disable: true } },
37
+ textInputElement: { table: { disable: true } },
39
38
  }}
40
39
  />
41
40
 
@@ -43,178 +42,183 @@ import DSProvider from "../../theme/provider";
43
42
 
44
43
  <Description of={SearchBar} />
45
44
 
46
- The main wrapper element that is rendered is `<form>` DOM element. All the props
47
- passed to `SearchBar` will apply to the `<form>` element. If you need to update
48
- the children, make sure the props are passed to the appropriate components.
45
+ The main wrapper element that is rendered is a `<form>` DOM element. All the
46
+ props passed to `SearchBar` will apply to the `<form>` element and its children.
47
+ The `SearchBar` component will render a `Select` component (optional),
48
+ `TextInput` component, `Button` component, and `HelperErrorText` component
49
+ based on the required props.
49
50
 
50
51
  The `Select` dropdown narrows the search within a specific category, typically
51
- title or author. You should only have one `Select` component at a time. If you
52
- need more options, link to the advance search page. Toggle the `Select` through
53
- the Controls.
54
-
55
- _Note: The `HelperErrorText` component should be the next direct sibling of the
56
- `SearchBar` component if it will be used._
57
-
58
- export const optionsGroup = {
59
- Art: [
60
- "Academic Painting",
61
- "Amazing Painting",
62
- "Ancient Statue",
63
- "Basic Painting",
64
- "Beautiful Statue",
65
- ],
66
- Bushes: [
67
- "Blue-Hydrangea Bush",
68
- "Blue-Hydrangea Start",
69
- "Holly Bush",
70
- "Orange-Tea-Olive Bush",
71
- "Pink Camellia Bush",
72
- ],
73
- Clothing: ["3D Glasses", "Academy Uniform", "Acid-Washed Jacket"],
74
- "DIY Recipes": ["Acorn Pochette", "Acoustic Guitar", "Angled Signpost"],
75
- Flowers: [
76
- "Black Cosmos",
77
- "Blue Pansies",
78
- "Gold Roses",
79
- "Lily of the Valley",
80
- "Orange Hyacinth",
81
- ],
82
- Fossils: [
83
- "Acanthostega",
84
- "Amber",
85
- "Ammonite",
86
- "Ankylo Skull",
87
- "Anomalocaris",
88
- "Australopith",
89
- ],
90
- Fruits: ["Apples", "Oranges", "Pears", "Coconuts", "Cherries"],
91
- Furniture: [
92
- "Abstract Wall",
93
- "Accessories Stand",
94
- "ACNH Switch",
95
- "Air Circulator",
96
- ],
97
- Materials: [
98
- "Acorn",
99
- "Aquaris Fragment",
100
- "Bamboo Piece",
101
- "Boot",
102
- "Clump of Weeds",
103
- ],
104
- NPC: ["Celeste", "Kicks", "Leif", "Redd", "Saharah"],
105
- Songs: ["Agent K.K.", "Café K.K.", "Comrade K.K."],
106
- Tools: [
107
- "Axe",
108
- "Bamboo Wand",
109
- "Fishing Rod",
110
- "Shovel",
111
- "Slingshot",
112
- "Watering Can",
113
- ],
114
- Villagers: ["Agnes", "Alfonso", "Anchovy", "Axel", "Aurora"],
115
- };
52
+ title or author. Toggle the `Select` through the Controls.
53
+
54
+ export const optionsGroup = [
55
+ "Art",
56
+ "Bushes",
57
+ "Clothing",
58
+ "Flowers",
59
+ "Fossils",
60
+ "Fruits",
61
+ "Furniture",
62
+ "Songs",
63
+ "Tools",
64
+ "Villagers",
65
+ ];
116
66
 
117
- <Preview withToolbar>
67
+ <Canvas withToolbar>
118
68
  <Story
119
69
  name="Basic"
120
70
  args={{
121
71
  showHelperText: true,
122
72
  showSelect: true,
123
- isErrorState: false,
124
- disabledButton: false,
73
+ invalidText: "Could not find the item :(",
74
+ isDisabled: false,
75
+ isInvalid: false,
76
+ isRequired: false,
77
+ helperErrorText: "Search for items in Animal Crossing New Horizons",
125
78
  }}
126
79
  >
127
80
  {(args) => (
128
- <div>
129
- <SearchBar {...args}>
130
- {args.showSelect && (
131
- <Select
132
- name="nhItemSearch"
133
- ariaLabel="Filter Search"
134
- id="select-searchBar"
135
- isRequired={false}
136
- >
137
- {Object.keys(optionsGroup).map((nhOption) => (
138
- <option key={nhOption} aria-selected={false}>
139
- {nhOption}
140
- </option>
141
- ))}
142
- </Select>
143
- )}
144
- <Input
145
- id="inputBasic"
146
- ariaLabelledBy="buttonBasic"
147
- placeholder="Item Search"
148
- required={true}
149
- type={InputTypes.text}
150
- attributes={{
151
- ["aria-describedby"]: "helperTextBasic",
152
- }}
153
- errored={args.isErrorState}
154
- />
155
- <Button
156
- buttonType={ButtonTypes.Primary}
157
- id="buttonBasic"
158
- type="submit"
159
- disabled={args.disabledButton}
160
- >
161
- <Icon
162
- name={IconNames.search}
163
- decorative={true}
164
- modifiers={["small", "icon-left"]}
165
- />
166
- Search
167
- </Button>
168
- </SearchBar>
169
- {args.showHelperText && (
170
- <HelperErrorText id="helperTextBasic" isError={args.isErrorState}>
171
- Search for items in Animal Crossing New Horizons
172
- </HelperErrorText>
173
- )}
174
- </div>
81
+ <SearchBar
82
+ onSubmit={() => {}}
83
+ {...args}
84
+ selectProps={
85
+ args.showSelect && {
86
+ name: "nhItemSearch",
87
+ labelText: "Select a category",
88
+ optionsData: optionsGroup,
89
+ }
90
+ }
91
+ textInputProps={{
92
+ labelText: "Item Search",
93
+ placeholder: "Item Search",
94
+ }}
95
+ helperErrorText={args.showHelperText && args.helperErrorText}
96
+ />
175
97
  )}
176
98
  </Story>
177
- </Preview>
99
+ </Canvas>
178
100
 
179
101
  <ArgsTable story="Basic" />
180
102
 
103
+ ## Component Props
104
+
105
+ ### Select Component
106
+
107
+ To render an optional `Select` component, an object must be passed to the
108
+ `selectProps` prop. It _must_ include `name`, `labelText`, and `optionsData`
109
+ properties. The `labelText` value won't be rendered but will be used for its
110
+ `aria-label` attribute.
111
+
112
+ ```
113
+ const selectProps = {
114
+ name: "select-form-name",
115
+ labelText: "Select a category",
116
+ optionsData: optionsGroup,
117
+ };
118
+
119
+ // ...
120
+ <SearchBar
121
+ onSubmit={() => {}}
122
+ selectProps={selectProps}
123
+ // ...
124
+ />
125
+ ```
126
+
127
+ ### TextInput Component
128
+
129
+ To render the `TextInput` component, an object must be passed to the
130
+ `textInputProps` prop. It _must_ include `labelText` and `placeholder`
131
+ properties. The `labelText` value won't be rendered but will be used for its
132
+ `aria-label` attribute.
133
+
134
+ ```
135
+ const textInputProps = {
136
+ labelText: "Item Search",
137
+ placeholder: "Item Search",
138
+ };
139
+
140
+ // ...
141
+ <SearchBar
142
+ onSubmit={() => {}}
143
+ textInputProps={textInputProps}
144
+ // ...
145
+ />
146
+ ```
147
+
148
+ ### Custom Input Component
149
+
150
+ To render a custom input component, pass the component to the `textInputElement`
151
+ prop. This will render your custom input component such as an `Autocomplete`
152
+ component. Check the "Search Autocomplete" example for more details.
153
+
154
+ ```
155
+ const textInputElement = <CustomInput {...props} />;
156
+
157
+ // ...
158
+ <SearchBar
159
+ onSubmit={() => {}}
160
+ textInputElement={textInputElement}
161
+ // ...
162
+ />
163
+ ```
164
+
165
+ ### Button Component
166
+
167
+ A `Button` component will automatically be rendered for the `SearchBar`
168
+ component. If you want to pass a callback function to the `Button`, use the
169
+ `buttonOnClick` prop.
170
+
171
+ ### HelperErrorText Component
172
+
173
+ To render the `HelperErrorText` component, pass a string value to the
174
+ `helperErrorText` prop. For the invalid state when `isInvalid` is true, pass the
175
+ error string in the `invalidText` prop.
176
+
177
+ ```
178
+ const helperErrorText = "";
179
+
180
+ // ...
181
+ <SearchBar
182
+ onSubmit={() => {}}
183
+ helperErrorText="Search for items in Animal Crossing New Horizons"
184
+ // ...
185
+ />
186
+ ```
187
+
181
188
  ## Search Autocomplete
182
189
 
183
190
  While the Design System does not implement an `Autosuggest` or `Autocomplete`
184
191
  component, it does show a pattern for using the `react-autosuggest` package.
185
192
  In this example, we're using the `react-autosuggest` example found in the
186
193
  [Basic Autosuggest story](https://nypl.github.io/nypl-design-system/storybook-static/?path=/story/autosuggest--autosuggest-library)
187
- as the main component inside the `SearchBar` component. See the combination of
188
- the Autosuggest story along with this story to see how to compose all the
189
- components together.
194
+ as the main component inside the `SearchBar` component.
190
195
 
191
- <Preview withToolbar>
192
- <Story name="Search Autocomplete">
196
+ In order to render this custom input element in the `SearchBar` component, pass
197
+ it in the `textInputElement` prop. Do not pass an object to the `textInputProps`
198
+ prop since the custom input component passed in `textInputElement` will take
199
+ precedence.
200
+
201
+ <Canvas withToolbar>
202
+ <Story
203
+ name="Search Autocomplete"
204
+ args={{
205
+ isInvalid: false,
206
+ isDisabled: false,
207
+ isRequired: false,
208
+ }}
209
+ >
193
210
  {(args) => (
194
211
  <div style={{ minHeight: "150px" }}>
195
- <SearchBar {...args}>
196
- {stories.SearchBarExample()}
197
- <Button
198
- buttonType={ButtonTypes.Primary}
199
- id="autosuggest-button"
200
- type="submit"
201
- >
202
- <Icon
203
- name={IconNames.search}
204
- decorative={true}
205
- modifiers={["small", "icon-left"]}
206
- />
207
- Search
208
- </Button>
209
- </SearchBar>
210
- <HelperErrorText id="autosuggest-helperText" isError={false}>
211
- Select your home library. Start by typing the name of the library. Try{" "}
212
- {'"'}ba{'"'}.
213
- </HelperErrorText>
212
+ <SearchBar
213
+ onSubmit={() => {}}
214
+ textInputElement={stories.SearchBarExample()}
215
+ helperErrorText="Select your home library. Start by typing the name of the library. Try 'ba'."
216
+ {...args}
217
+ />
214
218
  </div>
215
219
  )}
216
220
  </Story>
217
- </Preview>
221
+ </Canvas>
218
222
 
219
223
  ## Other Examples
220
224
 
@@ -223,75 +227,41 @@ Here are the same possible states of the `SearchBar` component in static example
223
227
 
224
228
  ### Error State
225
229
 
226
- For the error state, make sure that the `errored` prop is passed to the `Input`
227
- component and the `isError` prop is passed to the `HelperErrorText` component.
230
+ For the error state, set the `isInvalid` prop to `true`. This will update the
231
+ state for all its children. If you passed a custom input element, you must
232
+ handle the error state yourself.
228
233
 
229
- <Preview>
234
+ <Canvas>
230
235
  <DSProvider>
231
- <SearchBar>
232
- <Input
233
- ariaLabelledBy="button-error-state"
234
- id="input-error"
235
- placeholder="Item Search"
236
- required={true}
237
- type={InputTypes.text}
238
- errored={true}
239
- attributes={{
240
- ["aria-describedby"]: "error-helperText",
241
- }}
242
- />
243
- <Button
244
- buttonType={ButtonTypes.Primary}
245
- id="button-error-state"
246
- type="submit"
247
- >
248
- <Icon
249
- name={IconNames.search}
250
- decorative={true}
251
- modifiers={["small", "icon-left"]}
252
- />
253
- Search
254
- </Button>
255
- </SearchBar>
256
- <HelperErrorText id="error-helperText" isError={true}>
257
- Sorry, we can't find that item!
258
- </HelperErrorText>
236
+ <SearchBar
237
+ onSubmit={() => {}}
238
+ textInputProps={{
239
+ labelText: "Item Search",
240
+ placeholder: "Item Search",
241
+ }}
242
+ helperErrorText="Sorry, we can't find that item!"
243
+ invalidText="Could not find the item :("
244
+ isInvalid
245
+ />
259
246
  </DSProvider>
260
- </Preview>
261
-
262
- <br />
247
+ </Canvas>
263
248
 
264
249
  ### Disabled State
265
250
 
266
- For the disabled state, make sure to pass the `disabled` prop to the
267
- `Button` component.
251
+ For the disabled state, set the `isDisabled` prop to `true`. This will update
252
+ the state for all its children. If you passed a custom input element, you must
253
+ handle the disabled state yourself.
268
254
 
269
- <Preview>
255
+ <Canvas>
270
256
  <DSProvider>
271
- <SearchBar>
272
- <Input
273
- ariaLabelledBy="button-disabled"
274
- id="input-disabled"
275
- placeholder="Item Search"
276
- required={true}
277
- type={InputTypes.text}
278
- />
279
- <Button
280
- buttonType={ButtonTypes.Primary}
281
- id="button-disabled"
282
- type="submit"
283
- disabled={true}
284
- >
285
- <Icon
286
- name={IconNames.search}
287
- decorative={true}
288
- modifiers={["small", "icon-left"]}
289
- />
290
- Search
291
- </Button>
292
- </SearchBar>
293
- <HelperErrorText id="error-disabled">
294
- Reason for disabled state.
295
- </HelperErrorText>
257
+ <SearchBar
258
+ obSubmit={() => {}}
259
+ textInputProps={{
260
+ labelText: "Item Search",
261
+ placeholder: "Item Search",
262
+ }}
263
+ helperErrorText="Reason for disabled state."
264
+ isDisabled
265
+ />
296
266
  </DSProvider>
297
- </Preview>
267
+ </Canvas>
@@ -1,69 +1,174 @@
1
1
  import * as React from "react";
2
- import bem from "../../utils/bem";
2
+ import { Box, useMultiStyleConfig } from "@chakra-ui/react";
3
+
4
+ import generateUUID from "../../helpers/generateUUID";
5
+ import Select from "../Select/Select";
6
+ import TextInput from "../TextInput/TextInput";
7
+ import { TextInputTypes, TextInputVariants } from "../TextInput/TextInputTypes";
8
+ import Button from "../Button/Button";
9
+ import { ButtonTypes } from "../Button/ButtonTypes";
10
+ import Icon from "../Icons/Icon";
11
+ import { IconAlign, IconNames, IconSizes } from "../Icons/IconTypes";
12
+ import HelperErrorText from "../HelperErrorText/HelperErrorText";
13
+ import { SelectTypes } from "../Select/SelectTypes";
14
+
15
+ // Internal interfaces that are used only for `SearchBar` props.
16
+ interface SelectProps {
17
+ labelText: string;
18
+ name: string;
19
+ optionsData: string[];
20
+ }
21
+ interface TextInputProps {
22
+ labelText: string;
23
+ placeholder: string;
24
+ }
3
25
 
4
26
  export interface SearchBarProps {
5
- /** Populates aria-label on the form;
6
- * defines a hidden string that labels
7
- * the SearchBar
8
- */
9
- ariaLabel?: string;
10
- /** Populates aria-labelledby on the form;
11
- * defines a visible string that labels
12
- * the SearchBar
13
- */
14
- ariaLabelledBy?: string;
15
- /** Additional attributes passed to the form */
16
- attributes?: { [key: string]: any };
17
- /** BlockName for use with BEM. See how to work with modifiers and BEM here: http://getbem.com/introduction/ */
18
- blockName?: string;
19
- /** ClassName that appears in addition to "search-bar" */
20
- className?: string;
21
- /** Adds 'method' property to the form */
22
- method?: string;
23
- /** Adds 'action' property to the form */
27
+ /** Adds 'action' property to the `form` element. */
24
28
  action?: string;
29
+ /** The onClick callback function for the `Button` component. */
30
+ buttonOnClick?: (event: React.MouseEvent | React.KeyboardEvent) => void;
31
+ /** A class name for the `form` element. */
32
+ className?: string;
33
+ /** The text to display below the form in a `HelperErrorText` component. */
34
+ helperErrorText?: string;
25
35
  /** ID that other components can cross reference for accessibility purposes */
26
36
  id?: string;
27
- /** Modifiers array for use with BEM. See how to work with modifiers and BEM here: http://getbem.com/introduction/ */
28
- modifiers?: string[];
29
- /** Handler on form submit */
37
+ /** Optional string to populate the `HelperErrorText` for the error state
38
+ * when `isInvalid` is true. */
39
+ invalidText?: string;
40
+ /** Sets children form components in the disabled state. */
41
+ isDisabled?: boolean;
42
+ /** Sets children form components in the error state. */
43
+ isInvalid?: boolean;
44
+ /** Sets children form components in the required state. */
45
+ isRequired?: boolean;
46
+ /** Populates the `aria-label` attribute on the form element. */
47
+ labelText: string;
48
+ /** Adds 'method' property to the `form` element. */
49
+ method?: string;
50
+ /** Handler function when the form is submitted. */
30
51
  onSubmit: (event: React.FormEvent) => void;
52
+ /** Required props to render a `Select` element. */
53
+ selectProps?: SelectProps | undefined;
54
+ /** Will be used to visually display the label text for this
55
+ * `SearchBar` component. False by default. */
56
+ showLabel?: boolean;
57
+ /** Custom input element to render instead of a `TextInput` element. */
58
+ textInputElement?: JSX.Element;
59
+ /** Required props to render a `TextInput` element. */
60
+ textInputProps?: TextInputProps | undefined;
31
61
  }
32
62
 
33
- /** Renders a wrapper `form` element to be used with `Select` (optional),
34
- * `Input`, and `Button` components together. */
35
- export default function SearchBar(
36
- props: React.PropsWithChildren<SearchBarProps>
37
- ) {
63
+ /**
64
+ * Renders a wrapper `form` element to be used with `Select` (optional),
65
+ * `Input`, and `Button` components together.
66
+ */
67
+ export default function SearchBar(props: SearchBarProps) {
38
68
  const {
39
- ariaLabel,
40
- ariaLabelledBy,
41
- blockName,
42
- children,
69
+ action,
70
+ buttonOnClick = null,
43
71
  className,
44
- id,
45
- modifiers = [],
46
- onSubmit,
47
- attributes,
72
+ helperErrorText,
73
+ id = generateUUID(),
74
+ invalidText,
75
+ isDisabled = false,
76
+ isInvalid = false,
77
+ isRequired = false,
78
+ labelText,
48
79
  method,
49
- action,
80
+ onSubmit,
81
+ selectProps,
82
+ textInputElement,
83
+ textInputProps,
50
84
  } = props;
51
-
52
- const baseClass = "search-bar";
85
+ const styles = useMultiStyleConfig("SearchBar", { hasSelect: selectProps });
86
+ const stateProps = { isDisabled, isInvalid, isRequired };
87
+ const helperErrorTextID = generateUUID();
88
+ const ariaDescribedby = helperErrorTextID;
89
+ const footnote = isInvalid ? invalidText : helperErrorText;
90
+ const finalAriaLabel = footnote ? `${labelText} - ${footnote}` : labelText;
91
+ // Render the `Select` component.
92
+ const selectElem = selectProps && (
93
+ <Select
94
+ id={generateUUID()}
95
+ name={selectProps?.name}
96
+ labelText={selectProps?.labelText}
97
+ showLabel={false}
98
+ helperText=""
99
+ type={SelectTypes.SearchBar}
100
+ {...stateProps}
101
+ >
102
+ {selectProps?.optionsData.map((option) => (
103
+ <option key={option} value={option}>
104
+ {option}
105
+ </option>
106
+ ))}
107
+ </Select>
108
+ );
109
+ // Render the `TextInput` component.
110
+ const textInputNative = textInputProps && (
111
+ <TextInput
112
+ id={generateUUID()}
113
+ labelText={textInputProps?.labelText}
114
+ placeholder={textInputProps?.placeholder}
115
+ type={TextInputTypes.text}
116
+ variantType={
117
+ selectElem
118
+ ? TextInputVariants.SearchBarSelect
119
+ : TextInputVariants.SearchBar
120
+ }
121
+ helperText=""
122
+ showLabel={false}
123
+ {...stateProps}
124
+ />
125
+ );
126
+ // Render the `Button` component.
127
+ const buttonElem = (
128
+ <Button
129
+ id={generateUUID()}
130
+ buttonType={ButtonTypes.SearchBar}
131
+ type="submit"
132
+ onClick={buttonOnClick}
133
+ disabled={isDisabled}
134
+ >
135
+ <Icon
136
+ name={IconNames.Search}
137
+ size={IconSizes.Small}
138
+ align={IconAlign.Left}
139
+ />
140
+ Search
141
+ </Button>
142
+ );
143
+ // Render the `HelperErrorText` component.
144
+ const helperErrorTextElem = footnote && (
145
+ <HelperErrorText id={helperErrorTextID} isError={isInvalid}>
146
+ {footnote}
147
+ </HelperErrorText>
148
+ );
149
+ // If a custom input element was passed, use that instead of the
150
+ // `TextInput` component.
151
+ const textInputElem = textInputElement || textInputNative;
53
152
 
54
153
  return (
55
- <form
56
- className={bem(baseClass, modifiers, blockName, [className])}
154
+ <Box
155
+ as="form"
57
156
  id={id}
157
+ className={className}
58
158
  role="search"
59
- aria-label={ariaLabel}
60
- aria-labelledby={ariaLabelledBy}
159
+ aria-label={finalAriaLabel}
160
+ aria-describedby={ariaDescribedby}
61
161
  onSubmit={onSubmit}
62
162
  method={method}
63
163
  action={action}
64
- {...attributes}
164
+ __css={styles}
65
165
  >
66
- {children}
67
- </form>
166
+ <Box __css={styles.topRow}>
167
+ {selectElem}
168
+ {textInputElem}
169
+ {buttonElem}
170
+ </Box>
171
+ {helperErrorTextElem}
172
+ </Box>
68
173
  );
69
174
  }