@popsure/dirty-swan 0.65.1 → 0.66.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 (53) hide show
  1. package/dist/cjs/index.d.ts +2 -2
  2. package/dist/cjs/index.js +361 -209
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/lib/components/searchableDropdown/index.d.ts +22 -0
  5. package/dist/cjs/lib/components/searchableDropdown/index.stories.d.ts +108 -0
  6. package/dist/cjs/lib/components/searchableDropdown/index.test.d.ts +1 -0
  7. package/dist/cjs/lib/hooks/useDropdownAlignment.d.ts +5 -0
  8. package/dist/cjs/lib/index.d.ts +3 -2
  9. package/dist/esm/{Calendar-C7I0F5Gv.js → Calendar-8rhyapMz.js} +3 -19
  10. package/dist/esm/Calendar-8rhyapMz.js.map +1 -0
  11. package/dist/esm/components/dateSelector/components/Calendar.js +2 -1
  12. package/dist/esm/components/dateSelector/components/Calendar.js.map +1 -1
  13. package/dist/esm/components/dateSelector/index.js +2 -1
  14. package/dist/esm/components/dateSelector/index.js.map +1 -1
  15. package/dist/esm/components/dateSelector/index.stories.js +2 -1
  16. package/dist/esm/components/dateSelector/index.stories.js.map +1 -1
  17. package/dist/esm/components/dateSelector/index.test.js +2 -1
  18. package/dist/esm/components/dateSelector/index.test.js.map +1 -1
  19. package/dist/esm/components/searchableDropdown/index.js +13 -0
  20. package/dist/esm/components/searchableDropdown/index.js.map +1 -0
  21. package/dist/esm/components/searchableDropdown/index.stories.js +201 -0
  22. package/dist/esm/components/searchableDropdown/index.stories.js.map +1 -0
  23. package/dist/esm/components/searchableDropdown/index.test.js +607 -0
  24. package/dist/esm/components/searchableDropdown/index.test.js.map +1 -0
  25. package/dist/esm/components/toast/index.js +1 -1
  26. package/dist/esm/components/toast/index.stories.js +1 -1
  27. package/dist/esm/components/toast/index.test.js +1 -1
  28. package/dist/esm/{index-C4IAMlRE.js → index-CT0_LjIR.js} +2 -2
  29. package/dist/esm/{index-C4IAMlRE.js.map → index-CT0_LjIR.js.map} +1 -1
  30. package/dist/esm/index-QeP_xz9v.js +175 -0
  31. package/dist/esm/index-QeP_xz9v.js.map +1 -0
  32. package/dist/esm/index.d.ts +2 -2
  33. package/dist/esm/index.js +7 -17
  34. package/dist/esm/index.js.map +1 -1
  35. package/dist/esm/lib/components/searchableDropdown/index.d.ts +22 -0
  36. package/dist/esm/lib/components/searchableDropdown/index.stories.d.ts +108 -0
  37. package/dist/esm/lib/components/searchableDropdown/index.test.d.ts +1 -0
  38. package/dist/esm/lib/hooks/useDropdownAlignment.d.ts +5 -0
  39. package/dist/esm/lib/index.d.ts +3 -2
  40. package/dist/esm/useOnClickOutside-B5hujnpp.js +21 -0
  41. package/dist/esm/useOnClickOutside-B5hujnpp.js.map +1 -0
  42. package/dist/esm/util/images/index.stories.js +2 -1
  43. package/dist/esm/util/images/index.stories.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/index.tsx +3 -0
  46. package/src/lib/components/searchableDropdown/index.stories.tsx +286 -0
  47. package/src/lib/components/searchableDropdown/index.test.tsx +355 -0
  48. package/src/lib/components/searchableDropdown/index.tsx +267 -0
  49. package/src/lib/components/searchableDropdown/style.module.scss +137 -0
  50. package/src/lib/hooks/useDropdownAlignment.test.ts +210 -0
  51. package/src/lib/hooks/useDropdownAlignment.ts +34 -0
  52. package/src/lib/index.tsx +8 -0
  53. package/dist/esm/Calendar-C7I0F5Gv.js.map +0 -1
