@colisweb/rescript-toolkit 3.5.2 → 3.6.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.
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colisweb/rescript-toolkit",
3
- "version": "3.5.2",
3
+ "version": "3.6.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "clean": "rescript clean",
@@ -39,6 +39,7 @@ let components: array<(string, module(Config))> = [
39
39
  ("CopyWrapper", module(Playground_CopyWrapper)),
40
40
  ("Listbox", module(Playground_Listbox)),
41
41
  ("Coordinates", module(Playground_Coordinates)),
42
+ ("Modal2", module(Playground_Modal2)),
42
43
  ]
43
44
 
44
45
  module List = {
@@ -9,10 +9,10 @@ external codeExample: string = "default"
9
9
  @react.component
10
10
  let make = () => {
11
11
  let (uncontrolledValue, setUncontrolledValue) = React.useState((): option<
12
- Toolkit__Ui_Listbox.selectOption<string>,
12
+ HeadlessUi.Listbox.selectOption<string>,
13
13
  > => None)
14
14
 
15
- let options: Toolkit__Ui_Listbox.options<string> = [
15
+ let options: array<HeadlessUi.Listbox.selectOption<string>> = [
16
16
  {
17
17
  label: "Label1",
18
18
  value: "1",
@@ -0,0 +1,68 @@
1
+ open Toolkit__Ui
2
+
3
+ @module("@root/src/ui/Toolkit__Ui_Modal2.resi?raw")
4
+ external resi: string = "default"
5
+
6
+ @module("@root/playground/components/Playground_Modal2.res?raw")
7
+ external codeExample: string = "default"
8
+
9
+ @react.component
10
+ let make = () => {
11
+ let modalSize: array<Modal.size> = [#lg, #md, #sm, #xs]
12
+
13
+ let modalColor: array<Modal.color> = [#primary, #success, #danger, #neutral]
14
+
15
+ let (isVisible, setVisibility) = React.useState(() => false)
16
+ let (size, setSize) = React.useState(() => #md)
17
+ let (modalType, setModalType) = React.useState(() => #default)
18
+
19
+ <div className="flex flex-col gap-4 items-start">
20
+ <div>
21
+ <Toolkit__Ui_Label htmlFor="size"> {"Size :"->React.string} </Toolkit__Ui_Label>
22
+ <Toolkit__Ui.Select
23
+ id="size"
24
+ value={Obj.magic(size)}
25
+ onChange={value => {
26
+ setSize(_ => value->Obj.magic)
27
+ }}
28
+ options={modalSize->Array.map((value): Toolkit__Ui.Select.selectOption => {
29
+ label: value->Obj.magic,
30
+ value: value->Obj.magic,
31
+ })}
32
+ />
33
+ </div>
34
+ <div>
35
+ <Toolkit__Ui_Label htmlFor="color"> {"Color :"->React.string} </Toolkit__Ui_Label>
36
+ <Toolkit__Ui.Select
37
+ id="size"
38
+ onChange={value => {
39
+ setModalType(_ => value === "" ? #default : #colored(Obj.magic(value)))
40
+ }}
41
+ options={
42
+ open! Toolkit__Ui.Select
43
+
44
+ [
45
+ {
46
+ label: "default",
47
+ value: "",
48
+ },
49
+ ]->Array.concat(
50
+ modalColor->Array.map(value => {
51
+ label: value->Obj.magic,
52
+ value: value->Obj.magic,
53
+ }),
54
+ )
55
+ }
56
+ />
57
+ </div>
58
+ <Button onClick={_ => setVisibility(_ => true)}> {"Show modal"->React.string} </Button>
59
+ <Modal2
60
+ isVisible
61
+ title={"title"->React.string}
62
+ body={"Body"->React.string}
63
+ hide={() => setVisibility(_ => false)}
64
+ size
65
+ type_=modalType
66
+ />
67
+ </div>
68
+ }
@@ -705,10 +705,8 @@ module Make = (StateLenses: Config) => {
705
705
  <Form.Field
706
706
  field
707
707
  render={({handleChange, value}) => <>
708
- {label->Option.mapWithDefault(React.null, label =>
709
- <Toolkit__Ui_Label htmlFor=id> label </Toolkit__Ui_Label>
710
- )}
711
708
  <Toolkit__Ui_Switch
709
+ ?label
712
710
  onChange={value => handleChange(value)}
713
711
  name=id
714
712
  checked=value
@@ -36,3 +36,4 @@ module NativeDatePicker = Toolkit__Ui_NativeDatePicker
36
36
  module ErrorBoundary = Toolkit__Ui_ErrorBoundary
37
37
  module WeekDateFilter = Toolkit__Ui_WeekDateFilter
38
38
  module Coordinates = Toolkit__Ui_Coordinates
39
+ module Modal2 = Toolkit__Ui_Modal2
@@ -1,88 +1,22 @@
1
- type selectOption<'value> = {
2
- label: string,
3
- value: 'value,
4
- disabled?: bool,
5
- }
6
-
7
- type options<'value> = array<selectOption<'value>>
1
+ module Listbox = HeadlessUi.Listbox
8
2
 
9
3
  type compare<'value> =
10
4
  | Key(string)
11
5
  | ValueEquality
12
- | Function((option<selectOption<'value>>, selectOption<'value>) => bool)
13
-
14
- module Listbox = {
15
- type renderProps = {
16
- @as("open")
17
- isOpen: bool,
18
- }
19
-
20
- @module("@headlessui/react") @react.component
21
- external make: (
22
- ~children: renderProps => React.element,
23
- ~value: 'value,
24
- ~defaultValue: selectOption<'value>=?,
25
- ~onChange: selectOption<'value> => unit=?,
26
- ~disabled: bool=?,
27
- ~by: 'a=?,
28
- ~name: string=?,
29
- ~className: string=?,
30
- ) => React.element = "Listbox"
31
-
32
- module Button = {
33
- type renderProps<'value> = {value: 'value}
34
- @module("@headlessui/react") @scope("Listbox") @react.component
35
- external make: (
36
- ~children: renderProps<'value> => React.element,
37
- ~className: string=?,
38
- ) => React.element = "Button"
39
- }
40
- module Options = {
41
- @module("@headlessui/react") @scope("Listbox") @react.component
42
- external make: (
43
- ~children: React.element,
44
- ~className: string=?,
45
- ~static: bool=?,
46
- ) => React.element = "Options"
47
- }
48
- module Option = {
49
- type renderProps = {
50
- active: bool,
51
- selected: bool,
52
- }
53
-
54
- @module("@headlessui/react") @scope("Listbox") @react.component
55
- external make: (
56
- ~children: renderProps => React.element,
57
- ~value: 'value=?,
58
- ~disabled: bool=?,
59
- ~className: string=?,
60
- ) => React.element = "Option"
61
- }
62
- }
63
-
64
- module Transition = {
65
- @module("@headlessui/react") @react.component
66
- external make: (
67
- ~show: bool,
68
- ~children: React.element,
69
- ~enter: string=?,
70
- ~enterFrom: string=?,
71
- ~enterTo: string=?,
72
- ~leave: string=?,
73
- ~leaveFrom: string=?,
74
- ~leaveTo: string=?,
75
- ~className: string=?,
76
- ) => React.element = "Transition"
77
- }
6
+ | Function(
7
+ (
8
+ option<HeadlessUi.Listbox.selectOption<'value>>,
9
+ HeadlessUi.Listbox.selectOption<'value>,
10
+ ) => bool,
11
+ )
78
12
 
79
13
  @react.component
80
14
  let make = (
81
- ~options: options<'value>,
15
+ ~options: array<Listbox.selectOption<'value>>,
82
16
  ~compare: compare<'value>,
83
- ~onChange: option<selectOption<'value> => unit>=?,
17
+ ~onChange: option<Listbox.selectOption<'value> => unit>=?,
84
18
  ~placeholder=?,
85
- ~defaultOption: option<selectOption<'value>>=?,
19
+ ~defaultOption: option<Listbox.selectOption<'value>>=?,
86
20
  ~isDisabled=?,
87
21
  ~value=?,
88
22
  ~name=?,
@@ -120,7 +54,7 @@ let make = (
120
54
  <span className="table-cell truncate text-left">
121
55
  {switch (props.value, placeholder) {
122
56
  | (None, Some(p)) => p->React.string
123
- | (Some(Some(selectedOption)), _) => selectedOption.label->React.string
57
+ | (Some(selectedOption), _) => selectedOption.label->React.string
124
58
  | _ => React.null
125
59
  }}
126
60
  </span>
@@ -128,7 +62,7 @@ let make = (
128
62
  </>
129
63
  }}
130
64
  </Listbox.Button>
131
- <Transition
65
+ <HeadlessUi.Transition
132
66
  show={props.isOpen}
133
67
  className="relative z-20"
134
68
  enter="transition duration-100 ease-out"
@@ -181,7 +115,7 @@ let make = (
181
115
  })
182
116
  ->React.array}
183
117
  </Listbox.Options>
184
- </Transition>
118
+ </HeadlessUi.Transition>
185
119
  </>
186
120
  }}
187
121
  </Listbox>
@@ -1,23 +1,20 @@
1
- type selectOption<'value> = {
2
- label: string,
3
- value: 'value,
4
- disabled?: bool,
5
- }
6
-
7
- type options<'value> = array<selectOption<'value>>
8
-
9
1
  type compare<'value> =
10
2
  | Key(string)
11
3
  | ValueEquality
12
- | Function((option<selectOption<'value>>, selectOption<'value>) => bool)
4
+ | Function(
5
+ (
6
+ option<HeadlessUi.Listbox.selectOption<'value>>,
7
+ HeadlessUi.Listbox.selectOption<'value>,
8
+ ) => bool,
9
+ )
13
10
 
14
11
  @react.component
15
12
  let make: (
16
- ~options: options<'value>,
13
+ ~options: array<HeadlessUi.Listbox.selectOption<'value>>,
17
14
  ~compare: compare<'value>,
18
- ~onChange: selectOption<'value> => unit=?,
15
+ ~onChange: HeadlessUi.Listbox.selectOption<'value> => unit=?,
19
16
  ~placeholder: string=?,
20
- ~defaultOption: selectOption<'value>=?,
17
+ ~defaultOption: HeadlessUi.Listbox.selectOption<'value>=?,
21
18
  ~isDisabled: bool=?,
22
19
  ~value: 'value=?,
23
20
  ~name: string=?,
@@ -0,0 +1,128 @@
1
+ type size = [#xs | #sm | #md | #lg | #custom(int)]
2
+ type color = [#primary | #success | #danger | #neutral]
3
+ type style = [#default | #colored(color)]
4
+
5
+ let modalStyle = (~type_) =>
6
+ switch type_ {
7
+ | #default => "rounded"
8
+ | #colored(color) =>
9
+ switch color {
10
+ | #primary => "rounded-lg"
11
+ | #success => "rounded-lg border-2 border-success-500"
12
+ | #danger => "rounded-lg border-4 border-danger-700"
13
+ | #neutral => "rounded-lg"
14
+ }
15
+ }
16
+
17
+ let headerStyle = (~type_) =>
18
+ switch type_ {
19
+ | #default => ""
20
+ | #colored(color) =>
21
+ switch color {
22
+ | #primary => "bg-primary-700 rounded-t"
23
+ | #success => "bg-success-500 rounded-t"
24
+ | #danger => "bg-danger-700"
25
+ | #neutral => "bg-neutral-700 rounded-t-lg"
26
+ }
27
+ }
28
+
29
+ let titleStyle = (~type_) =>
30
+ switch type_ {
31
+ | #default => "w-full border-b border-info-500"
32
+ | #colored(_color) => "text-white"
33
+ }
34
+
35
+ let closeIconStyle = (~type_) =>
36
+ switch type_ {
37
+ | #default => "hover:bg-gray-200"
38
+ | #colored(_) => "hover:bg-white hover:text-black text-white"
39
+ }
40
+
41
+ @module("react")
42
+ external fragment: React.element = "Fragment"
43
+
44
+ @react.component
45
+ let make = (
46
+ ~isVisible,
47
+ ~title: option<React.element>=?,
48
+ ~body: React.element,
49
+ ~hide,
50
+ ~size=#md,
51
+ ~type_=#default,
52
+ ~footer=?,
53
+ ~ariaLabel="",
54
+ ) =>
55
+ <HeadlessUi.Transition
56
+ show={isVisible}
57
+ enter="transition duration-100 ease-out"
58
+ enterFrom="transform scale-95 opacity-0"
59
+ enterTo="transform scale-100 opacity-100"
60
+ leave="transition duration-75 ease-out"
61
+ leaveFrom="transform scale-100 opacity-100"
62
+ leaveTo="transform scale-95 opacity-0">
63
+ <HeadlessUi.Dialog open_=isVisible onClose=hide className="relative z-50">
64
+ <HeadlessUi.Transition.Child
65
+ enter="ease-out duration-300"
66
+ enterFrom="opacity-0"
67
+ enterTo="opacity-100"
68
+ leave="ease-in duration-200"
69
+ leaveFrom="opacity-100"
70
+ leaveTo="opacity-0">
71
+ <div className="fixed inset-0 bg-black/30" />
72
+ </HeadlessUi.Transition.Child>
73
+ <div className="fixed inset-0 overflow-y-auto">
74
+ <div className="flex min-h-full items-start justify-center p-4">
75
+ <HeadlessUi.Transition.Child
76
+ \"as"={Node(fragment)}
77
+ enter="ease-out duration-300"
78
+ enterFrom="opacity-0 scale-95"
79
+ enterTo="opacity-100 scale-100"
80
+ leave="ease-in duration-200"
81
+ leaveFrom="opacity-100 scale-100"
82
+ leaveTo="opacity-0 scale-95">
83
+ <HeadlessUi.Dialog.Panel
84
+ className={cx(["bg-white pb-5 shadow-lg w-full mt-[10vh]", modalStyle(~type_)])}
85
+ style={ReactDOMStyle.make(
86
+ ~maxWidth={
87
+ let value = switch size {
88
+ | #xs => 480
89
+ | #sm => 600
90
+ | #md => 768
91
+ | #lg => 900
92
+ | #custom(value) => value
93
+ }
94
+ `${value->Int.toString}px`
95
+ },
96
+ (),
97
+ )}>
98
+ <header
99
+ className={cx([
100
+ "flex items-center justify-between mb-4 pl-5 pr-3 pt-2 pb-1",
101
+ headerStyle(~type_),
102
+ ])}>
103
+ {title->Option.mapWithDefault(React.null, title =>
104
+ <HeadlessUi.Dialog.Title
105
+ className={cx(["text-2xl pb-1 font-display", titleStyle(~type_)])}>
106
+ title
107
+ </HeadlessUi.Dialog.Title>
108
+ )}
109
+ <button
110
+ onClick={_ => hide()}
111
+ className={cx([
112
+ title->Option.isSome ? "ml-4" : "ml-auto",
113
+ "p-1 rounded-full modal-close-button",
114
+ closeIconStyle(~type_),
115
+ ])}>
116
+ <ReactIcons.MdClose size=28 />
117
+ </button>
118
+ </header>
119
+ <div className="px-1 sm:px-2 md:px-5"> body </div>
120
+ {footer->Option.mapWithDefault(React.null, footer =>
121
+ <div className="flex flex-row justify-end mt-6 pr-4"> footer </div>
122
+ )}
123
+ </HeadlessUi.Dialog.Panel>
124
+ </HeadlessUi.Transition.Child>
125
+ </div>
126
+ </div>
127
+ </HeadlessUi.Dialog>
128
+ </HeadlessUi.Transition>
@@ -0,0 +1,15 @@
1
+ type size = [#xs | #sm | #md | #lg | #custom(int)]
2
+ type color = [#primary | #success | #danger | #neutral]
3
+ type style = [#default | #colored(color)]
4
+
5
+ @react.component
6
+ let make: (
7
+ ~isVisible: bool,
8
+ ~title: React.element=?,
9
+ ~body: React.element,
10
+ ~hide: unit => unit,
11
+ ~size: size=?, // default: `md
12
+ ~type_: style=?, // default: `default
13
+ ~footer: React.element=?,
14
+ ~ariaLabel: string=?,
15
+ ) => React.element
@@ -0,0 +1,118 @@
1
+ module Listbox = {
2
+ type renderProps = {
3
+ @as("open")
4
+ isOpen: bool,
5
+ }
6
+
7
+ type selectOption<'value> = {
8
+ label: string,
9
+ value: 'value,
10
+ disabled?: bool,
11
+ }
12
+
13
+ @module("@headlessui/react") @react.component
14
+ external make: (
15
+ ~children: renderProps => React.element,
16
+ ~value: 'value,
17
+ ~defaultValue: selectOption<'value>=?,
18
+ ~onChange: selectOption<'value> => unit=?,
19
+ ~disabled: bool=?,
20
+ ~by: 'a=?,
21
+ ~name: string=?,
22
+ ~className: string=?,
23
+ ) => React.element = "Listbox"
24
+
25
+ module Button = {
26
+ type renderProps<'value> = {value: option<selectOption<'value>>}
27
+
28
+ @module("@headlessui/react") @scope("Listbox") @react.component
29
+ external make: (
30
+ ~children: renderProps<'value> => React.element,
31
+ ~className: string=?,
32
+ ) => React.element = "Button"
33
+ }
34
+ module Options = {
35
+ @module("@headlessui/react") @scope("Listbox") @react.component
36
+ external make: (
37
+ ~children: React.element,
38
+ ~className: string=?,
39
+ ~static: bool=?,
40
+ ) => React.element = "Options"
41
+ }
42
+ module Option = {
43
+ type renderProps = {
44
+ active: bool,
45
+ selected: bool,
46
+ }
47
+
48
+ @module("@headlessui/react") @scope("Listbox") @react.component
49
+ external make: (
50
+ ~children: renderProps => React.element,
51
+ ~value: 'value=?,
52
+ ~disabled: bool=?,
53
+ ~className: string=?,
54
+ ) => React.element = "Option"
55
+ }
56
+ }
57
+
58
+ module Transition = {
59
+ @unboxed
60
+ type rec as_<'a> = Node('a): as_<'a>
61
+
62
+ @module("@headlessui/react") @react.component
63
+ external make: (
64
+ ~show: bool,
65
+ ~children: React.element,
66
+ ~enter: string=?,
67
+ ~enterFrom: string=?,
68
+ ~enterTo: string=?,
69
+ ~leave: string=?,
70
+ ~leaveFrom: string=?,
71
+ ~leaveTo: string=?,
72
+ ~className: string=?,
73
+ ~\"as": as_<'a>=?,
74
+ ) => React.element = "Transition"
75
+
76
+ module Child = {
77
+ @module("@headlessui/react") @scope("Transition") @react.component
78
+ external make: (
79
+ ~children: React.element,
80
+ ~enter: string=?,
81
+ ~enterFrom: string=?,
82
+ ~enterTo: string=?,
83
+ ~leave: string=?,
84
+ ~leaveFrom: string=?,
85
+ ~leaveTo: string=?,
86
+ ~className: string=?,
87
+ ~\"as": as_<'a>=?,
88
+ ) => React.element = "Child"
89
+ }
90
+ }
91
+
92
+ module Dialog = {
93
+ @module("@headlessui/react") @react.component
94
+ external make: (
95
+ ~open_: bool,
96
+ ~onClose: unit => unit,
97
+ ~children: React.element,
98
+ ~className: string=?,
99
+ ~style: ReactDOM.Style.t=?,
100
+ ) => React.element = "Dialog"
101
+
102
+ module Panel = {
103
+ @module("@headlessui/react") @scope("Dialog") @react.component
104
+ external make: (
105
+ ~children: React.element,
106
+ ~className: string=?,
107
+ ~style: ReactDOM.Style.t=?,
108
+ ) => React.element = "Panel"
109
+ }
110
+ module Title = {
111
+ @module("@headlessui/react") @scope("Dialog") @react.component
112
+ external make: (
113
+ ~children: React.element,
114
+ ~className: string=?,
115
+ ~style: ReactDOM.Style.t=?,
116
+ ) => React.element = "Title"
117
+ }
118
+ }