@colisweb/rescript-toolkit 2.71.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/.yarn/cache/@colisweb-restorative-npm-1.0.0-5eac899f0c-6e80ecc641.zip +0 -0
  2. package/.yarn/cache/@rescript-react-npm-0.11.0-687f8fa3b5-c399d114f7.zip +0 -0
  3. package/.yarn/cache/{rescript-npm-10.0.1-c064c63c72-59ae153c7f.zip → rescript-npm-10.1.2-eb312a329e-e70ae09da1.zip} +0 -0
  4. package/.yarn/install-state.gz +0 -0
  5. package/bsconfig.json +2 -2
  6. package/locale/fr.json +5 -0
  7. package/package.json +4 -5
  8. package/playground/PlaygroundApp.res +12 -0
  9. package/playground/PlaygroundBindings.res +106 -0
  10. package/playground/PlaygroundHooks.res +4 -4
  11. package/playground/PlaygroundRouter.res +18 -0
  12. package/playground/bindings/Playground_Bindings_Reach.res +143 -0
  13. package/playground/components/Playground_Form.res +56 -3
  14. package/playground/components/Playground_Modal.res +20 -5
  15. package/playground/components/Playground_Select.res +14 -4
  16. package/playground/hooks/{Playground_Clipboard.res → Playground_Hooks_Clipboard.res} +1 -1
  17. package/playground/hooks/{Playground_Disclosure.res → Playground_Hooks_Disclosure.res} +1 -1
  18. package/playground/hooks/{Playground_LazyLoad.res → Playground_Hooks_LazyLoad.res} +1 -1
  19. package/playground/hooks/{Playground_MediaQueries.res → Playground_Hooks_MediaQueries.res} +1 -1
  20. package/src/decoders/Toolkit__Decoders.res +1 -1
  21. package/src/form/Reform.res +8 -36
  22. package/src/form/Toolkit__Form.res +114 -55
  23. package/src/form/Toolkit__FormValidationFunctions.res +13 -0
  24. package/src/hooks/Toolkit__Hooks.res +1 -1
  25. package/src/intl/Toolkit__Intl.res +1 -1
  26. package/src/intl/Toolkit__Intl.resi +1 -1
  27. package/src/logger/Toolkit__NativeLogger.res +1 -1
  28. package/src/router/Toolkit__Router.res +0 -6
  29. package/src/ui/Toolkit__Ui.res +0 -2
  30. package/src/ui/Toolkit__Ui_Dropdown.res +13 -7
  31. package/src/ui/Toolkit__Ui_Dropdown.resi +2 -0
  32. package/src/ui/Toolkit__Ui_Layout.res +1 -6
  33. package/src/ui/Toolkit__Ui_MultiSelect.res +10 -4
  34. package/src/ui/Toolkit__Ui_MultiSelect.resi +5 -1
  35. package/src/ui/Toolkit__Ui_NativeDatePicker.res +2 -2
  36. package/src/ui/Toolkit__Ui_Select.res +22 -5
  37. package/src/ui/Toolkit__Ui_Select.resi +13 -2
  38. package/src/ui/Toolkit__Ui_SelectPolyvariant.res +45 -0
  39. package/src/ui/Toolkit__Ui_Table.res +11 -6
  40. package/src/ui/Toolkit__Ui_TextInput.res +2 -2
  41. package/src/ui/Toolkit__Ui_WeekDateFilter.res +16 -16
  42. package/src/utils/Toolkit__Utils_UnitMeasure.res +4 -4
  43. package/src/vendors/{BsCopyToClipboard.res → CopyToClipboard.res} +0 -0
  44. package/src/vendors/{BsDateFns.res → DateFns.res} +0 -0
  45. package/src/vendors/{BsJsCookie.res → JsCookie.res} +0 -0
  46. package/src/vendors/{BsReactDayPicker.res → ReactDayPicker.res} +0 -1
  47. package/src/vendors/{BsReactGoogleMaps.res → ReactGoogleMaps.res} +0 -0
  48. package/src/vendors/ReactIcons.res +5 -0
  49. package/src/vendors/{BsReactSelect.res → ReactSelect.res} +58 -58
  50. package/src/vendors/{BsSentryReactNative.res → SentryReactNative.res} +0 -0
  51. package/src/vendors/reach-ui/ReachUi_Accordion.res +12 -14
  52. package/src/vendors/reach-ui/ReachUi_AlertDialog.res +8 -34
  53. package/src/vendors/reach-ui/ReachUi_Dialog.res +7 -10
  54. package/src/vendors/reach-ui/ReachUi_Listbox.res +8 -9
  55. package/src/vendors/reach-ui/ReachUi_MenuButton.res +7 -30
  56. package/src/vendors/reach-ui/ReachUi_Popover.res +0 -6
  57. package/src/vendors/reach-ui/ReachUi_Tabs.res +18 -27
  58. package/.yarn/cache/@colisweb-restorative-npm-0.5.1-2ffe068813-cd8332a7eb.zip +0 -0
  59. package/.yarn/cache/@rescript-react-npm-0.10.3-26bd5d697f-8561282f78.zip +0 -0
  60. package/.yarn/cache/compute-scroll-into-view-npm-1.0.16-a8a68c1929-4334db6397.zip +0 -0
  61. package/.yarn/cache/downshift-npm-5.2.5-14bb33ffd8-498b4764a8.zip +0 -0
  62. package/src/mock/MockOverlay.resi +0 -4
  63. package/src/ui/Toolkit__Ui_Listbox.res +0 -123
  64. package/src/ui/Toolkit__Ui_ListboxInput.res +0 -673
  65. package/src/vendors/BsAnalytics.res +0 -34
  66. package/src/vendors/BsDownshift.res +0 -596