@@ -19,6 +19,7 @@ import Chip from './components/chip';
19
19
  import { AutoSuggestInput } from './components/input/autoSuggestInput';
20
20
  import { ComparisonTable, TableRating, TableTrueFalse, TableRowHeader, TableButton, TableInfoButton, TableHeader } from './components/comparisonTable';
21
21
  import { SegmentedControl } from './components/segmentedControl';
22
+ import { SearchableDropdown, SearchableDropdownProps, SearchableDropdownOption } from './components/searchableDropdown';
22
23
  import { Link } from './components/link';
23
24
  import { illustrations, images, IllustrationKeys } from './util/images';
24
25
  import { Spinner } from './components/spinner';
@@ -40,6 +41,6 @@ import { LogoInverted } from './components/logo/LogoInverted';
40
41
  import { LogoPositiveColor } from './components/logo/LogoPositiveColor';
41
42
  import { LogoPositiveBlack } from './components/logo/LogoPositiveBlack';
42
43
  export * from './components/icon';
43
- export { Accordion, DateSelector, SignaturePad, AutocompleteAddress, Input, MultiDropzone, DownloadButton, IbanInput, BottomModal, RegularModal, BottomOrRegularModal, FullScreenModal, InfoCard, Card, CardButton, Button, CurrencyInput, AutoSuggestMultiSelect, Chip, AutoSuggestInput, ComparisonTable, TableRating, TableTrueFalse, TableRowHeader, TableButton, TableInfoButton, SegmentedControl, Checkbox, Radio, Link, InformationBox, Badge, images, illustrations, Spinner, Table, Toggle, Toaster, toast, useEscapeKey, useFocusWithin, useOnClickOutside, useMediaQuery, LogoColor, LogoWhite, LogoBlack, LogoOrangeBox, LogoInvertedColor, LogoInverted, LogoPositiveColor, LogoPositiveBlack, };
44
- export type { AccordionProps, BadgeProps, IllustrationKeys, InformationBoxProps, InputProps, FileType, MultiDropzoneProps, TableHeader, UploadedFile, UploadStatus, CardProps, IconWrapperProps, TableData, TableProps, };
44
+ export { Accordion, DateSelector, SignaturePad, AutocompleteAddress, Input, MultiDropzone, DownloadButton, IbanInput, BottomModal, RegularModal, BottomOrRegularModal, FullScreenModal, InfoCard, Card, CardButton, Button, CurrencyInput, AutoSuggestMultiSelect, Chip, AutoSuggestInput, ComparisonTable, TableRating, TableTrueFalse, TableRowHeader, TableButton, TableInfoButton, SearchableDropdown, SegmentedControl, Checkbox, Radio, Link, InformationBox, Badge, images, illustrations, Spinner, Table, Toggle, Toaster, toast, useEscapeKey, useFocusWithin, useOnClickOutside, useMediaQuery, LogoColor, LogoWhite, LogoBlack, LogoOrangeBox, LogoInvertedColor, LogoInverted, LogoPositiveColor, LogoPositiveBlack, };
45
+ export type { AccordionProps, SearchableDropdownProps, SearchableDropdownOption, BadgeProps, IllustrationKeys, InformationBoxProps, InputProps, FileType, MultiDropzoneProps, TableHeader, UploadedFile, UploadStatus, CardProps, IconWrapperProps, TableData, TableProps, };
45
46
  export type { DownloadStatus } from './models/download';
