@majoo-ui/react 2.1.3 → 2.2.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.
@@ -47,9 +47,7 @@ const slideLeftAndFade = keyframes({
47
47
  transform: 'translateX(0)'
48
48
  }
49
49
  });
50
- const StyledContent = styled(DropdownMenuPrimitive.Content, {
51
- width: 143,
52
- maxWidth: 243,
50
+ const contentStyles = {
53
51
  backgroundColor: '$bgWhite',
54
52
  borderRadius: 4,
55
53
  padding: 8,
@@ -75,6 +73,19 @@ const StyledContent = styled(DropdownMenuPrimitive.Content, {
75
73
  }
76
74
  }
77
75
  }
76
+ };
77
+ const StyledContent = styled(DropdownMenuPrimitive.Content, {
78
+ width: 143,
79
+ maxWidth: 243,
80
+ ...contentStyles
81
+ });
82
+
83
+ // Submenus size to their own content instead of inheriting the trigger-sized width above.
84
+ const StyledSubContent = styled(DropdownMenuPrimitive.SubContent, {
85
+ width: 'max-content',
86
+ minWidth: 180,
87
+ maxWidth: 320,
88
+ ...contentStyles
78
89
  });
79
90
  const itemStyles = {
80
91
  all: 'unset',
@@ -97,24 +108,105 @@ const itemStyles = {
97
108
  '&:active': {
98
109
  backgroundColor: '$gray150'
99
110
  },
100
- '&:focus': {
111
+ // Radix moves focus to the highlighted item, but data-highlighted is the attribute it
112
+ // guarantees — keep both so hover and keyboard land on the same style.
113
+ '&:focus, &[data-highlighted]': {
101
114
  backgroundColor: '$gray100'
102
115
  }
103
116
  };
117
+ const selectedItemStyles = {
118
+ backgroundColor: '$bgSelectedLight',
119
+ color: '$textBrand',
120
+ fontWeight: 600
121
+ };
122
+
123
+ // Space reserved for the indicator drawn in the item's left gutter.
124
+ const INDICATOR_GUTTER = 28;
104
125
  const StyledItem = styled(DropdownMenuPrimitive.Item, {
105
- ...itemStyles
126
+ ...itemStyles,
127
+ variants: {
128
+ selected: {
129
+ true: selectedItemStyles
130
+ }
131
+ }
106
132
  });
107
133
  StyledItem.propTypes = {
108
134
  asChild: PropTypes.bool,
109
135
  disabled: PropTypes.bool,
110
- onSelect: PropTypes.func
136
+ onSelect: PropTypes.func,
137
+ selected: PropTypes.bool
111
138
  };
112
139
  const StyledCheckboxItem = styled(DropdownMenuPrimitive.CheckboxItem, {
113
- ...itemStyles
140
+ ...itemStyles,
141
+ paddingLeft: INDICATOR_GUTTER,
142
+ '&[data-state="checked"]': {
143
+ color: '$textPrimary',
144
+ fontWeight: 600
145
+ }
114
146
  });
147
+
148
+ // The ring and dot are drawn here rather than in ItemIndicator because Radix only mounts
149
+ // ItemIndicator while checked — the unchecked ring has to come from the item itself.
115
150
  const StyledRadioItem = styled(DropdownMenuPrimitive.RadioItem, {
116
- ...itemStyles
151
+ ...itemStyles,
152
+ paddingLeft: INDICATOR_GUTTER,
153
+ '&::before': {
154
+ content: '',
155
+ position: 'absolute',
156
+ left: 0,
157
+ top: '50%',
158
+ boxSizing: 'border-box',
159
+ width: 18,
160
+ height: 18,
161
+ borderRadius: '50%',
162
+ border: '1.5px solid $colors$formDefault',
163
+ transform: 'translateY(-50%)',
164
+ transition: 'border-color 120ms ease'
165
+ },
166
+ '&::after': {
167
+ content: '',
168
+ position: 'absolute',
169
+ left: 5,
170
+ top: '50%',
171
+ width: 8,
172
+ height: 8,
173
+ borderRadius: '50%',
174
+ backgroundColor: '$iconBrand',
175
+ transform: 'translateY(-50%) scale(0)',
176
+ transition: 'transform 120ms ease'
177
+ },
178
+ '&[data-state="checked"]': {
179
+ color: '$textPrimary',
180
+ fontWeight: 600,
181
+ '&::before': {
182
+ borderColor: '$formActive'
183
+ },
184
+ '&::after': {
185
+ transform: 'translateY(-50%) scale(1)'
186
+ }
187
+ },
188
+ '&[data-disabled]': {
189
+ '&::before': {
190
+ borderColor: '$formDisable'
191
+ },
192
+ '&::after': {
193
+ backgroundColor: '$iconDisable'
194
+ }
195
+ }
196
+ });
197
+ const StyledSubTrigger = styled(DropdownMenuPrimitive.SubTrigger, {
198
+ ...itemStyles,
199
+ '&[data-state="open"]': selectedItemStyles,
200
+ variants: {
201
+ selected: {
202
+ true: selectedItemStyles
203
+ }
204
+ }
117
205
  });
206
+ StyledSubTrigger.propTypes = {
207
+ disabled: PropTypes.bool,
208
+ selected: PropTypes.bool
209
+ };
118
210
  const StyledLabel = styled(DropdownMenuPrimitive.Label, {
119
211
  padding: '8px 0',
120
212
  fontSize: 12,
@@ -129,7 +221,10 @@ const StyledSeparator = styled(DropdownMenuPrimitive.Separator, {
129
221
  const StyledItemIndicator = styled(DropdownMenuPrimitive.ItemIndicator, {
130
222
  position: 'absolute',
131
223
  left: 0,
132
- width: 25,
224
+ top: '50%',
225
+ width: 18,
226
+ height: 18,
227
+ transform: 'translateY(-50%)',
133
228
  display: 'inline-flex',
134
229
  alignItems: 'center',
135
230
  justifyContent: 'center'
@@ -159,7 +254,7 @@ DropdownMenuContext.propTypes = {
159
254
  align: PropTypes.oneOf(['start', 'center', 'end'])
160
255
  };
161
256
  const DropdownMenuContentContext = ({
162
- theme,
257
+ theme = 'default',
163
258
  ...props
164
259
  }) => {
165
260
  const {
@@ -191,21 +286,43 @@ DropdownMenuContentContext.propTypes = {
191
286
  alignOffset: PropTypes.number,
192
287
  asChild: PropTypes.bool
193
288
  };
194
- const DropdownTrigger = /*#__PURE__*/React__default.forwardRef(({
289
+
290
+ // Radix positions submenus itself, so this only carries the theme class across the portal.
291
+ const DropdownMenuSubContentContext = ({
292
+ theme = 'default',
195
293
  children,
196
294
  ...props
295
+ }) => {
296
+ const themeProvider = useThemeProvider(theme);
297
+ return /*#__PURE__*/jsx(StyledSubContent, {
298
+ className: `dropdown-content ${themeProvider?.theme || ''}`,
299
+ ...props,
300
+ children: children
301
+ });
302
+ };
303
+ DropdownMenuSubContentContext.propTypes = {
304
+ sideOffset: PropTypes.number,
305
+ alignOffset: PropTypes.number,
306
+ asChild: PropTypes.bool
307
+ };
308
+
309
+ /**
310
+ * @type {React.ForwardRefExoticComponent<
311
+ * React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger> & React.RefAttributes<HTMLButtonElement>
312
+ * >}
313
+ */
314
+ const DropdownTrigger = /*#__PURE__*/React__default.forwardRef(({
315
+ children,
316
+ asChild,
317
+ ...rest
197
318
  }, ref) => {
198
- const {
199
- asChild,
200
- ...rest
201
- } = props;
202
319
  return /*#__PURE__*/jsx(DropdownMenuPrimitive.Trigger, {
203
320
  ...rest,
204
321
  asChild: asChild,
205
322
  ref: ref,
206
- children: children && /*#__PURE__*/React__default.cloneElement(children, {
323
+ children: /*#__PURE__*/React__default.isValidElement(children) ? /*#__PURE__*/React__default.cloneElement(children, {
207
324
  ...rest
208
- })
325
+ }) : children
209
326
  });
210
327
  });
211
328
  DropdownTrigger.propTypes = {
@@ -213,11 +330,20 @@ DropdownTrigger.propTypes = {
213
330
  };
214
331
  const RightSlot = styled('div', {
215
332
  marginLeft: 'auto',
216
- ':focus > &': {
217
- color: 'white'
218
- },
333
+ paddingLeft: 16,
334
+ display: 'inline-flex',
335
+ alignItems: 'center',
219
336
  '[data-disabled] &': {
220
337
  color: '$gray400'
338
+ },
339
+ variants: {
340
+ // Secondary text (a hint or shortcut) rather than an icon.
341
+ muted: {
342
+ true: {
343
+ color: '$textDisable',
344
+ fontSize: 12
345
+ }
346
+ }
221
347
  }
222
348
  });
223
349
  const StyledDropdown = styled(Button, {
@@ -261,7 +387,9 @@ const DropdownMenuCheckboxItem = StyledCheckboxItem;
261
387
  const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
262
388
  const DropdownMenuRadioItem = StyledRadioItem;
263
389
  const DropdownMenuItemIndicator = StyledItemIndicator;
264
- // export const DropdownMenuTriggerItem = StyledTriggerItem;
390
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
391
+ const DropdownMenuSubTrigger = StyledSubTrigger;
392
+ const DropdownMenuSubContent = DropdownMenuSubContentContext;
265
393
  const DropdownMenuLabel = StyledLabel;
266
394
  const DropdownMenuSeparator = StyledSeparator;
267
395
  const DropdownMenuArrow = StyledArrow;
@@ -273,9 +401,11 @@ DropdownMenuCheckboxItem.displayName = 'DropdownMenuCheckboxItem';
273
401
  DropdownMenuRadioGroup.displayName = 'DropdownMenuRadioGroup';
274
402
  DropdownMenuRadioItem.displayName = 'DropdownMenuRadioItem';
275
403
  DropdownMenuItemIndicator.displayName = 'DropdownMenuItemIndicator';
276
- // DropdownMenuTriggerItem.displayName = 'DropdownMenuTriggerItem';
404
+ DropdownMenuSub.displayName = 'DropdownMenuSub';
405
+ DropdownMenuSubTrigger.displayName = 'DropdownMenuSubTrigger';
406
+ DropdownMenuSubContent.displayName = 'DropdownMenuSubContent';
277
407
  DropdownMenuLabel.displayName = 'DropdownMenuLabel';
278
408
  DropdownMenuSeparator.displayName = 'DropdownMenuSeparator';
279
409
  DropdownMenuArrow.displayName = 'DropdownMenuArrow';
280
410
 
281
- export { ButtonDropdown, DropdownMenu, DropdownMenuArrow, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemIndicator, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, RightSlot, StyledDropdown };
411
+ export { ButtonDropdown, DropdownMenu, DropdownMenuArrow, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemIndicator, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, RightSlot, StyledDropdown };
@@ -0,0 +1,212 @@
1
+ import 'core-js/modules/es.iterator.constructor.js';
2
+ import 'core-js/modules/es.iterator.map.js';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+ import React__default, { useState } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { CaretDownOutline, ChevronRightOutline } from '@majoo-ui/icons';
7
+ import { styled, colors } from '../../config/stitches.config.esm.js';
8
+ import { weekdayNamesFullEng, weekdayNamesFullId } from '../../utils/calendar.esm.js';
9
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSub, DropdownMenuSubTrigger, RightSlot, DropdownMenuSubContent, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem } from '../dropdownMenu/DropdownMenu.esm.js';
10
+
11
+ const Trigger = styled('button', {
12
+ all: 'unset',
13
+ boxSizing: 'border-box',
14
+ display: 'inline-flex',
15
+ alignItems: 'center',
16
+ gap: '$spacing-02',
17
+ padding: '0 $spacing-04',
18
+ border: '1px solid $bgOutline',
19
+ borderRadius: '$lg',
20
+ backgroundColor: '$bgWhite',
21
+ color: '$textPrimary',
22
+ fontFamily: 'inherit',
23
+ fontSize: '$short-content-regular',
24
+ lineHeight: '$short-content-regular',
25
+ letterSpacing: '$short-content-regular',
26
+ cursor: 'pointer',
27
+ '&:hover': {
28
+ borderColor: '$primary600'
29
+ },
30
+ '&[data-state="open"]': {
31
+ borderColor: '$primary400'
32
+ },
33
+ variants: {
34
+ size: {
35
+ sm: {
36
+ height: 32
37
+ },
38
+ lg: {
39
+ height: 40
40
+ }
41
+ },
42
+ // Named apart from the DOM attribute so Stitches does not swallow it as a variant —
43
+ // the button still needs a real `disabled` to block the menu from opening.
44
+ isDisabled: {
45
+ true: {
46
+ backgroundColor: '$formDisable',
47
+ color: '$textDisable',
48
+ cursor: 'not-allowed',
49
+ '&:hover': {
50
+ borderColor: '$bgOutline'
51
+ }
52
+ }
53
+ }
54
+ },
55
+ defaultVariants: {
56
+ size: 'lg'
57
+ }
58
+ });
59
+ const TriggerLabel = styled('span', {
60
+ fontWeight: 600
61
+ });
62
+ const TriggerRange = styled('span', {
63
+ color: '$textDisable'
64
+ });
65
+ const MENU_ITEM_CSS = {
66
+ paddingLeft: '$spacing-04',
67
+ paddingRight: '$spacing-04'
68
+ };
69
+ const DEFAULT_PERIODS = ['day', 'week', 'month'];
70
+ // Listed Monday first, the way the week reads in Indonesian — not in Date#getDay order.
71
+ const START_DAY_ORDER = [1, 2, 3, 4, 5, 6, 0];
72
+ const PeriodSelect = /*#__PURE__*/React__default.forwardRef(({
73
+ value,
74
+ onChange,
75
+ startDay,
76
+ onStartDayChange,
77
+ defaultStartDay = 1,
78
+ resetStartDayOnPeriodChange = true,
79
+ periods = DEFAULT_PERIODS,
80
+ showRange = true,
81
+ disabled = false,
82
+ size = 'lg',
83
+ side = 'bottom',
84
+ align = 'start',
85
+ periodLabels,
86
+ startWeekLabel,
87
+ formatWeekRange,
88
+ css
89
+ }, ref) => {
90
+ const {
91
+ t,
92
+ i18n: {
93
+ language
94
+ }
95
+ } = useTranslation(['MajooUI/periodSelect', 'translation']);
96
+ const [open, setOpen] = useState(false);
97
+ const [internalStartDay, setInternalStartDay] = useState(defaultStartDay);
98
+ const activeStartDay = startDay !== null && startDay !== void 0 ? startDay : internalStartDay;
99
+ const weekdayNames = language === 'en' ? weekdayNamesFullEng : weekdayNamesFullId;
100
+ // A week always spans 7 days, so the last one is always 6 days after the first.
101
+ const rangeLabel = (day, place) => {
102
+ const endDay = (day + 6) % 7;
103
+ const range = {
104
+ startDay: day,
105
+ endDay,
106
+ startName: weekdayNames[day],
107
+ endName: weekdayNames[endDay],
108
+ place
109
+ };
110
+ return formatWeekRange ? formatWeekRange(range) : `${range.startName} - ${range.endName}`;
111
+ };
112
+ const showWeekRange = showRange && value === 'week';
113
+ const defaultPeriodLabels = {
114
+ day: t('day', 'Hari'),
115
+ week: t('week', 'Minggu'),
116
+ month: t('month', 'Bulan')
117
+ };
118
+ const periodLabel = period => {
119
+ var _a;
120
+ return (_a = periodLabels === null || periodLabels === void 0 ? void 0 : periodLabels[period]) !== null && _a !== void 0 ? _a : defaultPeriodLabels[period];
121
+ };
122
+ const applyStartDay = day => {
123
+ setInternalStartDay(day);
124
+ onStartDayChange === null || onStartDayChange === void 0 ? void 0 : onStartDayChange(day);
125
+ };
126
+ const selectPeriod = period => {
127
+ onChange(period);
128
+ if (resetStartDayOnPeriodChange && period !== 'week' && activeStartDay !== defaultStartDay) {
129
+ applyStartDay(defaultStartDay);
130
+ }
131
+ setOpen(false);
132
+ };
133
+ const renderPeriodItem = period => {
134
+ if (period !== 'week') {
135
+ return jsx(DropdownMenuItem, {
136
+ selected: value === period,
137
+ onSelect: () => selectPeriod(period),
138
+ css: MENU_ITEM_CSS,
139
+ children: periodLabel(period)
140
+ }, period);
141
+ }
142
+ return jsxs(DropdownMenuSub, {
143
+ children: [jsxs(DropdownMenuSubTrigger, {
144
+ selected: value === 'week',
145
+ onClick: () => selectPeriod('week'),
146
+ css: MENU_ITEM_CSS,
147
+ children: [periodLabel('week'), jsx(RightSlot, {
148
+ children: jsx(ChevronRightOutline, {
149
+ size: "16",
150
+ color: "currentColor"
151
+ })
152
+ })]
153
+ }), jsxs(DropdownMenuSubContent, {
154
+ sideOffset: 8,
155
+ alignOffset: -8,
156
+ css: {
157
+ padding: '$spacing-04 $spacing-05'
158
+ },
159
+ children: [jsx(DropdownMenuLabel, {
160
+ children: startWeekLabel !== null && startWeekLabel !== void 0 ? startWeekLabel : t('startWeekFrom', 'Mulai minggu dari:')
161
+ }), jsx(DropdownMenuRadioGroup, {
162
+ value: String(activeStartDay),
163
+ onValueChange: day => {
164
+ applyStartDay(Number(day));
165
+ onChange('week');
166
+ },
167
+ children: START_DAY_ORDER.map(day => jsx(DropdownMenuRadioItem, {
168
+ value: String(day),
169
+ children: rangeLabel(day, 'option')
170
+ }, day))
171
+ })]
172
+ })]
173
+ }, period);
174
+ };
175
+ return jsxs(DropdownMenu, {
176
+ open: open,
177
+ onOpenChange: setOpen,
178
+ side: side,
179
+ align: align,
180
+ modal: false,
181
+ children: [jsx(DropdownMenuTrigger, {
182
+ asChild: true,
183
+ children: jsxs(Trigger, {
184
+ ref: ref,
185
+ size: size,
186
+ isDisabled: disabled,
187
+ disabled: disabled,
188
+ css: css,
189
+ type: "button",
190
+ children: [jsxs(TriggerLabel, {
191
+ children: [periodLabel(value), showWeekRange && ',']
192
+ }), showWeekRange && jsx(TriggerRange, {
193
+ children: rangeLabel(activeStartDay, 'trigger')
194
+ }), jsx(CaretDownOutline, {
195
+ size: "16",
196
+ color: disabled ? colors.iconDisable : colors.iconPrimary
197
+ })]
198
+ })
199
+ }), jsx(DropdownMenuContent, {
200
+ sideOffset: 4,
201
+ css: {
202
+ width: 'max-content',
203
+ minWidth: 160,
204
+ maxWidth: 'none'
205
+ },
206
+ children: periods.map(renderPeriodItem)
207
+ })]
208
+ });
209
+ });
210
+ PeriodSelect.displayName = 'PeriodSelect';
211
+
212
+ export { PeriodSelect as default };
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.0",
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';
@@ -6,6 +6,10 @@ const monthNamesFullId = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni'
6
6
  const monthNamesFullEng = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
7
7
  const weekdayNamesShortId = ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'];
8
8
  const weekdayNamesShortEng = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
9
+
10
+ // Indexed like Date#getDay: 0 = Sunday.
11
+ const weekdayNamesFullId = ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu'];
12
+ const weekdayNamesFullEng = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
9
13
  const yearRangesList = rangeStart => {
10
14
  let start = rangeStart;
11
15
  let end = start + 9;
@@ -23,4 +27,4 @@ const getCalendarStartYear = year => year - year % 10 + 1;
23
27
  const getCalendarStartYearRange = year => year - year % 100 + 1;
24
28
  const toDateFormat = (date, locale = 'id') => moment(date).locale(locale).format('DD MMMM YYYY');
25
29
 
26
- export { getCalendarStartYear, getCalendarStartYearRange, monthNamesFullEng, monthNamesFullId, toDateFormat, weekdayNamesShortEng, weekdayNamesShortId, yearRangesList };
30
+ export { getCalendarStartYear, getCalendarStartYearRange, monthNamesFullEng, monthNamesFullId, toDateFormat, weekdayNamesFullEng, weekdayNamesFullId, weekdayNamesShortEng, weekdayNamesShortId, yearRangesList };