@@ -1,673 +0,0 @@
1
- open BsDownshift
2
- module Listbox = Toolkit__Ui_Listbox
3
-
4
- module ButtonInput = {
5
- module Button = Toolkit__Ui_Button
6
- type size = Button.size
7
-
8
- @react.component
9
- let make = (
10
- ~size=#md,
11
- ~ariaLabel: option<string>=?,
12
- ~ariaLabelledby: option<string>=?,
13
- ~ariaExpanded: option<bool>=?,
14
- ~id: option<string>=?,
15
- ~type_="button",
16
- ~onClick: option<ReactEvent.Mouse.t => unit>=?,
17
- ~disabled=false,
18
- ~isInvalid: option<bool>=?,
19
- ~autoFocus: option<bool>=?,
20
- ~value=?,
21
- ~className="",
22
- ~children=React.null,
23
- ~buttonRef=?,
24
- ) =>
25
- <Button
26
- ?buttonRef
27
- size
28
- color=#white
29
- variant=#default
30
- type_
31
- ?ariaLabel
32
- ?ariaLabelledby
33
- ?ariaExpanded
34
- ?id
35
- ?onClick
36
- disabled
37
- ?autoFocus
38
- className={cx([
39
- className,
40
- "w-full flex justify-between",
41
- isInvalid->Option.getWithDefault(false) ? "border-danger-500 shadow-danger-500" : "",
42
- ])}>
43
- {value->Option.mapWithDefault(React.null, value =>
44
- <span className="font-normal truncate"> {value->React.string} </span>
45
- )}
46
- children
47
- </Button>
48
- }
49
-
50
- module Item = {
51
- type value
52
-
53
- external fromValue: value => 'any = "%identity"
54
-
55
- external toValue: 'any => value = "%identity"
56
-
57
- type item =
58
- | Placeholder
59
- | Item(string, value)
60
-
61
- let item = (key, value) => Item(key, value->toValue)
62
-
63
- let mapItem = (item, fn) =>
64
- switch item {
65
- | Placeholder => None
66
- | Item(key, value) => Some(fn((key, value->fromValue)))
67
- }
68
-
69
- let value = item =>
70
- switch item {
71
- | Placeholder => None
72
- | Item(_, value) => Some(value->fromValue)
73
- }
74
- }
75
-
76
- include Item
77
-
78
- type selection = {
79
- selection: option<item>,
80
- selectItem: item => unit,
81
- isSelected: item => bool,
82
- }
83
-
84
- let isEqualItems = (itemA, itemB) =>
85
- switch (itemA, itemB) {
86
- | (Placeholder, Placeholder) => true
87
- | (Item(keyA, _), Item(keyB, _)) if keyA === keyB => true
88
- | _ => false
89
- }
90
-
91
- let getSelectionByValue = (items, value) => items->Array.getBy(isEqualItems(value))->Option.getExn
92
-
93
- let useSelection = (
94
- ~value: option<item>=?,
95
- ~defaultValue: option<item>=?,
96
- ~onChange: option<option<item> => unit>=?,
97
- ~items: array<item>,
98
- ): selection => {
99
- let isControlled = value->Option.isSome
100
-
101
- let (selection, setSelection) = React.useState(_ =>
102
- defaultValue->Option.map(getSelectionByValue(items))
103
- )
104
-
105
- let selection = !isControlled ? selection : value->Option.map(getSelectionByValue(items))
106
-
107
- let setSelection = !isControlled ? setSelection : fn => fn(None)->ignore
108
-
109
- let selectItem = React.useCallback1(selectedItem => {
110
- let newSelection = switch (selection, selectedItem) {
111
- | (Some(selection), selectedItem) if isEqualItems(selection, selectedItem) => None
112
- | (_, selectedItem) =>
113
- switch selectedItem {
114
- | Placeholder => None
115
- | selectedItem => Some(selectedItem)
116
- }
117
- }
118
-
119
- onChange->Option.map(onChange => onChange(newSelection))->ignore
120
-
121
- setSelection(_ => newSelection)
122
- }, [selection])
123
-
124
- let isSelected = React.useCallback1(
125
- item => selection->Option.mapWithDefault(false, isEqualItems(item)),
126
- [selection],
127
- )
128
-
129
- {selection: selection, selectItem: selectItem, isSelected: isSelected}
130
- }
131
-
132
- type multipleSelection = {
133
- selection: array<item>,
134
- selectItem: item => unit,
135
- isSelected: item => bool,
136
- }
137
-
138
- let getMultipleSelectionByValue = (items, values) =>
139
- values->Array.map(value => items->Array.getBy(isEqualItems(value))->Option.getExn)
140
-
141
- let useMultipleSelection = (
142
- ~value: option<array<item>>=?,
143
- ~defaultValue: option<array<item>>=?,
144
- ~onChange: option<array<item> => unit>=?,
145
- ~items: array<item>,
146
- ): multipleSelection => {
147
- let isControlled = value->Option.isSome
148
-
149
- let (selection, setSelection) = React.useState(_ =>
150
- defaultValue->Option.mapWithDefault([], getMultipleSelectionByValue(items))
151
- )
152
-
153
- let selection = !isControlled
154
- ? selection
155
- : value->Option.mapWithDefault([], getMultipleSelectionByValue(items))
156
-
157
- let setSelection = !isControlled ? setSelection : fn => fn([])->ignore
158
-
159
- let selectItem = React.useCallback1(selectedItem => {
160
- let newSelection = switch selection->Array.getIndexBy(selection =>
161
- isEqualItems(selection, selectedItem)
162
- ) {
163
- | Some(_) => Js.Array.filter(item => !isEqualItems(item, selectedItem), selection)
164
- | None =>
165
- switch selectedItem {
166
- | Placeholder => []
167
- | selectedItem => Js.Array.concat([selectedItem], selection)
168
- }
169
- }
170
-
171
- onChange->Option.map(fn => fn(newSelection))->ignore
172
-
173
- setSelection(_ => newSelection)
174
- }, [selection])
175
-
176
- let isSelected = React.useCallback1(
177
- item => selection->Array.getBy(selection => isEqualItems(selection, item))->Option.isSome,
178
- [selection],
179
- )
180
-
181
- {selection: selection, selectItem: selectItem, isSelected: isSelected}
182
- }
183
-
184
- type listboxInputContext = {
185
- api: BsDownshift.Select.t<item>,
186
- isSelected: item => bool,
187
- }
188
-
189
- let listboxInputContext: React.Context.t<option<listboxInputContext>> = React.createContext(None)
190
-
191
- let useListboxInputContext = () => React.useContext(listboxInputContext)->Option.getExn
192
-
193
- module ListboxInputProvider = {
194
- let makeProps = (~value, ~children, ()) =>
195
- {
196
- "value": Some(value),
197
- "children": children,
198
- }
199
- let make = React.Context.provider(listboxInputContext)
200
- }
201
-
202
- module ListboxInputPopover = {
203
- @react.component
204
- let make = React.forwardRef((~className="", ~children: React.element, ref_) => {
205
- let {api} = useListboxInputContext()
206
-
207
- <Listbox.Popover
208
- ref=?{ref_->Js.Nullable.toOption->Option.map(ReactDOM.Ref.domRef)}
209
- isOpen=api.isOpen
210
- className>
211
- children
212
- </Listbox.Popover>
213
- })
214
- }
215
-
216
- module ListboxInputList = {
217
- @react.component
218
- let make = React.forwardRef((
219
- ~className="",
220
- ~onBlur: option<ReactEvent.Focus.t => unit>=?,
221
- ~children: React.element,
222
- ref_,
223
- ) => {
224
- let {api} = useListboxInputContext()
225
-
226
- let menuProps = api.getMenuProps(
227
- Select.menuPropsOptions(
228
- ~onBlur?,
229
- ~ref=ref_->Js.Nullable.toOption->Option.map(ReactDOM.Ref.domRef),
230
- (),
231
- ),
232
- )
233
-
234
- <Listbox.List
235
- ref={ReactDOM.Ref.callbackDomRef(menuProps.ref)}
236
- isOpen=api.isOpen
237
- ariaLabelledby=menuProps.ariaLabelledby
238
- ariaActivedescendant=menuProps.ariaActivedescendant
239
- role=menuProps.role
240
- id=menuProps.id
241
- onMouseLeave=menuProps.onMouseLeave
242
- onKeyDown=menuProps.onKeyDown
243
- onBlur=menuProps.onBlur
244
- tabIndex=menuProps.tabIndex
245
- className={cx([className, "max-w-sm"])}>
246
- {api.isOpen ? children : React.null}
247
- </Listbox.List>
248
- })
249
- }
250
-
251
- module ListboxInputButton = {
252
- @react.component
253
- let make = (
254
- ~size: option<ButtonInput.size>=?,
255
- ~id: option<string>=?,
256
- ~onClick: option<ReactEvent.Mouse.t => unit>=?,
257
- ~disabled: option<bool>=?,
258
- ~autoFocus: option<bool>=?,
259
- ~isInvalid: option<bool>=?,
260
- ~className="",
261
- ~children: React.element,
262
- ~buttonRef=Js.Nullable.null,
263
- ) => {
264
- let {api} = useListboxInputContext()
265
-
266
- let toggleButtonProps = api.getToggleButtonProps(
267
- Select.toggleButtonPropsOptions(
268
- ~id?,
269
- ~onClick?,
270
- ~disabled?,
271
- ~ref=buttonRef->Js.Nullable.toOption->Option.map(ReactDOM.Ref.domRef),
272
- (),
273
- ),
274
- )
275
-
276
- <ButtonInput
277
- buttonRef={Obj.magic(ReactDOM.Ref.callbackDomRef(toggleButtonProps.ref))}
278
- disabled=toggleButtonProps.disabled
279
- ?isInvalid
280
- ?autoFocus
281
- ?size
282
- ariaLabel="toggle menu"
283
- ariaLabelledby=toggleButtonProps.ariaLabelledby
284
- ariaExpanded=toggleButtonProps.ariaExpanded
285
- id=toggleButtonProps.id
286
- onClick=toggleButtonProps.onClick
287
- className>
288
- children
289
- </ButtonInput>
290
- }
291
- }
292
-
293
- module ListboxInputOption = {
294
- @react.component
295
- let make = React.forwardRef((
296
- ~item: item,
297
- ~index: int,
298
- ~onClick: option<ReactEvent.Mouse.t => unit>=?,
299
- ~disabled: option<bool>=?,
300
- ~className="",
301
- ~children: React.element,
302
- ref_,
303
- ) => {
304
- let {api, isSelected} = useListboxInputContext()
305
-
306
- let itemProps = api.getItemProps(
307
- Select.itemPropsOptions(~item, ~index, ~disabled?, ~onClick?, ()),
308
- )
309
-
310
- <Listbox.Option
311
- ref=?{ref_->Js.Nullable.toOption->Option.map(ReactDOM.Ref.domRef)}
312
- isHighlighted={api.highlightedIndex === index}
313
- id=itemProps.id
314
- disabled=itemProps.disabled
315
- ariaSelected={itemProps.ariaSelected === "true"}
316
- role=itemProps.role
317
- onMouseMove=itemProps.onMouseMove
318
- onClick=itemProps.onClick
319
- className={cx([className, "pr-8", item === Placeholder ? "italic" : ""])}>
320
- {isSelected(item)
321
- ? <ReactIcons.MdCheck className="mr-4 w-6 h-6 flex-none" />
322
- : <span className="mr-4 w-6 h-6 flex-none" />}
323
- <span className="truncate"> children </span>
324
- </Listbox.Option>
325
- })
326
- }
327
-
328
- module ListboxInputGroupLabel = Toolkit__Ui_Listbox.ListboxGroupLabel
329
-
330
- module ListboxInputLabel = Toolkit__Ui_Listbox.ListboxLabel
331
-
332
- module ListboxInputDivider = Toolkit__Ui_Listbox.ListboxDivider
333
-
334
- module ListboxInputSelectProvider = {
335
- @react.component
336
- let make = (
337
- ~id: option<string>=?,
338
- ~name: option<string>=?,
339
- ~value: option<item>=?,
340
- ~defaultValue: option<item>=?,
341
- ~items: array<item>,
342
- ~itemToString: item => string,
343
- ~onChange: option<option<item> => unit>=?,
344
- ~required: option<bool>=?,
345
- ~children: (option<item>, array<item>) => React.element,
346
- ) => {
347
- let {selection, selectItem, isSelected}: selection = useSelection(
348
- ~items,
349
- ~value?,
350
- ~defaultValue?,
351
- ~onChange?,
352
- )
353
-
354
- let stateReducer = (
355
- _state: Select.state<item>,
356
- {action, changes}: Select.actionAndChanges<item>,
357
- ) =>
358
- switch action->Select.action {
359
- | MenuKeyDownEnter
360
- | MenuKeyDownSpaceButton
361
- | ItemClick
362
- | FunctionSelectItem =>
363
- let selectedItem = changes.selectedItem->Js.Nullable.toOption->Option.getExn
364
- selectItem(selectedItem)
365
- changes
366
-
367
- | _ => changes
368
- }
369
-
370
- let api = {
371
- open Select
372
- useSelect(
373
- selectOptions(
374
- ~items,
375
- ~stateReducer,
376
- ~itemToString=item => item->Js.Nullable.toOption->Option.mapWithDefault("", itemToString),
377
- ~selectedItem=selection->Js.Nullable.fromOption,
378
- (),
379
- ),
380
- )
381
- }
382
-
383
- <ListboxInputProvider value={api: api, isSelected: isSelected}>
384
- <div className="relative">
385
- <input
386
- type_="hidden"
387
- ?name
388
- ?id
389
- ?required
390
- readOnly=true
391
- value={selection->Option.mapWithDefault("", itemToString)}
392
- />
393
- {children(selection, items)}
394
- </div>
395
- </ListboxInputProvider>
396
- }
397
- }
398
-
399
- module ListboxInputSelect = {
400
- @react.component
401
- let make = (
402
- ~id: option<string>=?,
403
- ~name: option<string>=?,
404
- ~placeholder="Select",
405
- ~value: option<'value>=?,
406
- ~defaultValue: option<'value>=?,
407
- ~items: array<'value>,
408
- ~itemToLabel: option<'value => string>=?,
409
- ~itemToId: option<'value => string>=?,
410
- ~onChange: option<option<'value> => unit>=?,
411
- ~onBlur: option<ReactEvent.Focus.t => unit>=?,
412
- ~required: option<bool>=?,
413
- ~disabled=false,
414
- ~isInvalid: option<bool>=?,
415
- ~autoFocus: option<bool>=?,
416
- ~size=#md,
417
- ~hasPlaceholderOption=false,
418
- ~className="",
419
- ) => {
420
- let itemToId = value =>
421
- itemToId->Option.mapWithDefault(value->Obj.magic, itemToId => value->itemToId)
422
-
423
- let itemToString = item =>
424
- item
425
- ->Item.mapItem(((_, value)) =>
426
- itemToLabel->Option.mapWithDefault(value->Obj.magic, itemToLabel => value->itemToLabel)
427
- )
428
- ->Option.getWithDefault("")
429
-
430
- let items =
431
- items
432
- ->Array.map(value => Item.item(value->itemToId, value->Item.toValue))
433
- ->Array.concat(hasPlaceholderOption ? [Placeholder] : [], _)
434
-
435
- let value =
436
- value->Option.flatMap(value =>
437
- items->Array.getBy(item =>
438
- item->Item.mapItem(((key, _)) => key === value->itemToId)->Option.getWithDefault(false)
439
- )
440
- )
441
-
442
- let defaultValue =
443
- defaultValue->Option.flatMap(value =>
444
- items->Array.getBy(item =>
445
- item->Item.mapItem(((key, _)) => key === value->itemToId)->Option.getWithDefault(false)
446
- )
447
- )
448
-
449
- let onChange =
450
- onChange->Option.map((onChange, value) =>
451
- onChange(value->Option.flatMap(Item.mapItem(_, ((_, value)) => value)))
452
- )
453
-
454
- <ListboxInputSelectProvider ?onChange ?name ?value ?defaultValue ?required itemToString items>
455
- {(selection, items) => <>
456
- <ListboxInputButton
457
- ?autoFocus
458
- disabled
459
- ?isInvalid
460
- ?id
461
- size
462
- className={cx([className, "w-full flex justify-between"])}>
463
- <span className="truncate font-normal">
464
- {value
465
- ->Option.mapWithDefault(selection, value => Some(getSelectionByValue(items, value)))
466
- ->Option.mapWithDefault(placeholder, item => item->itemToString)
467
- ->React.string}
468
- </span>
469
- <ReactIcons.MdArrowDropDown className="ml-2 w-6 h-6 -my-1 flex-none" />
470
- </ListboxInputButton>
471
- <ListboxInputPopover className="-mt-12">
472
- <ListboxInputList ?onBlur>
473
- {items
474
- ->Array.mapWithIndex((index, item) =>
475
- switch item {
476
- | Placeholder =>
477
- <ListboxInputOption key="placeholder" item index>
478
- {placeholder->React.string}
479
- </ListboxInputOption>
480
- | Item(key, _) =>
481
- <ListboxInputOption key item index>
482
- {item->itemToString->React.string}
483
- </ListboxInputOption>
484
- }
485
- )
486
- ->React.array}
487
- </ListboxInputList>
488
- </ListboxInputPopover>
489
- </>}
490
- </ListboxInputSelectProvider>
491
- }
492
- }
493
-
494
- module ListboxInputMultiSelectProvider = {
495
- @react.component
496
- let make = (
497
- ~id: option<string>=?,
498
- ~name: option<string>=?,
499
- ~value: option<array<item>>=?,
500
- ~defaultValue: option<array<item>>=?,
501
- ~itemToString: item => string,
502
- ~items: array<item>,
503
- ~onChange: option<array<item> => unit>=?,
504
- ~required: option<bool>=?,
505
- ~children: (array<item>, array<item>) => React.element,
506
- ) => {
507
- let {selection, selectItem, isSelected}: multipleSelection = useMultipleSelection(
508
- ~items,
509
- ~value?,
510
- ~defaultValue?,
511
- ~onChange?,
512
- )
513
-
514
- let stateReducer = (
515
- state: Select.state<item>,
516
- {action, changes}: Select.actionAndChanges<item>,
517
- ) =>
518
- switch action->Select.action {
519
- | MenuKeyDownEnter
520
- | MenuKeyDownSpaceButton
521
- | ItemClick
522
- | FunctionSelectItem =>
523
- let selectedItem = changes.selectedItem->Js.Nullable.toOption->Option.getExn
524
- selectItem(selectedItem)
525
- {
526
- ...changes,
527
- isOpen: switch selectedItem {
528
- | Placeholder => false
529
- | Item(_) => true
530
- },
531
- highlightedIndex: state.highlightedIndex,
532
- }
533
-
534
- | _ => changes
535
- }
536
-
537
- let api = {
538
- open Select
539
- useSelect(
540
- selectOptions(
541
- ~items,
542
- ~stateReducer,
543
- ~itemToString=item => item->Js.Nullable.toOption->Option.mapWithDefault("", itemToString),
544
- ~selectedItem=selection->Array.get(0)->Js.Nullable.fromOption,
545
- (),
546
- ),
547
- )
548
- }
549
-
550
- <ListboxInputProvider value={api: api, isSelected: isSelected}>
551
- <div className="relative">
552
- <input type_="hidden" ?name ?id ?required readOnly=true value={selection->Obj.magic} />
553
- {children(selection, items)}
554
- </div>
555
- </ListboxInputProvider>
556
- }
557
- }
558
-
559
- module ListboxInputMultiSelect = {
560
- @react.component
561
- let make = (
562
- ~id: option<string>=?,
563
- ~name: option<string>=?,
564
- ~placeholder="Select",
565
- ~value: option<array<'value>>=?,
566
- ~defaultValue: option<array<'value>>=?,
567
- ~items: array<'value>,
568
- ~itemToLabel: option<'value => string>=?,
569
- ~itemToId: option<'value => string>=?,
570
- ~onChange: option<array<'value> => unit>=?,
571
- ~onBlur: option<ReactEvent.Focus.t => unit>=?,
572
- ~required: option<bool>=?,
573
- ~disabled=false,
574
- ~isInvalid: option<bool>=?,
575
- ~autoFocus: option<bool>=?,
576
- ~size=#md,
577
- ~hasPlaceholderOption=false,
578
- ~className="",
579
- ) => {
580
- let itemToId = value =>
581
- itemToId->Option.mapWithDefault(value->Obj.magic, itemToId => value->itemToId)
582
-
583
- let itemToString = item =>
584
- item
585
- ->Item.mapItem(((_, value)) =>
586
- itemToLabel->Option.mapWithDefault(value->Obj.magic, itemToLabel => value->itemToLabel)
587
- )
588
- ->Option.getWithDefault("")
589
-
590
- let items =
591
- items
592
- ->Array.map(value => Item.item(value->itemToId, value->Item.toValue))
593
- ->Array.concat(hasPlaceholderOption ? [Placeholder] : [], _)
594
-
595
- let value =
596
- value->Option.map(value =>
597
- value->Array.keepMap(value =>
598
- items->Array.getBy(item =>
599
- item->Item.mapItem(((key, _)) => key === value->itemToId)->Option.getWithDefault(false)
600
- )
601
- )
602
- )
603
-
604
- let defaultValue =
605
- defaultValue->Option.map(value =>
606
- value->Array.keepMap(value =>
607
- items->Array.getBy(item =>
608
- item->Item.mapItem(((key, _)) => key === value->itemToId)->Option.getWithDefault(false)
609
- )
610
- )
611
- )
612
-
613
- let onChange =
614
- onChange->Option.map((onChange, value) =>
615
- onChange(value->Array.keepMap(Item.mapItem(_, ((_, value)) => value)))
616
- )
617
-
618
- <ListboxInputMultiSelectProvider
619
- ?onChange ?name ?value ?defaultValue ?required items itemToString>
620
- {(selection, items) => <>
621
- <ListboxInputButton
622
- ?autoFocus
623
- disabled
624
- ?isInvalid
625
- ?id
626
- size
627
- className={cx([className, "w-full flex justify-between"])}>
628
- <span className="truncate font-normal">
629
- {switch value->Option.mapWithDefault(selection, value =>
630
- getMultipleSelectionByValue(items, value)
631
- ) {
632
- | [] => placeholder
633
- | items => items->Array.map(itemToString)->Js.Array.joinWith(", ", _)
634
- }->React.string}
635
- </span>
636
- <ReactIcons.MdArrowDropDown className="ml-2 w-6 h-6 -my-1 flex-none" />
637
- </ListboxInputButton>
638
- <ListboxInputPopover className="-mt-12">
639
- <ListboxInputList ?onBlur>
640
- <input />
641
- {items
642
- ->Array.mapWithIndex((index, item) =>
643
- switch item {
644
- | Placeholder =>
645
- <ListboxInputOption key="placeholder" item index>
646
- {placeholder->React.string}
647
- </ListboxInputOption>
648
- | Item(key, _) =>
649
- <ListboxInputOption key item index>
650
- {item->itemToString->React.string}
651
- </ListboxInputOption>
652
- }
653
- )
654
- ->React.array}
655
- </ListboxInputList>
656
- </ListboxInputPopover>
657
- </>}
658
- </ListboxInputMultiSelectProvider>
659
- }
660
- }
661
-
662
- module Popover = ListboxInputPopover
663
- module Provider = ListboxInputProvider
664
- module List = ListboxInputList
665
- module Button = ListboxInputButton
666
- module Option = ListboxInputOption
667
- module Label = ListboxInputLabel
668
- module GroupLabel = ListboxInputGroupLabel
669
- module Divider = ListboxInputDivider
670
- module SelectProvider = ListboxInputSelectProvider
671
- module Select = ListboxInputSelect
672
- module MultiSelectProvider = ListboxInputMultiSelectProvider
673
- module MultiSelect = ListboxInputMultiSelect
@@ -1,34 +0,0 @@
1
- @ocaml.doc("
2
- * Bindings of https://www.npmjs.com/package/analytics
3
- ")
4
- type plugin
5
-
6
- type options = {
7
- app: string,
8
- version: int,
9
- plugins: array<plugin>,
10
- }
11
-
12
- type instance
13
- type gaOptions = {
14
- trackingId: string,
15
- anonymizeIp: bool,
16
- customDimensions: Js.Dict.t<string>,
17
- setCustomDimensionsToPage: bool,
18
- }
19
-
20
- @module("analytics") external init: options => instance = "default"
21
-
22
- @bs.send
23
- external identify: (instance, string, Js.Dict.t<string>) => unit = "identify"
24
- @bs.send
25
- external page: (instance, ~dimensions: Js.Dict.t<string>=?, unit) => unit = "page"
26
-
27
- @bs.send
28
- external track: (instance, string, ~payload: Js.Dict.t<string>=?, unit) => unit = "track"
29
-
30
- @ocaml.doc("
31
- * Bindings of https://www.npmjs.com/package/@analytics/google-analytics
32
- ")
33
- @module("@analytics/google-analytics")
34
- external googleAnalytics: gaOptions => plugin = "default"