@@ -0,0 +1,21 @@
1
+ import { useEffect } from 'react';
2
+
3
+ var useOnClickOutside = function (ref, callback) {
4
+ useEffect(function () {
5
+ var listener = function (event) {
6
+ if (!ref.current || ref.current.contains(event.target)) {
7
+ return;
8
+ }
9
+ callback(event);
10
+ };
11
+ document.addEventListener('mousedown', listener);
12
+ document.addEventListener('touchstart', listener);
13
+ return function () {
14
+ document.removeEventListener('mousedown', listener);
15
+ document.removeEventListener('touchstart', listener);
16
+ };
17
+ }, [ref, callback]);
18
+ };
19
+
20
+ export { useOnClickOutside as u };
21
+ //# sourceMappingURL=useOnClickOutside-B5hujnpp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOnClickOutside-B5hujnpp.js","sources":["../../../src/lib/hooks/useOnClickOutside.ts"],"sourcesContent":["import { RefObject, useEffect } from 'react';\n\nexport const useOnClickOutside = (\n ref: RefObject<HTMLDivElement | null>,\n callback: (e: Event) => void\n) => {\n useEffect(() => {\n const listener = (event: Event) => {\n if (!ref.current || ref.current.contains(event.target as Node)) {\n return;\n }\n callback(event);\n };\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [ref, callback]);\n};\n"],"names":[],"mappings":";;AAEO,IAAM,iBAAiB,GAAG,UAC/B,GAAqC,EACrC,QAA4B,EAAA;AAE5B,IAAA,SAAS,CAAC,YAAA;QACR,IAAM,QAAQ,GAAG,UAAC,KAAY,EAAA;AAC5B,YAAA,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC,EAAE;gBAC9D;YACF;YACA,QAAQ,CAAC,KAAK,CAAC;AACjB,QAAA,CAAC;AACD,QAAA,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,QAAQ,CAAC;AAChD,QAAA,QAAQ,CAAC,gBAAgB,CAAC,YAAY,EAAE,QAAQ,CAAC;QACjD,OAAO,YAAA;AACL,YAAA,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC;AACnD,YAAA,QAAQ,CAAC,mBAAmB,CAAC,YAAY,EAAE,QAAQ,CAAC;AACtD,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACrB;;;;"}
@@ -18,7 +18,8 @@ import '../../components/table/components/TableCell/TableCell.js';
18
18
  import { s as styleInject } from '../../style-inject.es-tgCJW-Cu.js';
19
19
  import '../../_commonjsHelpers-BFTU3MAI.js';
20
20
  import '../../tslib.es6-CVlKGIvp.js';
21
- import '../../Calendar-C7I0F5Gv.js';
21
+ import '../../Calendar-8rhyapMz.js';
22
+ import '../../useOnClickOutside-B5hujnpp.js';
22
23
  import '../../components/icon/icons/Calendar.js';
23
24
  import '../../components/icon/IconWrapper/IconWrapper.js';
