@colisweb/rescript-toolkit 5.45.0 → 5.46.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.
- package/package.json +3 -1
- package/src/decoders/Toolkit__Decoders.res +24 -0
- package/src/tailwind/tailwind.config.cjs +13 -0
- package/src/ui/Toolkit__Ui_Modal.res +86 -0
- package/src/ui/Toolkit__Ui_Modal.resi +15 -0
- package/src/ui/Toolkit__Ui_NativeDatePicker.res +10 -2
- package/src/ui/Toolkit__Ui_NativeDatePicker.resi +1 -0
- package/src/vendors/DateFns.res +29 -17
- package/src/vendors/Radix.res +141 -1
- package/src/vendors/ReactUse.res +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colisweb/rescript-toolkit",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.46.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"clean": "rescript clean",
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
"@greenlabs/ppx-spice": "0.2.1",
|
|
36
36
|
"@headlessui/react": "2.2.1",
|
|
37
37
|
"@headlessui/tailwindcss": "0.2.2",
|
|
38
|
+
"@radix-ui/react-context-menu": "^2.2.16",
|
|
39
|
+
"@radix-ui/react-dialog": "1.1.15",
|
|
38
40
|
"@radix-ui/react-dropdown-menu": "2.1.7",
|
|
39
41
|
"@radix-ui/react-popover": "1.1.7",
|
|
40
42
|
"@radix-ui/react-scroll-area": "1.2.4",
|
|
@@ -73,6 +73,30 @@ module Date = {
|
|
|
73
73
|
type t = @spice.codec(codec) date
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
module LocalDate = {
|
|
77
|
+
type date = Js.Date.t
|
|
78
|
+
|
|
79
|
+
let encoder: Spice.encoder<date> = date =>
|
|
80
|
+
date->DateFns.formatWithPattern("yyyy-MM-dd")->Spice.stringToJson
|
|
81
|
+
|
|
82
|
+
let decoder: Spice.decoder<date> = json =>
|
|
83
|
+
switch Spice.stringFromJson(json) {
|
|
84
|
+
| Ok(v) =>
|
|
85
|
+
DateFns.parseWithPatternWithOptions(
|
|
86
|
+
v,
|
|
87
|
+
"yyyy-MM-dd",
|
|
88
|
+
Js.Date.make()->DateFns.startOfDay,
|
|
89
|
+
{locale: DateFns.frLocale},
|
|
90
|
+
)->Ok
|
|
91
|
+
| Error(_) as err => err
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let codec: Spice.codec<date> = (encoder, decoder)
|
|
95
|
+
|
|
96
|
+
@spice
|
|
97
|
+
type t = @spice.codec(codec) date
|
|
98
|
+
}
|
|
99
|
+
|
|
76
100
|
module LocalDatetime = {
|
|
77
101
|
type date = Js.Date.t
|
|
78
102
|
|
|
@@ -23,6 +23,8 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
animation: {
|
|
25
25
|
backforth: "backforth 2s ease-in-out infinite",
|
|
26
|
+
overlayShow: "overlayShow 200ms cubic-bezier(0.16, 1, 0.3, 1)",
|
|
27
|
+
contentShow: "contentShow 300ms cubic-bezier(0.16, 1, 0.3, 1)",
|
|
26
28
|
},
|
|
27
29
|
keyframes: {
|
|
28
30
|
backforth: {
|
|
@@ -30,6 +32,17 @@ module.exports = {
|
|
|
30
32
|
"50%": { left: "100%" },
|
|
31
33
|
"100%": { left: "0px" },
|
|
32
34
|
},
|
|
35
|
+
overlayShow: {
|
|
36
|
+
from: { opacity: "0" },
|
|
37
|
+
to: { opacity: "1" },
|
|
38
|
+
},
|
|
39
|
+
contentShow: {
|
|
40
|
+
from: {
|
|
41
|
+
opacity: "0",
|
|
42
|
+
transform: "scale(0.95)",
|
|
43
|
+
},
|
|
44
|
+
to: { opacity: "1", transform: "scale(1)" },
|
|
45
|
+
},
|
|
33
46
|
},
|
|
34
47
|
},
|
|
35
48
|
screens: {
|
|
@@ -118,3 +118,89 @@ let make = (
|
|
|
118
118
|
</HeadlessUi.Dialog.Panel>
|
|
119
119
|
</div>
|
|
120
120
|
</HeadlessUi.Dialog>
|
|
121
|
+
|
|
122
|
+
module Radix = {
|
|
123
|
+
open Radix
|
|
124
|
+
@react.component
|
|
125
|
+
let make = (
|
|
126
|
+
~isVisible,
|
|
127
|
+
~title: option<React.element>=?,
|
|
128
|
+
~body: React.element,
|
|
129
|
+
~hide,
|
|
130
|
+
~size=#md,
|
|
131
|
+
~type_=#default,
|
|
132
|
+
~footer=?,
|
|
133
|
+
~ariaLabel="",
|
|
134
|
+
~icon: option<module(ReactIcons.Icon)>=?,
|
|
135
|
+
) => {
|
|
136
|
+
// let (isOpen, setIsOpen) = React.useState(() => isVisible)
|
|
137
|
+
<Dialog.Root
|
|
138
|
+
\"open"=isVisible
|
|
139
|
+
onOpenChange={isOpen => {
|
|
140
|
+
if !isOpen {
|
|
141
|
+
hide()
|
|
142
|
+
}
|
|
143
|
+
}}>
|
|
144
|
+
<Dialog.Portal>
|
|
145
|
+
<Dialog.Overlay
|
|
146
|
+
className="z-40 fixed inset-0 bg-black/30 data-[state=open]:animate-overlayShow"
|
|
147
|
+
/>
|
|
148
|
+
<div
|
|
149
|
+
className="z-50 fixed inset-0 overflow-y-auto flex min-h-full items-start justify-center p-4">
|
|
150
|
+
<Dialog.Content
|
|
151
|
+
className={cx([
|
|
152
|
+
"bg-white pb-5 shadow-lg w-full mt-[10vh] data-[state=open]:animate-contentShow",
|
|
153
|
+
modalStyle(~type_),
|
|
154
|
+
])}
|
|
155
|
+
style={ReactDOMStyle.make(
|
|
156
|
+
~maxWidth={
|
|
157
|
+
let value = switch size {
|
|
158
|
+
| #xs => 480
|
|
159
|
+
| #sm => 600
|
|
160
|
+
| #md => 768
|
|
161
|
+
| #lg => 900
|
|
162
|
+
| #custom(value) => value
|
|
163
|
+
}
|
|
164
|
+
`${value->Int.toString}px`
|
|
165
|
+
},
|
|
166
|
+
(),
|
|
167
|
+
)}>
|
|
168
|
+
<header
|
|
169
|
+
className={cx([
|
|
170
|
+
"flex items-center justify-between mb-4 pl-5 pr-3 pt-2 pb-1",
|
|
171
|
+
headerStyle(~type_),
|
|
172
|
+
])}>
|
|
173
|
+
{title->Option.mapWithDefault(React.null, title =>
|
|
174
|
+
<Dialog.Title
|
|
175
|
+
className={cx([
|
|
176
|
+
"text-2xl pb-1 inline-flex items-center gap-2 font-display",
|
|
177
|
+
titleStyle(~type_),
|
|
178
|
+
])}>
|
|
179
|
+
{icon->Option.mapWithDefault(React.null, icon => {
|
|
180
|
+
let module(Icon) = icon
|
|
181
|
+
|
|
182
|
+
<Icon />
|
|
183
|
+
})}
|
|
184
|
+
title
|
|
185
|
+
</Dialog.Title>
|
|
186
|
+
)}
|
|
187
|
+
<button
|
|
188
|
+
onClick={_ => hide()}
|
|
189
|
+
className={cx([
|
|
190
|
+
title->Option.isSome ? "ml-4" : "ml-auto",
|
|
191
|
+
"p-1 rounded-full modal-close-button",
|
|
192
|
+
closeIconStyle(~type_),
|
|
193
|
+
])}>
|
|
194
|
+
<ReactIcons.MdClose size=28 />
|
|
195
|
+
</button>
|
|
196
|
+
</header>
|
|
197
|
+
<div className="px-1 sm:px-2 md:px-5"> body </div>
|
|
198
|
+
{footer->Option.mapWithDefault(React.null, footer =>
|
|
199
|
+
<div className="flex flex-row justify-end mt-6 pr-4"> footer </div>
|
|
200
|
+
)}
|
|
201
|
+
</Dialog.Content>
|
|
202
|
+
</div>
|
|
203
|
+
</Dialog.Portal>
|
|
204
|
+
</Dialog.Root>
|
|
205
|
+
}
|
|
206
|
+
}
|
|
@@ -14,3 +14,18 @@ let make: (
|
|
|
14
14
|
~ariaLabel: string=?,
|
|
15
15
|
~icon: module(ReactIcons.Icon)=?,
|
|
16
16
|
) => React.element
|
|
17
|
+
|
|
18
|
+
module Radix: {
|
|
19
|
+
@react.component
|
|
20
|
+
let make: (
|
|
21
|
+
~isVisible: bool,
|
|
22
|
+
~title: React.element=?,
|
|
23
|
+
~body: React.element,
|
|
24
|
+
~hide: unit => unit,
|
|
25
|
+
~size: size=?, // default: `md
|
|
26
|
+
~type_: style=?, // default: `default
|
|
27
|
+
~footer: React.element=?,
|
|
28
|
+
~ariaLabel: string=?,
|
|
29
|
+
~icon: module(ReactIcons.Icon)=?,
|
|
30
|
+
) => React.element
|
|
31
|
+
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
@react.component
|
|
2
|
-
let make = (
|
|
3
|
-
|
|
2
|
+
let make = (
|
|
3
|
+
~onChange,
|
|
4
|
+
~value=?,
|
|
5
|
+
~id=?,
|
|
6
|
+
~disabled=false,
|
|
7
|
+
~isInvalid=false,
|
|
8
|
+
~className="",
|
|
9
|
+
~containerClassName="",
|
|
10
|
+
) =>
|
|
11
|
+
<div className={cx(["relative", containerClassName])}>
|
|
4
12
|
<input
|
|
5
13
|
?id
|
|
6
14
|
value=?{value->Option.map(d => d->DateFns.formatWithPattern("yyyy-MM-dd"))}
|
package/src/vendors/DateFns.res
CHANGED
|
@@ -49,6 +49,16 @@ external isWithinInterval: (Js.Date.t, intervalObject) => bool = "isWithinInterv
|
|
|
49
49
|
|
|
50
50
|
// parse
|
|
51
51
|
|
|
52
|
+
type parseOptions = {locale?: dateFnsLocale}
|
|
53
|
+
|
|
54
|
+
@module("date-fns")
|
|
55
|
+
external parse: string => Js.Date.t = "parse"
|
|
56
|
+
@module("date-fns")
|
|
57
|
+
external parseWithPattern: (string, string) => Js.Date.t = "parse"
|
|
58
|
+
@module("date-fns")
|
|
59
|
+
external parseWithPatternWithOptions: (string, string, Js.Date.t, parseOptions) => Js.Date.t =
|
|
60
|
+
"parse"
|
|
61
|
+
|
|
52
62
|
@module("date-fns")
|
|
53
63
|
external parseISO: string => Js.Date.t = "parseISO"
|
|
54
64
|
|
|
@@ -137,6 +147,21 @@ external isSameMonth: (Js.Date.t, Js.Date.t) => bool = "isSameMonth"
|
|
|
137
147
|
@module("date-fns")
|
|
138
148
|
external isFirstDayOfMonth: Js.Date.t => bool = "isFirstDayOfMonth"
|
|
139
149
|
|
|
150
|
+
@module("date-fns")
|
|
151
|
+
external isMonday: Js.Date.t => bool = "isMonday"
|
|
152
|
+
@module("date-fns")
|
|
153
|
+
external isTuesday: Js.Date.t => bool = "isTuesday"
|
|
154
|
+
@module("date-fns")
|
|
155
|
+
external isWednesday: Js.Date.t => bool = "isWednesday"
|
|
156
|
+
@module("date-fns")
|
|
157
|
+
external isThursday: Js.Date.t => bool = "isThursday"
|
|
158
|
+
@module("date-fns")
|
|
159
|
+
external isFriday: Js.Date.t => bool = "isFriday"
|
|
160
|
+
@module("date-fns")
|
|
161
|
+
external isSaturday: Js.Date.t => bool = "isSaturday"
|
|
162
|
+
@module("date-fns")
|
|
163
|
+
external isSunday: Js.Date.t => bool = "isSunday"
|
|
164
|
+
|
|
140
165
|
// other
|
|
141
166
|
|
|
142
167
|
@module("date-fns")
|
|
@@ -149,9 +174,6 @@ external getDay: Js.Date.t => int = "getDay"
|
|
|
149
174
|
@module("date-fns")
|
|
150
175
|
external getHours: Js.Date.t => int = "getHours"
|
|
151
176
|
|
|
152
|
-
@module("date-fns")
|
|
153
|
-
external parse: string => Js.Date.t = "parse"
|
|
154
|
-
|
|
155
177
|
@module("date-fns")
|
|
156
178
|
external nextTuesday: Js.Date.t => Js.Date.t = "nextTuesday"
|
|
157
179
|
@module("date-fns")
|
|
@@ -166,19 +188,9 @@ external nextSaturday: Js.Date.t => Js.Date.t = "nextSaturday"
|
|
|
166
188
|
external nextSunday: Js.Date.t => Js.Date.t = "nextSunday"
|
|
167
189
|
|
|
168
190
|
@module("date-fns")
|
|
169
|
-
external
|
|
170
|
-
@module("date-fns")
|
|
171
|
-
external isTuesday: Js.Date.t => bool = "isTuesday"
|
|
172
|
-
@module("date-fns")
|
|
173
|
-
external isWednesday: Js.Date.t => bool = "isWednesday"
|
|
174
|
-
@module("date-fns")
|
|
175
|
-
external isThursday: Js.Date.t => bool = "isThursday"
|
|
176
|
-
@module("date-fns")
|
|
177
|
-
external isFriday: Js.Date.t => bool = "isFriday"
|
|
178
|
-
@module("date-fns")
|
|
179
|
-
external isSaturday: Js.Date.t => bool = "isSaturday"
|
|
180
|
-
@module("date-fns")
|
|
181
|
-
external isSunday: Js.Date.t => bool = "isSunday"
|
|
191
|
+
external minutesToHours: int => int = "minutesToHours"
|
|
182
192
|
|
|
183
193
|
@module("date-fns")
|
|
184
|
-
external
|
|
194
|
+
external max: array<Js.Date.t> => Js.Date.t = "max"
|
|
195
|
+
@module("date-fns")
|
|
196
|
+
external min: array<Js.Date.t> => Js.Date.t = "min"
|
package/src/vendors/Radix.res
CHANGED
|
@@ -164,7 +164,7 @@ module DropdownMenu = {
|
|
|
164
164
|
external make: React.component<props> = "Root"
|
|
165
165
|
}
|
|
166
166
|
module Trigger = {
|
|
167
|
-
type options = {asChild?: bool}
|
|
167
|
+
type options = {asChild?: bool, disabled?: bool}
|
|
168
168
|
type props = {...options, children: React.element}
|
|
169
169
|
@module("@radix-ui/react-dropdown-menu")
|
|
170
170
|
external make: React.component<props> = "Trigger"
|
|
@@ -471,3 +471,143 @@ module Toast = {
|
|
|
471
471
|
external make: React.component<props> = "Close"
|
|
472
472
|
}
|
|
473
473
|
}
|
|
474
|
+
|
|
475
|
+
module Dialog = {
|
|
476
|
+
module Root = {
|
|
477
|
+
type options = {
|
|
478
|
+
defaultOpen?: bool,
|
|
479
|
+
\"open": bool,
|
|
480
|
+
onOpenChange?: bool => unit,
|
|
481
|
+
modal?: bool,
|
|
482
|
+
}
|
|
483
|
+
type props = {
|
|
484
|
+
...options,
|
|
485
|
+
children: React.element,
|
|
486
|
+
}
|
|
487
|
+
@module("@radix-ui/react-dialog")
|
|
488
|
+
external make: React.component<props> = "Root"
|
|
489
|
+
}
|
|
490
|
+
module Trigger = {
|
|
491
|
+
type props = {children: React.element, asChild?: bool}
|
|
492
|
+
@module("@radix-ui/react-dialog")
|
|
493
|
+
external make: React.component<props> = "Trigger"
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
module Portal = {
|
|
497
|
+
@module("@radix-ui/react-dialog") @react.component
|
|
498
|
+
external make: (
|
|
499
|
+
~children: React.element,
|
|
500
|
+
~forceMount: bool=?,
|
|
501
|
+
~className: string=?,
|
|
502
|
+
) => React.element = "Portal"
|
|
503
|
+
}
|
|
504
|
+
module Overlay = {
|
|
505
|
+
@module("@radix-ui/react-dialog") @react.component
|
|
506
|
+
external make: (
|
|
507
|
+
~children: React.element=?,
|
|
508
|
+
~className: string=?,
|
|
509
|
+
~asChild: bool=?,
|
|
510
|
+
~forceMount: bool=?,
|
|
511
|
+
) => React.element = "Overlay"
|
|
512
|
+
}
|
|
513
|
+
module Content = {
|
|
514
|
+
type align =
|
|
515
|
+
| @as("center") Center
|
|
516
|
+
| @as("start") Start
|
|
517
|
+
| @as("end") End
|
|
518
|
+
|
|
519
|
+
type side =
|
|
520
|
+
| @as("top") Top
|
|
521
|
+
| @as("right") Right
|
|
522
|
+
| @as("bottom") Bottom
|
|
523
|
+
| @as("left") Left
|
|
524
|
+
|
|
525
|
+
type options = {
|
|
526
|
+
asChild?: bool,
|
|
527
|
+
forceMount?: bool,
|
|
528
|
+
onOpenAutoFocus?: ReactEvent.Focus.t => unit,
|
|
529
|
+
onCloseAutoFocus?: ReactEvent.Focus.t => unit,
|
|
530
|
+
onEscapeKeyDown?: ReactEvent.Keyboard.t => unit,
|
|
531
|
+
onPointerDownOutside?: ReactEvent.Mouse.t => unit,
|
|
532
|
+
onInteractOutside?: ReactEvent.Mouse.t => unit,
|
|
533
|
+
className?: string,
|
|
534
|
+
style?: ReactDOMStyle.t,
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
type props = {
|
|
538
|
+
...options,
|
|
539
|
+
children: React.element,
|
|
540
|
+
}
|
|
541
|
+
@module("@radix-ui/react-dialog")
|
|
542
|
+
external make: React.component<props> = "Content"
|
|
543
|
+
}
|
|
544
|
+
module Close = {
|
|
545
|
+
type props = {className?: string, children?: React.element, asChild?: bool}
|
|
546
|
+
@module("@radix-ui/react-dialog")
|
|
547
|
+
external make: React.component<props> = "Close"
|
|
548
|
+
}
|
|
549
|
+
module Title = {
|
|
550
|
+
type props = {className?: string, asChild?: bool, children?: React.element}
|
|
551
|
+
@module("@radix-ui/react-dialog")
|
|
552
|
+
external make: React.component<props> = "Title"
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// module ContextMenu = {
|
|
557
|
+
// module Root = {
|
|
558
|
+
// type options = {onOpenChange?: bool => unit, modal?: bool}
|
|
559
|
+
// type props = {
|
|
560
|
+
// ...options,
|
|
561
|
+
// children: React.element,
|
|
562
|
+
// }
|
|
563
|
+
// @module("@radix-ui/react-context-menu")
|
|
564
|
+
// external make: React.component<props> = "Root"
|
|
565
|
+
// }
|
|
566
|
+
|
|
567
|
+
// module Trigger = {
|
|
568
|
+
// type props = {children: React.element, disabled?: bool, asChild?: bool, className?: string}
|
|
569
|
+
// @module("@radix-ui/react-context-menu")
|
|
570
|
+
// external make: React.component<props> = "Trigger"
|
|
571
|
+
// }
|
|
572
|
+
|
|
573
|
+
// module Portal = {
|
|
574
|
+
// @module("@radix-ui/react-context-menu") @react.component
|
|
575
|
+
// external make: (~children: React.element) => React.element = "Portal"
|
|
576
|
+
// }
|
|
577
|
+
// module Content = {
|
|
578
|
+
// type options = {alignOffset?: int, sideOffset?: int, align?: string}
|
|
579
|
+
|
|
580
|
+
// type props = {
|
|
581
|
+
// ...options,
|
|
582
|
+
// className?: string,
|
|
583
|
+
// children: React.element,
|
|
584
|
+
// }
|
|
585
|
+
// @module("@radix-ui/react-context-menu")
|
|
586
|
+
// external make: React.component<props> = "Content"
|
|
587
|
+
|
|
588
|
+
// let className = "z-50 min-w-[220px] bg-white rounded-md overflow-hidden p-[5px] shadow-lg"
|
|
589
|
+
// }
|
|
590
|
+
// module Arrow = {
|
|
591
|
+
// type props = {className?: string, width?: int, height?: int}
|
|
592
|
+
// @module("@radix-ui/react-context-menu")
|
|
593
|
+
// external make: React.component<props> = "Arrow"
|
|
594
|
+
// }
|
|
595
|
+
// module Label = {
|
|
596
|
+
// type props = {className?: string, width?: int, height?: int}
|
|
597
|
+
// @module("@radix-ui/react-context-menu")
|
|
598
|
+
// external make: React.component<props> = "Label"
|
|
599
|
+
// }
|
|
600
|
+
// module Item = {
|
|
601
|
+
// type props = {
|
|
602
|
+
// className?: string,
|
|
603
|
+
// disabled?: bool,
|
|
604
|
+
// onSelect?: ReactEvent.Mouse.t => unit,
|
|
605
|
+
// textValue: string,
|
|
606
|
+
// children: React.element,
|
|
607
|
+
// }
|
|
608
|
+
// @module("@radix-ui/react-context-menu")
|
|
609
|
+
// external make: React.component<props> = "Item"
|
|
610
|
+
|
|
611
|
+
// let className = "text-sm leading-none text-neutral-700 rounded-[3px] flex items-center h-[25px] py-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-neutral-900 data-[disabled]:pointer-events-none data-[highlighted]:text-neutral-500 data-[highlighted]:bg-neutral-100"
|
|
612
|
+
// }
|
|
613
|
+
// }
|
package/src/vendors/ReactUse.res
CHANGED
|
@@ -68,3 +68,16 @@ type scrollCoords = {
|
|
|
68
68
|
|
|
69
69
|
@module("react-use")
|
|
70
70
|
external useWindowScroll: unit => scrollCoords = "useWindowScroll"
|
|
71
|
+
|
|
72
|
+
type measure = {
|
|
73
|
+
x: int,
|
|
74
|
+
y: int,
|
|
75
|
+
width: int,
|
|
76
|
+
height: int,
|
|
77
|
+
top: int,
|
|
78
|
+
right: int,
|
|
79
|
+
bottom: int,
|
|
80
|
+
left: int,
|
|
81
|
+
}
|
|
82
|
+
@module("react-use")
|
|
83
|
+
external useMeasure: unit => (React.ref<Js.Nullable.t<Dom.element>>, measure) = "useMeasure"
|