@majoo-ui/react 2.1.3 → 2.2.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.
@@ -1,9 +1,10 @@
1
- import { useFloating, offset, shift, flip, useInteractions, useClick, useDismiss, FloatingFocusManager, FloatingPortal } from '@floating-ui/react';
1
+ import { useFloating, autoUpdate, useInteractions, useClick, useDismiss, FloatingFocusManager, FloatingPortal } from '@floating-ui/react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useState, useEffect, useContext, cloneElement, createContext } from 'react';
4
4
  import Flex from '../../layout/flex/Flex.esm.js';
5
5
  import { foundations } from '@majoo-ui/core';
6
6
  import { ConditionalWrapper } from '../../wrapper/ConditionalWrapper.esm.js';
7
+ import { createPopoverMiddleware } from './middleware.esm.js';
7
8
  import { jsx, Fragment } from 'react/jsx-runtime';
8
9
 
9
10
  const {
@@ -17,7 +18,7 @@ const Popover = ({
17
18
  placement,
18
19
  sideOffset = 5,
19
20
  hideOnScroll = false,
20
- flip: flip$1 = true,
21
+ flip = true,
21
22
  onClose
22
23
  }) => {
23
24
  const [openState, setOpenState] = useState(false);
@@ -27,9 +28,17 @@ const Popover = ({
27
28
  useEffect(() => {
28
29
  if (onOpenChange) onOpenChange(openState);
29
30
  }, [openState, onOpenChange]);
31
+
32
+ // floating-ui measures the element PopoverContent renders, so its children must
33
+ // be in-flow (see createPopoverMiddleware). autoUpdate recomputes when content
34
+ // height changes after mount (async options, a menu toggling display).
30
35
  const floatingHook = useFloating({
31
36
  open: openState,
32
- middleware: [offset(sideOffset), shift(), flip$1 && flip()],
37
+ whileElementsMounted: autoUpdate,
38
+ middleware: createPopoverMiddleware({
39
+ sideOffset,
40
+ flip
41
+ }),
33
42
  onOpenChange: isOpen => {
34
43
  setOpenState(isOpen);
35
44
  !isOpen && onClose?.();
@@ -0,0 +1,43 @@
1
+ import { offset, flip, shift, size } from '@floating-ui/react';
2
+
3
+ /**
4
+ * The floating-ui middleware every majoo-ui dropdown shares, so Popover and the
5
+ * components that drive floating-ui themselves (InputSelectCheck) place content
6
+ * the same way.
7
+ *
8
+ * - `flip` treats `placement` as a preference: the other side is used when the
9
+ * preferred one lacks room.
10
+ * - `size` writes two CSS variables on the floating element, which consumers opt
11
+ * into: `--majoo-popover-available-height` (room left on the chosen side) and
12
+ * `--majoo-popover-reference-width` (width of the trigger).
13
+ *
14
+ * floating-ui measures the floating element itself, so its content must be
15
+ * in-flow — an all-absolute child measures 0px and flip/shift never fire.
16
+ */
17
+ // Floor for the reported available height. Without it, flip and size lock each
18
+ // other: a menu that opens while still `display: none` measures 0px, flip keeps a
19
+ // side with almost no room, size reports ~0px, the menu's max-height collapses to
20
+ // 0 and never changes size again — so autoUpdate never re-runs flip. With a floor
21
+ // the box always has real height, flip moves it to the roomier side, and size then
22
+ // grows it from there.
23
+ const MIN_AVAILABLE_HEIGHT = 120;
24
+ const createPopoverMiddleware = ({
25
+ sideOffset = 5,
26
+ flip: flip$1 = true
27
+ } = {}) => [offset(sideOffset), flip$1 && flip({
28
+ padding: 8
29
+ }), shift({
30
+ padding: 8
31
+ }), size({
32
+ padding: 8,
33
+ apply({
34
+ availableHeight,
35
+ rects,
36
+ elements
37
+ }) {
38
+ elements.floating.style.setProperty('--majoo-popover-available-height', `${Math.max(MIN_AVAILABLE_HEIGHT, availableHeight)}px`);
39
+ elements.floating.style.setProperty('--majoo-popover-reference-width', `${rects.reference.width}px`);
40
+ }
41
+ })].filter(Boolean);
42
+
43
+ export { createPopoverMiddleware };
package/index.esm.css CHANGED
@@ -2,6 +2,251 @@
2
2
  outline: none;
3
3
  }
4
4
 
5
+ .ReactCrop {
6
+ position: relative;
7
+ display: inline-block;
8
+ cursor: crosshair;
9
+ overflow: hidden;
10
+ max-width: 100%;
11
+ }
12
+ .ReactCrop *,
13
+ .ReactCrop *::before,
14
+ .ReactCrop *::after {
15
+ box-sizing: border-box;
16
+ }
17
+ .ReactCrop--disabled,
18
+ .ReactCrop--locked {
19
+ cursor: inherit;
20
+ }
21
+ .ReactCrop__child-wrapper {
22
+ max-height: inherit;
23
+ }
24
+ .ReactCrop__child-wrapper > img,
25
+ .ReactCrop__child-wrapper > video {
26
+ display: block;
27
+ max-width: 100%;
28
+ max-height: inherit;
29
+ touch-action: none;
30
+ }
31
+ .ReactCrop__crop-selection {
32
+ position: absolute;
33
+ top: 0;
34
+ left: 0;
35
+ transform: translate3d(0, 0, 0);
36
+ cursor: move;
37
+ box-shadow: 0 0 0 9999em rgba(0, 0, 0, 0.5);
38
+ touch-action: none;
39
+ border: 1px dashed #fff;
40
+ }
41
+ .ReactCrop--disabled .ReactCrop__crop-selection {
42
+ cursor: inherit;
43
+ }
44
+ .ReactCrop--circular-crop .ReactCrop__crop-selection {
45
+ border-radius: 50%;
46
+ box-shadow: 0px 0px 1px 1px #fff, 0 0 0 9999em rgba(0, 0, 0, 0.5);
47
+ }
48
+ .ReactCrop__crop-selection:focus {
49
+ outline: none;
50
+ border-color: blue;
51
+ border-style: solid;
52
+ }
53
+ .ReactCrop--invisible-crop .ReactCrop__crop-selection {
54
+ display: none;
55
+ }
56
+ .ReactCrop__rule-of-thirds-vt::before,
57
+ .ReactCrop__rule-of-thirds-vt::after,
58
+ .ReactCrop__rule-of-thirds-hz::before,
59
+ .ReactCrop__rule-of-thirds-hz::after {
60
+ content: '';
61
+ display: block;
62
+ position: absolute;
63
+ background-color: rgba(255, 255, 255, 0.4);
64
+ }
65
+ .ReactCrop__rule-of-thirds-vt::before,
66
+ .ReactCrop__rule-of-thirds-vt::after {
67
+ width: 1px;
68
+ height: 100%;
69
+ }
70
+ .ReactCrop__rule-of-thirds-vt::before {
71
+ left: 33.3333%;
72
+ left: 33.3333333333%;
73
+ }
74
+ .ReactCrop__rule-of-thirds-vt::after {
75
+ left: 66.6666%;
76
+ left: 66.6666666667%;
77
+ }
78
+ .ReactCrop__rule-of-thirds-hz::before,
79
+ .ReactCrop__rule-of-thirds-hz::after {
80
+ width: 100%;
81
+ height: 1px;
82
+ }
83
+ .ReactCrop__rule-of-thirds-hz::before {
84
+ top: 33.3333%;
85
+ top: 33.3333333333%;
86
+ }
87
+ .ReactCrop__rule-of-thirds-hz::after {
88
+ top: 66.6666%;
89
+ top: 66.6666666667%;
90
+ }
91
+ .ReactCrop__drag-handle {
92
+ position: absolute;
93
+ }
94
+ .ReactCrop__drag-handle::after {
95
+ position: absolute;
96
+ content: '';
97
+ display: block;
98
+ width: 10px;
99
+ height: 10px;
100
+ background-color: rgba(0, 0, 0, 0.2);
101
+ border: 1px solid rgba(255, 255, 255, 0.7);
102
+ outline: 1px solid rgba(0, 0, 0, 0);
103
+ }
104
+ .ReactCrop__drag-handle:focus::after {
105
+ border-color: blue;
106
+ background: #2dbfff;
107
+ }
108
+ .ReactCrop .ord-nw {
109
+ top: 0;
110
+ left: 0;
111
+ margin-top: -5px;
112
+ margin-left: -5px;
113
+ cursor: nw-resize;
114
+ }
115
+ .ReactCrop .ord-nw::after {
116
+ top: 0;
117
+ left: 0;
118
+ }
119
+ .ReactCrop .ord-n {
120
+ top: 0;
121
+ left: 50%;
122
+ margin-top: -5px;
123
+ margin-left: -5px;
124
+ cursor: n-resize;
125
+ }
126
+ .ReactCrop .ord-n::after {
127
+ top: 0;
128
+ }
129
+ .ReactCrop .ord-ne {
130
+ top: 0;
131
+ right: 0;
132
+ margin-top: -5px;
133
+ margin-right: -5px;
134
+ cursor: ne-resize;
135
+ }
136
+ .ReactCrop .ord-ne::after {
137
+ top: 0;
138
+ right: 0;
139
+ }
140
+ .ReactCrop .ord-e {
141
+ top: 50%;
142
+ right: 0;
143
+ margin-top: -5px;
144
+ margin-right: -5px;
145
+ cursor: e-resize;
146
+ }
147
+ .ReactCrop .ord-e::after {
148
+ right: 0;
149
+ }
150
+ .ReactCrop .ord-se {
151
+ bottom: 0;
152
+ right: 0;
153
+ margin-bottom: -5px;
154
+ margin-right: -5px;
155
+ cursor: se-resize;
156
+ }
157
+ .ReactCrop .ord-se::after {
158
+ bottom: 0;
159
+ right: 0;
160
+ }
161
+ .ReactCrop .ord-s {
162
+ bottom: 0;
163
+ left: 50%;
164
+ margin-bottom: -5px;
165
+ margin-left: -5px;
166
+ cursor: s-resize;
167
+ }
168
+ .ReactCrop .ord-s::after {
169
+ bottom: 0;
170
+ }
171
+ .ReactCrop .ord-sw {
172
+ bottom: 0;
173
+ left: 0;
174
+ margin-bottom: -5px;
175
+ margin-left: -5px;
176
+ cursor: sw-resize;
177
+ }
178
+ .ReactCrop .ord-sw::after {
179
+ bottom: 0;
180
+ left: 0;
181
+ }
182
+ .ReactCrop .ord-w {
183
+ top: 50%;
184
+ left: 0;
185
+ margin-top: -5px;
186
+ margin-left: -5px;
187
+ cursor: w-resize;
188
+ }
189
+ .ReactCrop .ord-w::after {
190
+ left: 0;
191
+ }
192
+ .ReactCrop__disabled .ReactCrop__drag-handle {
193
+ cursor: inherit;
194
+ }
195
+ .ReactCrop__drag-bar {
196
+ position: absolute;
197
+ }
198
+ .ReactCrop__drag-bar.ord-n {
199
+ top: 0;
200
+ left: 0;
201
+ width: 100%;
202
+ height: 6px;
203
+ margin-top: -3px;
204
+ }
205
+ .ReactCrop__drag-bar.ord-e {
206
+ right: 0;
207
+ top: 0;
208
+ width: 6px;
209
+ height: 100%;
210
+ margin-right: -3px;
211
+ }
212
+ .ReactCrop__drag-bar.ord-s {
213
+ bottom: 0;
214
+ left: 0;
215
+ width: 100%;
216
+ height: 6px;
217
+ margin-bottom: -3px;
218
+ }
219
+ .ReactCrop__drag-bar.ord-w {
220
+ top: 0;
221
+ left: 0;
222
+ width: 6px;
223
+ height: 100%;
224
+ margin-left: -3px;
225
+ }
226
+ .ReactCrop--new-crop .ReactCrop__drag-bar,
227
+ .ReactCrop--new-crop .ReactCrop__drag-handle,
228
+ .ReactCrop--fixed-aspect .ReactCrop__drag-bar {
229
+ display: none;
230
+ }
231
+ .ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-n,
232
+ .ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-e,
233
+ .ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-s,
234
+ .ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-w {
235
+ display: none;
236
+ }
237
+ @media (pointer: coarse) {
238
+ .ReactCrop .ord-n,
239
+ .ReactCrop .ord-e,
240
+ .ReactCrop .ord-s,
241
+ .ReactCrop .ord-w {
242
+ display: none;
243
+ }
244
+ .ReactCrop__drag-handle {
245
+ width: 24px;
246
+ height: 24px;
247
+ }
248
+ }
249
+
5
250
  .rdw-option-wrapper {
6
251
  padding: 5px;
7
252
  min-width: 25px;
@@ -1048,248 +1293,3 @@
1048
1293
  .public-DraftStyleDefault-depth4.public-DraftStyleDefault-reset {
1049
1294
  counter-reset: ol4;
1050
1295
  }
1051
-
1052
- .ReactCrop {
1053
- position: relative;
1054
- display: inline-block;
1055
- cursor: crosshair;
1056
- overflow: hidden;
1057
- max-width: 100%;
1058
- }
1059
- .ReactCrop *,
1060
- .ReactCrop *::before,
1061
- .ReactCrop *::after {
1062
- box-sizing: border-box;
1063
- }
1064
- .ReactCrop--disabled,
1065
- .ReactCrop--locked {
1066
- cursor: inherit;
1067
- }
1068
- .ReactCrop__child-wrapper {
1069
- max-height: inherit;
1070
- }
1071
- .ReactCrop__child-wrapper > img,
1072
- .ReactCrop__child-wrapper > video {
1073
- display: block;
1074
- max-width: 100%;
1075
- max-height: inherit;
1076
- touch-action: none;
1077
- }
1078
- .ReactCrop__crop-selection {
1079
- position: absolute;
1080
- top: 0;
1081
- left: 0;
1082
- transform: translate3d(0, 0, 0);
1083
- cursor: move;
1084
- box-shadow: 0 0 0 9999em rgba(0, 0, 0, 0.5);
1085
- touch-action: none;
1086
- border: 1px dashed #fff;
1087
- }
1088
- .ReactCrop--disabled .ReactCrop__crop-selection {
1089
- cursor: inherit;
1090
- }
1091
- .ReactCrop--circular-crop .ReactCrop__crop-selection {
1092
- border-radius: 50%;
1093
- box-shadow: 0px 0px 1px 1px #fff, 0 0 0 9999em rgba(0, 0, 0, 0.5);
1094
- }
1095
- .ReactCrop__crop-selection:focus {
1096
- outline: none;
1097
- border-color: blue;
1098
- border-style: solid;
1099
- }
1100
- .ReactCrop--invisible-crop .ReactCrop__crop-selection {
1101
- display: none;
1102
- }
1103
- .ReactCrop__rule-of-thirds-vt::before,
1104
- .ReactCrop__rule-of-thirds-vt::after,
1105
- .ReactCrop__rule-of-thirds-hz::before,
1106
- .ReactCrop__rule-of-thirds-hz::after {
1107
- content: '';
1108
- display: block;
1109
- position: absolute;
1110
- background-color: rgba(255, 255, 255, 0.4);
1111
- }
1112
- .ReactCrop__rule-of-thirds-vt::before,
1113
- .ReactCrop__rule-of-thirds-vt::after {
1114
- width: 1px;
1115
- height: 100%;
1116
- }
1117
- .ReactCrop__rule-of-thirds-vt::before {
1118
- left: 33.3333%;
1119
- left: 33.3333333333%;
1120
- }
1121
- .ReactCrop__rule-of-thirds-vt::after {
1122
- left: 66.6666%;
1123
- left: 66.6666666667%;
1124
- }
1125
- .ReactCrop__rule-of-thirds-hz::before,
1126
- .ReactCrop__rule-of-thirds-hz::after {
1127
- width: 100%;
1128
- height: 1px;
1129
- }
1130
- .ReactCrop__rule-of-thirds-hz::before {
1131
- top: 33.3333%;
1132
- top: 33.3333333333%;
1133
- }
1134
- .ReactCrop__rule-of-thirds-hz::after {
1135
- top: 66.6666%;
1136
- top: 66.6666666667%;
1137
- }
1138
- .ReactCrop__drag-handle {
1139
- position: absolute;
1140
- }
1141
- .ReactCrop__drag-handle::after {
1142
- position: absolute;
1143
- content: '';
1144
- display: block;
1145
- width: 10px;
1146
- height: 10px;
1147
- background-color: rgba(0, 0, 0, 0.2);
1148
- border: 1px solid rgba(255, 255, 255, 0.7);
1149
- outline: 1px solid rgba(0, 0, 0, 0);
1150
- }
1151
- .ReactCrop__drag-handle:focus::after {
1152
- border-color: blue;
1153
- background: #2dbfff;
1154
- }
1155
- .ReactCrop .ord-nw {
1156
- top: 0;
1157
- left: 0;
1158
- margin-top: -5px;
1159
- margin-left: -5px;
1160
- cursor: nw-resize;
1161
- }
1162
- .ReactCrop .ord-nw::after {
1163
- top: 0;
1164
- left: 0;
1165
- }
1166
- .ReactCrop .ord-n {
1167
- top: 0;
1168
- left: 50%;
1169
- margin-top: -5px;
1170
- margin-left: -5px;
1171
- cursor: n-resize;
1172
- }
1173
- .ReactCrop .ord-n::after {
1174
- top: 0;
1175
- }
1176
- .ReactCrop .ord-ne {
1177
- top: 0;
1178
- right: 0;
1179
- margin-top: -5px;
1180
- margin-right: -5px;
1181
- cursor: ne-resize;
1182
- }
1183
- .ReactCrop .ord-ne::after {
1184
- top: 0;
1185
- right: 0;
1186
- }
1187
- .ReactCrop .ord-e {
1188
- top: 50%;
1189
- right: 0;
1190
- margin-top: -5px;
1191
- margin-right: -5px;
1192
- cursor: e-resize;
1193
- }
1194
- .ReactCrop .ord-e::after {
1195
- right: 0;
1196
- }
1197
- .ReactCrop .ord-se {
1198
- bottom: 0;
1199
- right: 0;
1200
- margin-bottom: -5px;
1201
- margin-right: -5px;
1202
- cursor: se-resize;
1203
- }
1204
- .ReactCrop .ord-se::after {
1205
- bottom: 0;
1206
- right: 0;
1207
- }
1208
- .ReactCrop .ord-s {
1209
- bottom: 0;
1210
- left: 50%;
1211
- margin-bottom: -5px;
1212
- margin-left: -5px;
1213
- cursor: s-resize;
1214
- }
1215
- .ReactCrop .ord-s::after {
1216
- bottom: 0;
1217
- }
1218
- .ReactCrop .ord-sw {
1219
- bottom: 0;
1220
- left: 0;
1221
- margin-bottom: -5px;
1222
- margin-left: -5px;
1223
- cursor: sw-resize;
1224
- }
1225
- .ReactCrop .ord-sw::after {
1226
- bottom: 0;
1227
- left: 0;
1228
- }
1229
- .ReactCrop .ord-w {
1230
- top: 50%;
1231
- left: 0;
1232
- margin-top: -5px;
1233
- margin-left: -5px;
1234
- cursor: w-resize;
1235
- }
1236
- .ReactCrop .ord-w::after {
1237
- left: 0;
1238
- }
1239
- .ReactCrop__disabled .ReactCrop__drag-handle {
1240
- cursor: inherit;
1241
- }
1242
- .ReactCrop__drag-bar {
1243
- position: absolute;
1244
- }
1245
- .ReactCrop__drag-bar.ord-n {
1246
- top: 0;
1247
- left: 0;
1248
- width: 100%;
1249
- height: 6px;
1250
- margin-top: -3px;
1251
- }
1252
- .ReactCrop__drag-bar.ord-e {
1253
- right: 0;
1254
- top: 0;
1255
- width: 6px;
1256
- height: 100%;
1257
- margin-right: -3px;
1258
- }
1259
- .ReactCrop__drag-bar.ord-s {
1260
- bottom: 0;
1261
- left: 0;
1262
- width: 100%;
1263
- height: 6px;
1264
- margin-bottom: -3px;
1265
- }
1266
- .ReactCrop__drag-bar.ord-w {
1267
- top: 0;
1268
- left: 0;
1269
- width: 6px;
1270
- height: 100%;
1271
- margin-left: -3px;
1272
- }
1273
- .ReactCrop--new-crop .ReactCrop__drag-bar,
1274
- .ReactCrop--new-crop .ReactCrop__drag-handle,
1275
- .ReactCrop--fixed-aspect .ReactCrop__drag-bar {
1276
- display: none;
1277
- }
1278
- .ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-n,
1279
- .ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-e,
1280
- .ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-s,
1281
- .ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-w {
1282
- display: none;
1283
- }
1284
- @media (pointer: coarse) {
1285
- .ReactCrop .ord-n,
1286
- .ReactCrop .ord-e,
1287
- .ReactCrop .ord-s,
1288
- .ReactCrop .ord-w {
1289
- display: none;
1290
- }
1291
- .ReactCrop__drag-handle {
1292
- width: 24px;
1293
- height: 24px;
1294
- }
1295
- }
package/index.esm.js CHANGED
@@ -57,6 +57,7 @@ export { default as Skeleton } from './components/skeleton/Skeleton.esm.js';
57
57
  export { default as TagList } from './components/tagList/TagList.esm.js';
58
58
  export { ScrollSync } from './components/scrollSync/ScrollSync.esm.js';
59
59
  export { ScrollSyncNode } from './components/scrollSync/ScrollSyncNode.esm.js';
60
+ export { default as PeriodSelect } from './components/periodSelect/PeriodSelect.esm.js';
60
61
  export { useListOption } from './hooks/useListOption/useListOption.esm.js';
61
62
  export { useToggle } from './hooks/useToggle/useToggle.esm.js';
62
63
  export { Avatar } from './components/avatar/Avatar.esm.js';
@@ -94,7 +95,7 @@ export { default as Upload } from './components/upload/Upload.esm.js';
94
95
  export { AlertDialog, AlertDialogCancel, AlertDialogConfirm, AlertDialogContent, AlertDialogDescription, AlertDialogFunction, AlertDialogRoot, AlertDialogTitle, AlertDialogTrigger } from './components/alertDialog/AlertDialog.esm.js';
95
96
  export { BOTTOM_LEFT_POSITION, BOTTOM_RIGHT_POSITION, TOP_LEFT_POSITION, TOP_RIGHT_POSITION } from './components/toast/Toast.esm.js';
96
97
  export { BreadcrumbItem } from './components/breadcrumb/Breadcrumb.esm.js';
97
- export { ButtonDropdown, DropdownMenu, DropdownMenuArrow, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemIndicator, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, RightSlot, StyledDropdown } from './components/dropdownMenu/DropdownMenu.esm.js';
98
+ export { ButtonDropdown, DropdownMenu, DropdownMenuArrow, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemIndicator, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, RightSlot, StyledDropdown } from './components/dropdownMenu/DropdownMenu.esm.js';
98
99
  export { ButtonGroup, ButtonGroupItem } from './components/buttonGroup/ButtonGroup.esm.js';
99
100
  export { default as ColorPicker } from './components/colorPicker/ColorPicker.esm.js';
100
101
  export { Drawer, DrawerBody, DrawerClose, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from './components/drawer/Drawer.esm.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@majoo-ui/react",
3
- "version": "2.1.3",
3
+ "version": "2.2.1",
4
4
  "main": "./index.esm.js",
5
5
  "sideEffects": [
6
6
  "*.css",
@@ -46,3 +46,4 @@ export * from './contextMenu';
46
46
  export * from './skeleton';
47
47
  export * from './tagList';
48
48
  export * from './scrollSync';
49
+ export * from './periodSelect';
@@ -0,0 +1,83 @@
1
+ import React from 'react';
2
+ import { CSS } from '../../config/stitches.config';
3
+ export type PeriodValue = 'day' | 'week' | 'month';
4
+ export interface PeriodSelectProps {
5
+ /**
6
+ * The selected period.
7
+ */
8
+ value: PeriodValue;
9
+ /**
10
+ * Called when the user picks a period. Picking a start day also reports `'week'`.
11
+ */
12
+ onChange: (value: PeriodValue) => void;
13
+ /**
14
+ * First day of the week, indexed like `Date#getDay` (0 = Sunday, 1 = Monday).
15
+ * Leave undefined to let the component hold it internally.
16
+ */
17
+ startDay?: number;
18
+ /**
19
+ * Called when the user picks a different first day of the week.
20
+ */
21
+ onStartDayChange?: (startDay: number) => void;
22
+ /**
23
+ * First day of the week before the user changes anything.
24
+ */
25
+ defaultStartDay?: number;
26
+ /**
27
+ * If true, leaving the weekly period reports `defaultStartDay` back through
28
+ * `onStartDayChange`, so returning to weekly starts from the default again.
29
+ */
30
+ resetStartDayOnPeriodChange?: boolean;
31
+ /**
32
+ * Periods offered, in the order they are listed.
33
+ */
34
+ periods?: PeriodValue[];
35
+ /**
36
+ * If false, the trigger shows the period alone, without the day range.
37
+ */
38
+ showRange?: boolean;
39
+ /**
40
+ * If true, the component is disabled.
41
+ */
42
+ disabled?: boolean;
43
+ /**
44
+ * Specify the trigger size.
45
+ */
46
+ size?: 'sm' | 'lg';
47
+ /**
48
+ * The preferred side of the trigger to render the menu against.
49
+ */
50
+ side?: 'top' | 'right' | 'bottom' | 'left';
51
+ /**
52
+ * The preferred alignment against the trigger.
53
+ */
54
+ align?: 'start' | 'center' | 'end';
55
+ /**
56
+ * Replaces the label of one or more periods. Anything left out keeps its default
57
+ * (`Hari`, `Minggu`, `Bulan`), which already goes through i18n.
58
+ */
59
+ periodLabels?: Partial<Record<PeriodValue, React.ReactNode>>;
60
+ /**
61
+ * Replaces the submenu heading above the start-day options.
62
+ */
63
+ startWeekLabel?: React.ReactNode;
64
+ /**
65
+ * Replaces the default `Senin - Minggu` label, both on the trigger and on each option.
66
+ * `place` says which of the two is being rendered, so the two can read differently.
67
+ * Days are indexed like `Date#getDay`.
68
+ */
69
+ formatWeekRange?: (range: WeekRange) => React.ReactNode;
70
+ /**
71
+ * Additional CSS trigger styles.
72
+ */
73
+ css?: CSS;
74
+ }
75
+ export interface WeekRange {
76
+ startDay: number;
77
+ endDay: number;
78
+ startName: string;
79
+ endName: string;
80
+ place: 'trigger' | 'option';
81
+ }
82
+ declare const PeriodSelect: React.ForwardRefExoticComponent<PeriodSelectProps & React.RefAttributes<HTMLButtonElement>>;
83
+ export default PeriodSelect;
@@ -0,0 +1,2 @@
1
+ export { default as PeriodSelect } from './PeriodSelect';
2
+ export * from './PeriodSelect';