24
25
  import '../../index-CNcEE5dn.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.stories.js","sources":["../../../../../src/lib/util/images/index.stories.tsx"],"sourcesContent":["import { ChangeEvent, useState } from 'react';\nimport { illustrations } from '../../util/images';\nimport classNames from 'classnames';\nimport { Button, Input } from '../..';\nimport styles from './style.module.scss';\n\nconst story = {\n title: 'Utils/Illustrations',\n parameters: {\n docs: {\n description: {\n component:\n 'Use the `illustrations` object export to access our list of available images.',\n },\n },\n },\n};\n\nconst initialImages = Object.entries(illustrations);\n\nexport const Illustrations = () => {\n const [value, setValue] = useState('');\n const [options, setOptions] = useState(initialImages);\n\n const clearSearch = () => {\n setValue('');\n setOptions(initialImages);\n };\n\n const handleOnSearch = (event: ChangeEvent<HTMLInputElement>) => {\n const searchValue = event.target.value;\n setValue(event.target.value);\n\n if (searchValue === '') {\n setOptions(initialImages);\n return;\n }\n\n setOptions(\n initialImages.filter(([key]) =>\n key.toLowerCase().includes(searchValue.toLowerCase())\n )\n );\n };\n\n return (\n <div>\n <div className={classNames(styles.searchBar, 'bg-white')}>\n <div className=\"d-flex gap8 wmx12 m-auto\">\n <Input\n className=\"w70\"\n onChange={handleOnSearch}\n placeholder=\"Search icon\"\n value={value}\n />\n <Button className=\"w30\" disabled={!value} onClick={clearSearch}>\n Clear search\n </Button>\n </div>\n </div>\n\n <div className=\"d-flex f-wrap mt80\">\n {options.map(([iconKey, src]) => (\n <div key={iconKey} className=\"w20 p8\">\n <div className=\"br4 p24 pt16 pb16 bg-neutral-50 w100 d-flex fd-column ai-center\">\n <div className={styles.imageWrapper}>\n <img src={src} alt={iconKey} />\n </div>\n <span className=\"p-p--small mt16\">{iconKey}</span>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport default story;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"index.stories.js","sources":["../../../../../src/lib/util/images/index.stories.tsx"],"sourcesContent":["import { ChangeEvent, useState } from 'react';\nimport { illustrations } from '../../util/images';\nimport classNames from 'classnames';\nimport { Button, Input } from '../..';\nimport styles from './style.module.scss';\n\nconst story = {\n title: 'Utils/Illustrations',\n parameters: {\n docs: {\n description: {\n component:\n 'Use the `illustrations` object export to access our list of available images.',\n },\n },\n },\n};\n\nconst initialImages = Object.entries(illustrations);\n\nexport const Illustrations = () => {\n const [value, setValue] = useState('');\n const [options, setOptions] = useState(initialImages);\n\n const clearSearch = () => {\n setValue('');\n setOptions(initialImages);\n };\n\n const handleOnSearch = (event: ChangeEvent<HTMLInputElement>) => {\n const searchValue = event.target.value;\n setValue(event.target.value);\n\n if (searchValue === '') {\n setOptions(initialImages);\n return;\n }\n\n setOptions(\n initialImages.filter(([key]) =>\n key.toLowerCase().includes(searchValue.toLowerCase())\n )\n );\n };\n\n return (\n <div>\n <div className={classNames(styles.searchBar, 'bg-white')}>\n <div className=\"d-flex gap8 wmx12 m-auto\">\n <Input\n className=\"w70\"\n onChange={handleOnSearch}\n placeholder=\"Search icon\"\n value={value}\n />\n <Button className=\"w30\" disabled={!value} onClick={clearSearch}>\n Clear search\n </Button>\n </div>\n </div>\n\n <div className=\"d-flex f-wrap mt80\">\n {options.map(([iconKey, src]) => (\n <div key={iconKey} className=\"w20 p8\">\n <div className=\"br4 p24 pt16 pb16 bg-neutral-50 w100 d-flex fd-column ai-center\">\n <div className={styles.imageWrapper}>\n <img src={src} alt={iconKey} />\n </div>\n <span className=\"p-p--small mt16\">{iconKey}</span>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport default story;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@popsure/dirty-swan",
3
- "version": "0.65.1",
3
+ "version": "0.66.1",
4
4
  "author": "Vincent Audoire <vincent@getpopsure.com>",
5
5
  "license": "MIT",
6
6
  "private": false,
package/src/index.tsx CHANGED
@@ -53,6 +53,7 @@ export {
53
53
  LogoInverted,
54
54
  LogoPositiveColor,
55
55
  LogoPositiveBlack,
56
+ SearchableDropdown,
56
57
  } from './lib';
57
58
 
58
59
  export * from './lib/components/icon';
@@ -73,6 +74,8 @@ export type {
73
74
  IconWrapperProps,
74
75
  TableData,
75
76
  TableProps,
77
+ SearchableDropdownProps,
78
+ SearchableDropdownOption,
76
79
  } from './lib';
77
80
 
78
81
  ReactDOM.render(<App />, document.getElementById('root'));
