@colisweb/rescript-toolkit 2.23.0 → 2.25.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": "2.23.0",
3
+ "version": "2.25.1",
4
4
  "scripts": {
5
5
  "clean": "rescript clean",
6
6
  "build": "rescript build",
@@ -25,6 +25,7 @@ module Reference = Toolkit__Ui_Reference
25
25
  module RichText = Toolkit__Ui_RichText
26
26
  module ProgressBar = Toolkit__Ui_ProgressBar
27
27
  module Dropdown = Toolkit__Ui_Dropdown
28
+ module DropdownList = Toolkit__Ui_DropdownList
28
29
  module Layout = Toolkit__Ui_Layout
29
30
  module SpinnerFullScreen = Toolkit__Ui_SpinnerFullScreen
30
31
  module MultiSelect = Toolkit__Ui_MultiSelect
@@ -0,0 +1,166 @@
1
+ type position = [
2
+ | #bottom
3
+ | #top
4
+ ]
5
+
6
+ type item = {
7
+ icon: React.element,
8
+ label: React.element,
9
+ onClick: unit => unit,
10
+ className: string,
11
+ }
12
+
13
+ @react.component
14
+ let make = (
15
+ ~label: React.element,
16
+ ~dropdownClassName="",
17
+ ~buttonClassName="",
18
+ ~containerClassName="",
19
+ ~defaultIsOpen=false,
20
+ ~buttonColor: Toolkit__Ui_Button.color=#white,
21
+ ~buttonSize: Toolkit__Ui_Button.size=#md,
22
+ ~buttonVariant: Toolkit__Ui_Button.variant=#default,
23
+ ~position=#bottom,
24
+ ~items: array<item>,
25
+ ) => {
26
+ let dropdownRef = React.useRef(Js.Nullable.null)
27
+ let buttonRef = React.useRef(Js.Nullable.null)
28
+ let (position, _setPosition) = React.useState(() => position)
29
+ let {isOpen, hide, toggle} = Toolkit__Hooks.useDisclosure(~defaultIsOpen, ())
30
+ let {isXs} = Toolkit__Hooks.useMediaQuery()
31
+
32
+ Toolkit__Hooks.useOnClickOutside(dropdownRef, _ => {
33
+ hide()
34
+ })
35
+ let (adjustmentStyle, setAdjustmentStyle) = React.useState(() => None)
36
+
37
+ React.useEffect1(() => {
38
+ if isOpen && !isXs {
39
+ Js.Global.setTimeout(() => {
40
+ buttonRef.current
41
+ ->Js.Nullable.toOption
42
+ ->Option.forEach(dom => {
43
+ let buttonRect = dom->Browser.DomElement.getBoundingClientRect
44
+ let dropdownRect =
45
+ dropdownRef.current
46
+ ->Js.Nullable.toOption
47
+ ->Option.map(Browser.DomElement.getBoundingClientRect)
48
+
49
+ let calculatedTop = switch position {
50
+ | #bottom => buttonRect.top +. buttonRect.height +. 10.
51
+ | #top => {
52
+ let base = buttonRect.top -. 10.
53
+ switch dropdownRect {
54
+ | None => base
55
+ | Some({height}) => {
56
+ let newBase = base -. height /. 2.
57
+ newBase < 0. ? buttonRect.top +. buttonRect.height +. 10. : newBase
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ let calculatedLeft = {
64
+ let baseContainerCenter = buttonRect.left +. buttonRect.width /. 2.
65
+
66
+ switch dropdownRect {
67
+ | None => baseContainerCenter
68
+ | Some({width}) => {
69
+ let baseCalculated = baseContainerCenter -. width /. 2.
70
+ let hasOverflowLeft = baseCalculated < 0.
71
+ let hasOverflowRight =
72
+ baseContainerCenter +. width /. 2. > Browser.innerWidth->Int.toFloat
73
+
74
+ if hasOverflowLeft {
75
+ 0.
76
+ } else if hasOverflowRight {
77
+ let tmp = baseContainerCenter +. width /. 2.
78
+
79
+ baseCalculated -. (tmp -. Browser.innerWidth->Int.toFloat)
80
+ } else {
81
+ baseCalculated
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ setAdjustmentStyle(_ => Some(
88
+ ReactDOM.Style.make(
89
+ ~top=`${calculatedTop->Js.Float.toString}px`,
90
+ ~left=`${calculatedLeft->Js.Float.toString}px`,
91
+ ~opacity="1",
92
+ (),
93
+ ),
94
+ ))
95
+ })
96
+ }, 16)->ignore
97
+ } else {
98
+ setAdjustmentStyle(_ => None)
99
+ }
100
+ None
101
+ }, [isOpen, isXs])
102
+
103
+ <div className={cx(["relative", containerClassName])}>
104
+ <Toolkit__Ui_Button
105
+ variant=buttonVariant
106
+ buttonRef={ReactDOM.Ref.domRef(buttonRef)}
107
+ size=buttonSize
108
+ type_="button"
109
+ color=buttonColor
110
+ onClick={event => {
111
+ switch dropdownRef.current->Js.Nullable.toOption {
112
+ | None => toggle()
113
+ | Some(domRef) => {
114
+ let isInDropdown = ReactEvent.Mouse.currentTarget(event)["contains"](. domRef)
115
+ if !isInDropdown {
116
+ toggle()
117
+ }
118
+ }
119
+ }
120
+ }}
121
+ className={cx([buttonClassName, "dropdown-button"])}>
122
+ label
123
+ {isOpen
124
+ ? <ReachUi.Portal>
125
+ <div
126
+ ref={ReactDOM.Ref.domRef(dropdownRef)}
127
+ className={cx([
128
+ "dropdown",
129
+ "top-0 left-0 p-2 transform transition-opacity duration-150 ease-in-out shadow rounded text-base font-normal text-neutral-700",
130
+ isXs ? "fixed !w-full !h-full z-40" : "absolute z-20 bg-white w-60 opacity-0",
131
+ dropdownClassName,
132
+ ])}
133
+ style={adjustmentStyle->Option.getWithDefault(ReactDOM.Style.make())}>
134
+ {isXs
135
+ ? <div
136
+ className="bg-neutral-500 absolute left-0 top-0 w-full h-full opacity-50 z-30"
137
+ />
138
+ : React.null}
139
+ <div className={cx([isXs ? "z-40 absolute left-0 bottom-0 w-full" : ""])}>
140
+ <div
141
+ className={cx([
142
+ "flex flex-col",
143
+ isXs ? "bg-white p-2 mx-2 shadow rounded-t-lg" : "",
144
+ ])}>
145
+ {items
146
+ ->Array.mapWithIndex((i, {icon, label, onClick, className}) => {
147
+ <div
148
+ onClick={_ => onClick()}
149
+ className={cx([
150
+ "flex flex-row gap-4 items-center py-2 hover:bg-neutral-100 focus:bg-neutral-100 cursor-pointer",
151
+ i == 0 ? "" : "border-t",
152
+ className,
153
+ ])}
154
+ key={i->Int.toString}>
155
+ {icon} {label}
156
+ </div>
157
+ })
158
+ ->React.array}
159
+ </div>
160
+ </div>
161
+ </div>
162
+ </ReachUi.Portal>
163
+ : React.null}
164
+ </Toolkit__Ui_Button>
165
+ </div>
166
+ }
@@ -0,0 +1,25 @@
1
+ type position = [
2
+ | #bottom
3
+ | #top
4
+ ]
5
+
6
+ type item = {
7
+ icon: React.element,
8
+ label: React.element,
9
+ onClick: unit => unit,
10
+ className: string,
11
+ }
12
+
13
+ @react.component
14
+ let make: (
15
+ ~label: React.element,
16
+ ~dropdownClassName: string=?,
17
+ ~buttonClassName: string=?,
18
+ ~containerClassName: string=?,
19
+ ~defaultIsOpen: bool=?,
20
+ ~buttonColor: Toolkit__Ui_Button.color=?,
21
+ ~buttonSize: Toolkit__Ui_Button.size=?,
22
+ ~buttonVariant: Toolkit__Ui_Button.variant=?,
23
+ ~position: position=?,
24
+ ~items: array<item>,
25
+ ) => React.element
@@ -94,6 +94,7 @@ external makeColumn: (
94
94
  ~id: string,
95
95
  ~header: React.element,
96
96
  ~filterRender: filterProps<'filterValue> => React.element=?,
97
+ ~filter: string=?,
97
98
  ~cell: cellProps<'cellValue> => React.element=?,
98
99
  ~minWidth: int=?,
99
100
  ~width: int=?,