@colisweb/rescript-toolkit 5.45.0 → 5.46.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colisweb/rescript-toolkit",
3
- "version": "5.45.0",
3
+ "version": "5.46.1",
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 = (~onChange, ~value=?, ~id=?, ~disabled=false, ~isInvalid=false, ~className="") =>
3
- <div className="relative">
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"))}
@@ -6,4 +6,5 @@ let make: (
6
6
  ~disabled: bool=?,
7
7
  ~isInvalid: bool=?,
8
8
  ~className: string=?,
9
+ ~containerClassName: string=?,
9
10
  ) => React.element
@@ -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
 
@@ -148,6 +158,8 @@ external getTime: Js.Date.t => float = "getTime"
148
158
  external getDay: Js.Date.t => int = "getDay"
149
159
  @module("date-fns")
150
160
  external getHours: Js.Date.t => int = "getHours"
161
+ @module("date-fns")
162
+ external getMinutes: Js.Date.t => int = "getMinutes"
151
163
 
152
164
  @module("date-fns")
153
165
  external parse: string => Js.Date.t = "parse"
@@ -180,5 +192,35 @@ external isSaturday: Js.Date.t => bool = "isSaturday"
180
192
  @module("date-fns")
181
193
  external isSunday: Js.Date.t => bool = "isSunday"
182
194
 
195
+ // other
196
+
197
+ @module("date-fns")
198
+ external getWeekNumber: Js.Date.t => int = "getWeek"
199
+
200
+ @module("date-fns")
201
+ external getTime: Js.Date.t => float = "getTime"
202
+ @module("date-fns")
203
+ external getDay: Js.Date.t => int = "getDay"
204
+ @module("date-fns")
205
+ external getHours: Js.Date.t => int = "getHours"
206
+
207
+ @module("date-fns")
208
+ external nextTuesday: Js.Date.t => Js.Date.t = "nextTuesday"
209
+ @module("date-fns")
210
+ external nextWednesday: Js.Date.t => Js.Date.t = "nextWednesday"
211
+ @module("date-fns")
212
+ external nextThursday: Js.Date.t => Js.Date.t = "nextThursday"
213
+ @module("date-fns")
214
+ external nextFriday: Js.Date.t => Js.Date.t = "nextFriday"
215
+ @module("date-fns")
216
+ external nextSaturday: Js.Date.t => Js.Date.t = "nextSaturday"
217
+ @module("date-fns")
218
+ external nextSunday: Js.Date.t => Js.Date.t = "nextSunday"
219
+
183
220
  @module("date-fns")
184
221
  external minutesToHours: int => int = "minutesToHours"
222
+
223
+ @module("date-fns")
224
+ external max: array<Js.Date.t> => Js.Date.t = "max"
225
+ @module("date-fns")
226
+ external min: array<Js.Date.t> => Js.Date.t = "min"
@@ -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
+ // }
@@ -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"