@@ -0,0 +1,286 @@
1
+ import { useState } from 'react';
2
+ import { SearchableDropdown, SearchableDropdownProps } from '.';
3
+
4
+ const story = {
5
+ title: 'JSX/SearchableDropdown',
6
+ component: SearchableDropdown,
7
+ argTypes: {
8
+ options: {
9
+ description: 'Array of options to display',
10
+ table: {
11
+ type: {
12
+ summary: '{ id: string; label: string; icon?: ReactNode }[]',
13
+ },
14
+ },
15
+ },
16
+ value: {
17
+ description: 'The currently selected option id',
18
+ },
19
+ onChange: {
20
+ action: true,
21
+ table: {
22
+ category: 'Callbacks',
23
+ },
24
+ },
25
+ searchable: {
26
+ description: 'Whether the dropdown includes a search input',
27
+ control: 'boolean',
28
+ },
29
+ placeholder: {
30
+ description: 'Placeholder text for the search input',
31
+ control: 'text',
32
+ },
33
+ triggerPlaceholder: {
34
+ description: 'Placeholder text shown on the trigger when no value is selected',
35
+ control: 'text',
36
+ },
37
+ noResultsText: {
38
+ description: 'Text shown when no options match the search',
39
+ control: 'text',
40
+ },
41
+ groupName: {
42
+ description: 'Name attribute for the radio group',
43
+ control: 'text',
44
+ },
45
+ dropUp: {
46
+ description: 'Whether the dropdown opens upward',
47
+ control: 'boolean',
48
+ },
49
+ condensed: {
50
+ description: 'Whether to use a compact trigger (icon only)',
51
+ control: 'boolean',
52
+ },
53
+ bordered: {
54
+ description: 'Whether to show a border on the trigger',
55
+ control: 'boolean',
56
+ },
57
+ showChevron: {
58
+ description: 'Whether to show a chevron icon on the trigger',
59
+ control: 'boolean',
60
+ },
61
+ },
62
+ args: {
63
+ options: [
64
+ { id: 'de', label: 'Germany' },
65
+ { id: 'fr', label: 'France' },
66
+ { id: 'es', label: 'Spain' },
67
+ { id: 'it', label: 'Italy' },
68
+ { id: 'pt', label: 'Portugal' },
69
+ ],
70
+ value: 'de',
71
+ searchable: false,
72
+ placeholder: 'Search',
73
+ triggerPlaceholder: 'Select a country',
74
+ noResultsText: 'No results found',
75
+ groupName: 'country',
76
+ dropUp: false,
77
+ condensed: false,
78
+ bordered: false,
79
+ showChevron: false,
80
+ },
81
+ parameters: {
82
+ componentSubtitle:
83
+ 'A dropdown component that supports searchable options with keyboard navigation.',
84
+ },
85
+ };
86
+
87
+ export const Default = {
88
+ render: (args: SearchableDropdownProps) => {
89
+ const [selected, setSelected] = useState(args.value);
90
+
91
+ return (
92
+ <div style={{ width: 300 }}>
93
+ <SearchableDropdown
94
+ {...args}
95
+ value={selected}
96
+ onChange={(val) => {
97
+ args.onChange(val);
98
+ setSelected(val);
99
+ }}
100
+ />
101
+ </div>
102
+ );
103
+ },
104
+
105
+ name: 'Default',
106
+ };
107
+
108
+ export const Searchable = {
109
+ render: (args: SearchableDropdownProps) => {
110
+ const [selected, setSelected] = useState(args.value);
111
+
112
+ const options = [
113
+ { id: 'de', label: 'Germany' },
114
+ { id: 'fr', label: 'France' },
115
+ { id: 'es', label: 'Spain' },
116
+ { id: 'it', label: 'Italy' },
117
+ { id: 'pt', label: 'Portugal' },
118
+ { id: 'nl', label: 'Netherlands' },
119
+ { id: 'be', label: 'Belgium' },
120
+ { id: 'at', label: 'Austria' },
121
+ { id: 'ch', label: 'Switzerland' },
122
+ { id: 'pl', label: 'Poland' },
123
+ ];
124
+
125
+ return (
126
+ <div style={{ width: 300 }}>
127
+ <SearchableDropdown
128
+ {...args}
129
+ options={options}
130
+ searchable
131
+ value={selected}
132
+ onChange={(val) => {
133
+ args.onChange(val);
134
+ setSelected(val);
135
+ }}
136
+ />
137
+ </div>
138
+ );
139
+ },
140
+
141
+ name: 'Searchable',
142
+ };
143
+
144
+ export const WithIcons = {
145
+ render: (args: SearchableDropdownProps) => {
146
+ const [selected, setSelected] = useState('de');
147
+
148
+ const options = [
149
+ { id: 'de', label: 'Germany', icon: <span>🇩🇪</span> },
150
+ { id: 'fr', label: 'France', icon: <span>🇫🇷</span> },
151
+ { id: 'es', label: 'Spain', icon: <span>🇪🇸</span> },
152
+ { id: 'it', label: 'Italy', icon: <span>🇮🇹</span> },
153
+ { id: 'pt', label: 'Portugal', icon: <span>🇵🇹</span> },
154
+ ];
155
+
156
+ return (
157
+ <div style={{ width: 300 }}>
158
+ <SearchableDropdown
159
+ {...args}
160
+ options={options}
161
+ value={selected}
162
+ onChange={(val) => {
163
+ args.onChange(val);
164
+ setSelected(val);
165
+ }}
166
+ />
167
+ </div>
168
+ );
169
+ },
170
+
171
+ name: 'With Icons',
172
+ };
173
+
174
+ export const Condensed = {
175
+ render: (args: SearchableDropdownProps) => {
176
+ const [selected, setSelected] = useState('de');
177
+
178
+ const options = [
179
+ { id: 'de', label: 'Germany', icon: <span>🇩🇪</span> },
180
+ { id: 'fr', label: 'France', icon: <span>🇫🇷</span> },
181
+ { id: 'es', label: 'Spain', icon: <span>🇪🇸</span> },
182
+ ];
183
+
184
+ return (
185
+ <SearchableDropdown
186
+ {...args}
187
+ options={options}
188
+ condensed
189
+ bordered
190
+ value={selected}
191
+ onChange={(val) => {
192
+ args.onChange(val);
193
+ setSelected(val);
194
+ }}
195
+ />
196
+ );
197
+ },
198
+
199
+ name: 'Condensed',
200
+ };
201
+
202
+ export const WithChevron = {
203
+ render: (args: SearchableDropdownProps) => {
204
+ const [selected, setSelected] = useState('de');
205
+
206
+ const options = [
207
+ { id: 'de', label: 'Germany' },
208
+ { id: 'fr', label: 'France' },
209
+ { id: 'es', label: 'Spain' },
210
+ ];
211
+
212
+ return (
213
+ <div style={{ width: 300 }}>
214
+ <SearchableDropdown
215
+ {...args}
216
+ options={options}
217
+ showChevron
218
+ bordered
219
+ value={selected}
220
+ onChange={(val) => {
221
+ args.onChange(val);
222
+ setSelected(val);
223
+ }}
224
+ />
225
+ </div>
226
+ );
227
+ },
228
+
229
+ name: 'With Chevron',
230
+ };
231
+
232
+ export const Disabled = {
233
+ render: (args: SearchableDropdownProps) => {
234
+ return (
235
+ <div style={{ width: 300 }}>
236
+ <SearchableDropdown
237
+ {...args}
238
+ options={[
239
+ { id: 'de', label: 'Germany' },
240
+ { id: 'fr', label: 'France' },
241
+ { id: 'es', label: 'Spain' },
242
+ ]}
243
+ disabled
244
+ bordered
245
+ showChevron
246
+ value="de"
247
+ onChange={args.onChange}
248
+ />
249
+ </div>
250
+ );
251
+ },
252
+
253
+ name: 'Disabled',
254
+ };
255
+
256
+ export const DropUp = {
257
+ render: (args: SearchableDropdownProps) => {
258
+ const [selected, setSelected] = useState('de');
259
+
260
+ const options = [
261
+ { id: 'de', label: 'Germany' },
262
+ { id: 'fr', label: 'France' },
263
+ { id: 'es', label: 'Spain' },
264
+ ];
265
+
266
+ return (
267
+ <div style={{ width: 300, marginTop: 300 }}>
268
+ <SearchableDropdown
269
+ {...args}
270
+ options={options}
271
+ dropUp
272
+ searchable
273
+ value={selected}
274
+ onChange={(val) => {
275
+ args.onChange(val);
276
+ setSelected(val);
277
+ }}
278
+ />
279
+ </div>
280
+ );
281
+ },
282
+
283
+ name: 'Drop Up',
284
+ };
285
+
286
+ export default story;