@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colisweb/rescript-toolkit",
3
- "version": "5.45.0",
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 = (~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
 
@@ -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 isMonday: Js.Date.t => bool = "isMonday"
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 minutesToHours: int => int = "minutesToHours"
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"
@@ -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"