@cdx-ui/components 0.0.1-beta.140 → 0.0.1-beta.141
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/lib/commonjs/components/BottomSheet/index.js +8 -2
- package/lib/commonjs/components/BottomSheet/index.js.map +1 -1
- package/lib/commonjs/components/Calendar/CalendarMonthHeader.js +96 -0
- package/lib/commonjs/components/Calendar/CalendarMonthHeader.js.map +1 -0
- package/lib/commonjs/components/Calendar/CalendarYearPickerGrid.js +74 -0
- package/lib/commonjs/components/Calendar/CalendarYearPickerGrid.js.map +1 -0
- package/lib/commonjs/components/Calendar/flashCalendarAdapter.js +298 -0
- package/lib/commonjs/components/Calendar/flashCalendarAdapter.js.map +1 -0
- package/lib/commonjs/components/Calendar/index.js +149 -0
- package/lib/commonjs/components/Calendar/index.js.map +1 -0
- package/lib/commonjs/components/Calendar/styles.js +70 -0
- package/lib/commonjs/components/Calendar/styles.js.map +1 -0
- package/lib/commonjs/components/DateField/index.js +147 -0
- package/lib/commonjs/components/DateField/index.js.map +1 -0
- package/lib/commonjs/components/DateField/styles.js +34 -0
- package/lib/commonjs/components/DateField/styles.js.map +1 -0
- package/lib/commonjs/components/DatePicker/index.js +163 -0
- package/lib/commonjs/components/DatePicker/index.js.map +1 -0
- package/lib/commonjs/components/DateRangePicker/index.js +177 -0
- package/lib/commonjs/components/DateRangePicker/index.js.map +1 -0
- package/lib/commonjs/components/DateTimeField/index.js +96 -0
- package/lib/commonjs/components/DateTimeField/index.js.map +1 -0
- package/lib/commonjs/components/DateTimeList/index.js +180 -0
- package/lib/commonjs/components/DateTimeList/index.js.map +1 -0
- package/lib/commonjs/components/DateTimeList/styles.js +55 -0
- package/lib/commonjs/components/DateTimeList/styles.js.map +1 -0
- package/lib/commonjs/components/DateTimePicker/index.js +187 -0
- package/lib/commonjs/components/DateTimePicker/index.js.map +1 -0
- package/lib/commonjs/components/MonthCalendar/index.js +229 -0
- package/lib/commonjs/components/MonthCalendar/index.js.map +1 -0
- package/lib/commonjs/components/MonthPicker/index.js +163 -0
- package/lib/commonjs/components/MonthPicker/index.js.map +1 -0
- package/lib/commonjs/components/RangeCalendar/index.js +165 -0
- package/lib/commonjs/components/RangeCalendar/index.js.map +1 -0
- package/lib/commonjs/components/index.js +120 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/components/picker/PickerTrigger.js +49 -0
- package/lib/commonjs/components/picker/PickerTrigger.js.map +1 -0
- package/lib/commonjs/components/picker/styles.js +15 -0
- package/lib/commonjs/components/picker/styles.js.map +1 -0
- package/lib/commonjs/components/picker/surfaces.js +141 -0
- package/lib/commonjs/components/picker/surfaces.js.map +1 -0
- package/lib/module/components/BottomSheet/index.js +8 -2
- package/lib/module/components/BottomSheet/index.js.map +1 -1
- package/lib/module/components/Calendar/CalendarMonthHeader.js +92 -0
- package/lib/module/components/Calendar/CalendarMonthHeader.js.map +1 -0
- package/lib/module/components/Calendar/CalendarYearPickerGrid.js +70 -0
- package/lib/module/components/Calendar/CalendarYearPickerGrid.js.map +1 -0
- package/lib/module/components/Calendar/flashCalendarAdapter.js +290 -0
- package/lib/module/components/Calendar/flashCalendarAdapter.js.map +1 -0
- package/lib/module/components/Calendar/index.js +145 -0
- package/lib/module/components/Calendar/index.js.map +1 -0
- package/lib/module/components/Calendar/styles.js +66 -0
- package/lib/module/components/Calendar/styles.js.map +1 -0
- package/lib/module/components/DateField/index.js +143 -0
- package/lib/module/components/DateField/index.js.map +1 -0
- package/lib/module/components/DateField/styles.js +30 -0
- package/lib/module/components/DateField/styles.js.map +1 -0
- package/lib/module/components/DatePicker/index.js +159 -0
- package/lib/module/components/DatePicker/index.js.map +1 -0
- package/lib/module/components/DateRangePicker/index.js +173 -0
- package/lib/module/components/DateRangePicker/index.js.map +1 -0
- package/lib/module/components/DateTimeField/index.js +92 -0
- package/lib/module/components/DateTimeField/index.js.map +1 -0
- package/lib/module/components/DateTimeList/index.js +176 -0
- package/lib/module/components/DateTimeList/index.js.map +1 -0
- package/lib/module/components/DateTimeList/styles.js +52 -0
- package/lib/module/components/DateTimeList/styles.js.map +1 -0
- package/lib/module/components/DateTimePicker/index.js +183 -0
- package/lib/module/components/DateTimePicker/index.js.map +1 -0
- package/lib/module/components/MonthCalendar/index.js +225 -0
- package/lib/module/components/MonthCalendar/index.js.map +1 -0
- package/lib/module/components/MonthPicker/index.js +159 -0
- package/lib/module/components/MonthPicker/index.js.map +1 -0
- package/lib/module/components/RangeCalendar/index.js +161 -0
- package/lib/module/components/RangeCalendar/index.js.map +1 -0
- package/lib/module/components/index.js +10 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/components/picker/PickerTrigger.js +45 -0
- package/lib/module/components/picker/PickerTrigger.js.map +1 -0
- package/lib/module/components/picker/styles.js +12 -0
- package/lib/module/components/picker/styles.js.map +1 -0
- package/lib/module/components/picker/surfaces.js +135 -0
- package/lib/module/components/picker/surfaces.js.map +1 -0
- package/lib/typescript/components/BottomSheet/index.d.ts +2 -2
- package/lib/typescript/components/BottomSheet/index.d.ts.map +1 -1
- package/lib/typescript/components/Calendar/CalendarMonthHeader.d.ts +14 -0
- package/lib/typescript/components/Calendar/CalendarMonthHeader.d.ts.map +1 -0
- package/lib/typescript/components/Calendar/CalendarYearPickerGrid.d.ts +12 -0
- package/lib/typescript/components/Calendar/CalendarYearPickerGrid.d.ts.map +1 -0
- package/lib/typescript/components/Calendar/flashCalendarAdapter.d.ts +18 -0
- package/lib/typescript/components/Calendar/flashCalendarAdapter.d.ts.map +1 -0
- package/lib/typescript/components/Calendar/index.d.ts +19 -0
- package/lib/typescript/components/Calendar/index.d.ts.map +1 -0
- package/lib/typescript/components/Calendar/styles.d.ts +23 -0
- package/lib/typescript/components/Calendar/styles.d.ts.map +1 -0
- package/lib/typescript/components/DateField/index.d.ts +43 -0
- package/lib/typescript/components/DateField/index.d.ts.map +1 -0
- package/lib/typescript/components/DateField/styles.d.ts +15 -0
- package/lib/typescript/components/DateField/styles.d.ts.map +1 -0
- package/lib/typescript/components/DatePicker/index.d.ts +40 -0
- package/lib/typescript/components/DatePicker/index.d.ts.map +1 -0
- package/lib/typescript/components/DateRangePicker/index.d.ts +45 -0
- package/lib/typescript/components/DateRangePicker/index.d.ts.map +1 -0
- package/lib/typescript/components/DateTimeField/index.d.ts +29 -0
- package/lib/typescript/components/DateTimeField/index.d.ts.map +1 -0
- package/lib/typescript/components/DateTimeList/index.d.ts +19 -0
- package/lib/typescript/components/DateTimeList/index.d.ts.map +1 -0
- package/lib/typescript/components/DateTimeList/styles.d.ts +17 -0
- package/lib/typescript/components/DateTimeList/styles.d.ts.map +1 -0
- package/lib/typescript/components/DateTimePicker/index.d.ts +40 -0
- package/lib/typescript/components/DateTimePicker/index.d.ts.map +1 -0
- package/lib/typescript/components/MonthCalendar/index.d.ts +29 -0
- package/lib/typescript/components/MonthCalendar/index.d.ts.map +1 -0
- package/lib/typescript/components/MonthPicker/index.d.ts +40 -0
- package/lib/typescript/components/MonthPicker/index.d.ts.map +1 -0
- package/lib/typescript/components/RangeCalendar/index.d.ts +19 -0
- package/lib/typescript/components/RangeCalendar/index.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +10 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/components/picker/PickerTrigger.d.ts +25 -0
- package/lib/typescript/components/picker/PickerTrigger.d.ts.map +1 -0
- package/lib/typescript/components/picker/styles.d.ts +4 -0
- package/lib/typescript/components/picker/styles.d.ts.map +1 -0
- package/lib/typescript/components/picker/surfaces.d.ts +28 -0
- package/lib/typescript/components/picker/surfaces.d.ts.map +1 -0
- package/package.json +6 -4
- package/src/components/BottomSheet/index.tsx +7 -1
- package/src/components/Calendar/CalendarMonthHeader.tsx +124 -0
- package/src/components/Calendar/CalendarYearPickerGrid.tsx +101 -0
- package/src/components/Calendar/flashCalendarAdapter.ts +362 -0
- package/src/components/Calendar/index.tsx +151 -0
- package/src/components/Calendar/styles.ts +80 -0
- package/src/components/DateField/index.tsx +196 -0
- package/src/components/DateField/styles.ts +51 -0
- package/src/components/DatePicker/index.tsx +187 -0
- package/src/components/DateRangePicker/index.tsx +202 -0
- package/src/components/DateTimeField/index.tsx +128 -0
- package/src/components/DateTimeList/index.tsx +187 -0
- package/src/components/DateTimeList/styles.ts +59 -0
- package/src/components/DateTimePicker/index.tsx +233 -0
- package/src/components/MonthCalendar/index.tsx +252 -0
- package/src/components/MonthPicker/index.tsx +188 -0
- package/src/components/RangeCalendar/index.tsx +162 -0
- package/src/components/index.ts +10 -0
- package/src/components/picker/PickerTrigger.tsx +65 -0
- package/src/components/picker/styles.ts +17 -0
- package/src/components/picker/surfaces.tsx +174 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { forwardRef, useMemo, type ReactNode } from 'react';
|
|
2
|
+
import { View, type ViewProps } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
DateFieldInput as DateFieldInputPrimitive,
|
|
5
|
+
DateFieldRoot as DateFieldRootPrimitive,
|
|
6
|
+
DateFieldSegment as DateFieldSegmentPrimitive,
|
|
7
|
+
InputRoot as InputRootPrimitive,
|
|
8
|
+
Slot,
|
|
9
|
+
dataAttributes,
|
|
10
|
+
mergeDataAttributes,
|
|
11
|
+
type DateFieldRootProps as DateFieldRootPrimitiveProps,
|
|
12
|
+
type DateFieldSegmentProps as DateFieldSegmentPrimitiveProps,
|
|
13
|
+
} from '@cdx-ui/primitives';
|
|
14
|
+
import type { DateComponentLabels } from '@cdx-ui/formatters';
|
|
15
|
+
import { cn, ParentContext, useParentContext } from '@cdx-ui/utils';
|
|
16
|
+
import {
|
|
17
|
+
dateFieldGroupVariants,
|
|
18
|
+
dateFieldInputVariants,
|
|
19
|
+
dateFieldRootVariants,
|
|
20
|
+
dateFieldSegmentVariants,
|
|
21
|
+
dateFieldSuffixVariants,
|
|
22
|
+
type DateFieldGroupVariantProps,
|
|
23
|
+
} from './styles';
|
|
24
|
+
|
|
25
|
+
const SCOPE = 'DATE_FIELD';
|
|
26
|
+
|
|
27
|
+
type DateFieldStyleContext = DateFieldGroupVariantProps & {
|
|
28
|
+
fullWidth?: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const useDateFieldStyleContext = (): DateFieldStyleContext =>
|
|
32
|
+
(useParentContext()[SCOPE] as DateFieldStyleContext | undefined) ?? {};
|
|
33
|
+
|
|
34
|
+
export interface DateFieldProps extends DateFieldRootPrimitiveProps, DateFieldGroupVariantProps {
|
|
35
|
+
className?: string;
|
|
36
|
+
/** When true (the default), the group stretches to fill its container; when false, it hugs the segments. */
|
|
37
|
+
fullWidth?: boolean;
|
|
38
|
+
labels?: Partial<DateComponentLabels>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const DateFieldRoot = forwardRef<View, DateFieldProps>(
|
|
42
|
+
(
|
|
43
|
+
{
|
|
44
|
+
mode = 'date',
|
|
45
|
+
locale = 'en-US',
|
|
46
|
+
labels,
|
|
47
|
+
variant = 'outline',
|
|
48
|
+
size = 'default',
|
|
49
|
+
fullWidth,
|
|
50
|
+
className,
|
|
51
|
+
children,
|
|
52
|
+
style,
|
|
53
|
+
...props
|
|
54
|
+
},
|
|
55
|
+
ref,
|
|
56
|
+
) => {
|
|
57
|
+
const parent = useParentContext();
|
|
58
|
+
const ctx = useMemo(
|
|
59
|
+
() => ({ ...parent, [SCOPE]: { variant, size, fullWidth } }),
|
|
60
|
+
[parent, variant, size, fullWidth],
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<ParentContext.Provider value={ctx}>
|
|
65
|
+
<DateFieldRootPrimitive
|
|
66
|
+
ref={ref}
|
|
67
|
+
mode={mode}
|
|
68
|
+
locale={locale}
|
|
69
|
+
labels={labels}
|
|
70
|
+
className={cn(dateFieldRootVariants(), className)}
|
|
71
|
+
style={style}
|
|
72
|
+
{...props}
|
|
73
|
+
{...mergeDataAttributes(props, dataAttributes({ slot: 'date-field' }))}
|
|
74
|
+
>
|
|
75
|
+
{children}
|
|
76
|
+
</DateFieldRootPrimitive>
|
|
77
|
+
</ParentContext.Provider>
|
|
78
|
+
);
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
DateFieldRoot.displayName = 'DateField';
|
|
83
|
+
|
|
84
|
+
export interface DateFieldGroupProps extends ViewProps, DateFieldGroupVariantProps {
|
|
85
|
+
className?: string;
|
|
86
|
+
children?: ReactNode;
|
|
87
|
+
fullWidth?: boolean;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const DateFieldGroup = forwardRef<View, DateFieldGroupProps>(
|
|
91
|
+
({ variant, size, fullWidth, className, children, style, ...props }, ref) => {
|
|
92
|
+
const inherited = useDateFieldStyleContext();
|
|
93
|
+
const resolvedVariant = variant ?? inherited.variant ?? 'outline';
|
|
94
|
+
const resolvedSize = size ?? inherited.size ?? 'default';
|
|
95
|
+
const resolvedFullWidth = fullWidth ?? inherited.fullWidth ?? true;
|
|
96
|
+
const computedClassName = cn(
|
|
97
|
+
dateFieldGroupVariants({ variant: resolvedVariant, size: resolvedSize }),
|
|
98
|
+
!resolvedFullWidth && 'w-auto self-start',
|
|
99
|
+
className,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<InputRootPrimitive ref={ref} className={computedClassName} style={style} {...props}>
|
|
104
|
+
{children}
|
|
105
|
+
</InputRootPrimitive>
|
|
106
|
+
);
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
DateFieldGroup.displayName = 'DateField.Group';
|
|
111
|
+
|
|
112
|
+
export interface DateFieldInputProps extends Omit<ViewProps, 'children'> {
|
|
113
|
+
children?: (segment: DateFieldSegmentPrimitiveProps['segment']) => ReactNode;
|
|
114
|
+
slot?: 'start' | 'end';
|
|
115
|
+
className?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface DateFieldSegmentProps extends DateFieldSegmentPrimitiveProps {
|
|
119
|
+
className?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const DateFieldSegment = forwardRef<View, DateFieldSegmentProps>(
|
|
123
|
+
({ segment, className, style, ...props }, ref) => (
|
|
124
|
+
<DateFieldSegmentPrimitive
|
|
125
|
+
ref={ref}
|
|
126
|
+
segment={segment}
|
|
127
|
+
className={cn(dateFieldSegmentVariants({ literal: !segment.isEditable }), className)}
|
|
128
|
+
style={style}
|
|
129
|
+
{...props}
|
|
130
|
+
{...mergeDataAttributes(props, dataAttributes({ slot: 'date-field-segment' }))}
|
|
131
|
+
/>
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
DateFieldSegment.displayName = 'DateField.Segment';
|
|
136
|
+
|
|
137
|
+
const renderDefaultDateFieldSegment = (segment: DateFieldSegmentPrimitiveProps['segment']) => (
|
|
138
|
+
<DateFieldSegment segment={segment} />
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const DateFieldInput = forwardRef<View, DateFieldInputProps>(
|
|
142
|
+
({ children = renderDefaultDateFieldSegment, className, style, ...props }, ref) => {
|
|
143
|
+
const { size } = useDateFieldStyleContext();
|
|
144
|
+
return (
|
|
145
|
+
<DateFieldInputPrimitive
|
|
146
|
+
ref={ref}
|
|
147
|
+
className={cn(dateFieldInputVariants({ size: size ?? 'default' }), className)}
|
|
148
|
+
style={style}
|
|
149
|
+
{...props}
|
|
150
|
+
>
|
|
151
|
+
{children}
|
|
152
|
+
</DateFieldInputPrimitive>
|
|
153
|
+
);
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
DateFieldInput.displayName = 'DateField.Input';
|
|
158
|
+
|
|
159
|
+
export interface DateFieldSuffixProps extends ViewProps {
|
|
160
|
+
asChild?: boolean;
|
|
161
|
+
className?: string;
|
|
162
|
+
children?: ReactNode;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const DateFieldSuffix = forwardRef<View, DateFieldSuffixProps>(
|
|
166
|
+
({ asChild, className, children, style, ...props }, ref) => {
|
|
167
|
+
const Comp = asChild ? Slot : View;
|
|
168
|
+
return (
|
|
169
|
+
<Comp
|
|
170
|
+
ref={ref}
|
|
171
|
+
className={cn(dateFieldSuffixVariants(), className)}
|
|
172
|
+
style={style}
|
|
173
|
+
{...props}
|
|
174
|
+
{...mergeDataAttributes(props, dataAttributes({ slot: 'date-field-suffix' }))}
|
|
175
|
+
>
|
|
176
|
+
{children}
|
|
177
|
+
</Comp>
|
|
178
|
+
);
|
|
179
|
+
},
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
DateFieldSuffix.displayName = 'DateField.Suffix';
|
|
183
|
+
|
|
184
|
+
type DateFieldCompound = typeof DateFieldRoot & {
|
|
185
|
+
Group: typeof DateFieldGroup;
|
|
186
|
+
Input: typeof DateFieldInput;
|
|
187
|
+
Segment: typeof DateFieldSegment;
|
|
188
|
+
Suffix: typeof DateFieldSuffix;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export const DateField = Object.assign(DateFieldRoot, {
|
|
192
|
+
Group: DateFieldGroup,
|
|
193
|
+
Input: DateFieldInput,
|
|
194
|
+
Segment: DateFieldSegment,
|
|
195
|
+
Suffix: DateFieldSuffix,
|
|
196
|
+
}) as DateFieldCompound;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { cva, type VariantProps } from '@cdx-ui/utils';
|
|
2
|
+
import { inputRootVariants, inputSlotVariants } from '../Input/styles';
|
|
3
|
+
|
|
4
|
+
export const dateFieldRootVariants = cva('gap-1.5');
|
|
5
|
+
|
|
6
|
+
export const dateFieldGroupVariants = inputRootVariants;
|
|
7
|
+
|
|
8
|
+
export const dateFieldInputVariants = cva(
|
|
9
|
+
[
|
|
10
|
+
'flex-1 min-w-0 flex-row flex-wrap items-center gap-px bg-transparent p-0',
|
|
11
|
+
'text-content-primary',
|
|
12
|
+
'web:outline-none',
|
|
13
|
+
'tracking-normal',
|
|
14
|
+
'tabular-nums',
|
|
15
|
+
],
|
|
16
|
+
{
|
|
17
|
+
variants: {
|
|
18
|
+
size: {
|
|
19
|
+
default: 'text-[0.875rem]',
|
|
20
|
+
small: 'text-[0.75rem]',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
size: 'default',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const dateFieldSegmentVariants = cva(
|
|
30
|
+
[
|
|
31
|
+
'body-md shrink-0 rounded-[var(--border-radius-default)] px-0.5 text-end tabular-nums',
|
|
32
|
+
'text-content-primary',
|
|
33
|
+
'data-[placeholder=true]:text-content-tertiary',
|
|
34
|
+
'data-[focus=true]:bg-surface-action-subtle data-[focus=true]:text-content-primary',
|
|
35
|
+
],
|
|
36
|
+
{
|
|
37
|
+
variants: {
|
|
38
|
+
literal: {
|
|
39
|
+
true: 'text-content-secondary px-0',
|
|
40
|
+
false: '',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
defaultVariants: {
|
|
44
|
+
literal: false,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export const dateFieldSuffixVariants = inputSlotVariants;
|
|
50
|
+
|
|
51
|
+
export type DateFieldGroupVariantProps = VariantProps<typeof dateFieldGroupVariants>;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { forwardRef, useCallback, useMemo, type ReactNode } from 'react';
|
|
2
|
+
import { View, type ViewProps } from 'react-native';
|
|
3
|
+
import { CalendarToday } from '@cdx-ui/icons';
|
|
4
|
+
import type { DateId } from '@cdx-ui/formatters';
|
|
5
|
+
import {
|
|
6
|
+
dataAttributes,
|
|
7
|
+
DatePickerContext,
|
|
8
|
+
DatePickerRoot as DatePickerRootPrimitive,
|
|
9
|
+
mergeDataAttributes,
|
|
10
|
+
useDatePickerContext,
|
|
11
|
+
type DatePickerRootProps as DatePickerRootPrimitiveProps,
|
|
12
|
+
} from '@cdx-ui/primitives';
|
|
13
|
+
import { cn, ParentContext, useParentContext } from '@cdx-ui/utils';
|
|
14
|
+
import { Dialog } from '../Dialog';
|
|
15
|
+
import { Icon } from '../Icon';
|
|
16
|
+
import { Calendar, type CalendarProps } from '../Calendar';
|
|
17
|
+
import { PickerTrigger, type PickerTriggerProps } from '../picker/PickerTrigger';
|
|
18
|
+
import {
|
|
19
|
+
PickerBottomSheetSurface,
|
|
20
|
+
PickerDialogSurface,
|
|
21
|
+
PickerPopoverSurface,
|
|
22
|
+
} from '../picker/surfaces';
|
|
23
|
+
|
|
24
|
+
export interface DatePickerProps extends DatePickerRootPrimitiveProps, Omit<ViewProps, 'children'> {
|
|
25
|
+
className?: string;
|
|
26
|
+
children?: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const DATE_FIELD_SCOPE = 'DATE_FIELD';
|
|
30
|
+
|
|
31
|
+
const DatePickerRoot = forwardRef<View, DatePickerProps>(
|
|
32
|
+
({ className, children, style, ...props }, ref) => {
|
|
33
|
+
const parent = useParentContext();
|
|
34
|
+
const ctx = useMemo(
|
|
35
|
+
() => ({
|
|
36
|
+
...parent,
|
|
37
|
+
[DATE_FIELD_SCOPE]: { variant: 'outline', size: 'default', fullWidth: true },
|
|
38
|
+
}),
|
|
39
|
+
[parent],
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<ParentContext.Provider value={ctx}>
|
|
44
|
+
<DatePickerRootPrimitive
|
|
45
|
+
ref={ref}
|
|
46
|
+
className={cn('gap-2', className)}
|
|
47
|
+
style={style}
|
|
48
|
+
{...props}
|
|
49
|
+
{...mergeDataAttributes(props, dataAttributes({ slot: 'date-picker' }))}
|
|
50
|
+
>
|
|
51
|
+
{children}
|
|
52
|
+
</DatePickerRootPrimitive>
|
|
53
|
+
</ParentContext.Provider>
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
DatePickerRoot.displayName = 'DatePicker';
|
|
59
|
+
|
|
60
|
+
type DatePickerTriggerProps = Omit<
|
|
61
|
+
PickerTriggerProps,
|
|
62
|
+
'open' | 'setOpen' | 'disabled' | 'triggerRef' | 'accessibilityLabel'
|
|
63
|
+
> & {
|
|
64
|
+
accessibilityLabel?: string;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const DatePickerTrigger = forwardRef<View, DatePickerTriggerProps>(
|
|
68
|
+
({ accessibilityLabel, ...props }, ref) => {
|
|
69
|
+
const { open, setOpen, disabled, triggerRef, labels } = useDatePickerContext();
|
|
70
|
+
return (
|
|
71
|
+
<PickerTrigger
|
|
72
|
+
ref={ref}
|
|
73
|
+
open={open}
|
|
74
|
+
setOpen={setOpen}
|
|
75
|
+
disabled={disabled}
|
|
76
|
+
triggerRef={triggerRef}
|
|
77
|
+
accessibilityLabel={accessibilityLabel ?? labels.openDatePicker}
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
DatePickerTrigger.displayName = 'DatePicker.Trigger';
|
|
85
|
+
|
|
86
|
+
const DatePickerTriggerIndicator = () => (
|
|
87
|
+
<Icon as={CalendarToday} className="text-content-secondary" />
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
DatePickerTriggerIndicator.displayName = 'DatePicker.TriggerIndicator';
|
|
91
|
+
|
|
92
|
+
type DatePickerCalendarProps = Omit<
|
|
93
|
+
CalendarProps,
|
|
94
|
+
'value' | 'onValueChange' | 'minValue' | 'maxValue'
|
|
95
|
+
>;
|
|
96
|
+
|
|
97
|
+
const DatePickerCalendar = forwardRef<View, DatePickerCalendarProps>(({ ...props }, ref) => {
|
|
98
|
+
const { value, onValueChange, open, setOpen, minValue, maxValue, locale, labels } =
|
|
99
|
+
useDatePickerContext();
|
|
100
|
+
|
|
101
|
+
const handleValueChange = useCallback(
|
|
102
|
+
(next: DateId | undefined) => {
|
|
103
|
+
onValueChange?.(next);
|
|
104
|
+
if (open) {
|
|
105
|
+
setOpen(false);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
[onValueChange, open, setOpen],
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<Calendar
|
|
113
|
+
ref={ref}
|
|
114
|
+
value={value}
|
|
115
|
+
onValueChange={handleValueChange}
|
|
116
|
+
minValue={minValue}
|
|
117
|
+
maxValue={maxValue}
|
|
118
|
+
locale={locale}
|
|
119
|
+
labels={labels}
|
|
120
|
+
{...props}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
DatePickerCalendar.displayName = 'DatePicker.Calendar';
|
|
126
|
+
|
|
127
|
+
function DatePickerDialog({ children }: { children: ReactNode }) {
|
|
128
|
+
const ctx = useDatePickerContext();
|
|
129
|
+
return (
|
|
130
|
+
<PickerDialogSurface
|
|
131
|
+
open={ctx.open}
|
|
132
|
+
setOpen={ctx.setOpen}
|
|
133
|
+
registerSurface={ctx.registerSurface}
|
|
134
|
+
>
|
|
135
|
+
<Dialog.Popup className="p-4">
|
|
136
|
+
<DatePickerContext.Provider value={ctx}>{children}</DatePickerContext.Provider>
|
|
137
|
+
</Dialog.Popup>
|
|
138
|
+
</PickerDialogSurface>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function DatePickerBottomSheet({ children }: { children: ReactNode }) {
|
|
143
|
+
const ctx = useDatePickerContext();
|
|
144
|
+
return (
|
|
145
|
+
<PickerBottomSheetSurface
|
|
146
|
+
open={ctx.open}
|
|
147
|
+
setOpen={ctx.setOpen}
|
|
148
|
+
registerSurface={ctx.registerSurface}
|
|
149
|
+
>
|
|
150
|
+
<DatePickerContext.Provider value={ctx}>{children}</DatePickerContext.Provider>
|
|
151
|
+
</PickerBottomSheetSurface>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function DatePickerPopover({ children, className }: { children: ReactNode; className?: string }) {
|
|
156
|
+
const ctx = useDatePickerContext();
|
|
157
|
+
return (
|
|
158
|
+
<PickerPopoverSurface
|
|
159
|
+
open={ctx.open}
|
|
160
|
+
setOpen={ctx.setOpen}
|
|
161
|
+
registerSurface={ctx.registerSurface}
|
|
162
|
+
anchorRef={ctx.anchorRef}
|
|
163
|
+
triggerRef={ctx.triggerRef}
|
|
164
|
+
className={className}
|
|
165
|
+
>
|
|
166
|
+
<DatePickerContext.Provider value={ctx}>{children}</DatePickerContext.Provider>
|
|
167
|
+
</PickerPopoverSurface>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
type DatePickerCompound = typeof DatePickerRoot & {
|
|
172
|
+
Trigger: typeof DatePickerTrigger;
|
|
173
|
+
TriggerIndicator: typeof DatePickerTriggerIndicator;
|
|
174
|
+
Calendar: typeof DatePickerCalendar;
|
|
175
|
+
Popover: typeof DatePickerPopover;
|
|
176
|
+
Dialog: typeof DatePickerDialog;
|
|
177
|
+
BottomSheet: typeof DatePickerBottomSheet;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export const DatePicker = Object.assign(DatePickerRoot, {
|
|
181
|
+
Trigger: DatePickerTrigger,
|
|
182
|
+
TriggerIndicator: DatePickerTriggerIndicator,
|
|
183
|
+
Calendar: DatePickerCalendar,
|
|
184
|
+
Popover: DatePickerPopover,
|
|
185
|
+
Dialog: DatePickerDialog,
|
|
186
|
+
BottomSheet: DatePickerBottomSheet,
|
|
187
|
+
}) as DatePickerCompound;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { forwardRef, useMemo, type ReactNode } from 'react';
|
|
2
|
+
import { Text, View, type ViewProps } from 'react-native';
|
|
3
|
+
import { CalendarToday } from '@cdx-ui/icons';
|
|
4
|
+
import {
|
|
5
|
+
dataAttributes,
|
|
6
|
+
DateRangePickerContext,
|
|
7
|
+
DateRangePickerRoot as DateRangePickerRootPrimitive,
|
|
8
|
+
mergeDataAttributes,
|
|
9
|
+
useDateRangePickerContext,
|
|
10
|
+
type DateRangePickerRootProps as DateRangePickerRootPrimitiveProps,
|
|
11
|
+
} from '@cdx-ui/primitives';
|
|
12
|
+
import { cn, ParentContext, useParentContext } from '@cdx-ui/utils';
|
|
13
|
+
import { Dialog } from '../Dialog';
|
|
14
|
+
import { Icon } from '../Icon';
|
|
15
|
+
import { RangeCalendar, type RangeCalendarProps } from '../RangeCalendar';
|
|
16
|
+
import { PickerTrigger, type PickerTriggerProps } from '../picker/PickerTrigger';
|
|
17
|
+
import {
|
|
18
|
+
PickerBottomSheetSurface,
|
|
19
|
+
PickerDialogSurface,
|
|
20
|
+
PickerPopoverSurface,
|
|
21
|
+
} from '../picker/surfaces';
|
|
22
|
+
|
|
23
|
+
export type { DateRangeValue } from '@cdx-ui/primitives';
|
|
24
|
+
|
|
25
|
+
export interface DateRangePickerProps
|
|
26
|
+
extends DateRangePickerRootPrimitiveProps, Omit<ViewProps, 'children'> {
|
|
27
|
+
className?: string;
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const DATE_FIELD_SCOPE = 'DATE_FIELD';
|
|
32
|
+
|
|
33
|
+
const DateRangePickerRoot = forwardRef<View, DateRangePickerProps>(
|
|
34
|
+
({ className, children, style, ...props }, ref) => {
|
|
35
|
+
const parent = useParentContext();
|
|
36
|
+
const ctx = useMemo(
|
|
37
|
+
() => ({
|
|
38
|
+
...parent,
|
|
39
|
+
[DATE_FIELD_SCOPE]: { variant: 'outline', size: 'default', fullWidth: true },
|
|
40
|
+
}),
|
|
41
|
+
[parent],
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<ParentContext.Provider value={ctx}>
|
|
46
|
+
<DateRangePickerRootPrimitive
|
|
47
|
+
ref={ref}
|
|
48
|
+
className={cn('gap-2', className)}
|
|
49
|
+
style={style}
|
|
50
|
+
{...props}
|
|
51
|
+
{...mergeDataAttributes(props, dataAttributes({ slot: 'date-range-picker' }))}
|
|
52
|
+
>
|
|
53
|
+
{children}
|
|
54
|
+
</DateRangePickerRootPrimitive>
|
|
55
|
+
</ParentContext.Provider>
|
|
56
|
+
);
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
DateRangePickerRoot.displayName = 'DateRangePicker';
|
|
61
|
+
|
|
62
|
+
type DateRangePickerTriggerProps = Omit<
|
|
63
|
+
PickerTriggerProps,
|
|
64
|
+
'open' | 'setOpen' | 'disabled' | 'triggerRef' | 'accessibilityLabel'
|
|
65
|
+
> & {
|
|
66
|
+
accessibilityLabel?: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const DateRangePickerTrigger = forwardRef<View, DateRangePickerTriggerProps>(
|
|
70
|
+
({ accessibilityLabel, ...props }, ref) => {
|
|
71
|
+
const { open, setOpen, disabled, triggerRef, labels } = useDateRangePickerContext();
|
|
72
|
+
return (
|
|
73
|
+
<PickerTrigger
|
|
74
|
+
ref={ref}
|
|
75
|
+
open={open}
|
|
76
|
+
setOpen={setOpen}
|
|
77
|
+
disabled={disabled}
|
|
78
|
+
triggerRef={triggerRef}
|
|
79
|
+
accessibilityLabel={accessibilityLabel ?? labels.openDateRangePicker}
|
|
80
|
+
{...props}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
DateRangePickerTrigger.displayName = 'DateRangePicker.Trigger';
|
|
87
|
+
|
|
88
|
+
const DateRangePickerTriggerIndicator = () => (
|
|
89
|
+
<Icon as={CalendarToday} className="text-content-secondary" />
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
DateRangePickerTriggerIndicator.displayName = 'DateRangePicker.TriggerIndicator';
|
|
93
|
+
|
|
94
|
+
const DateRangePickerRangeSeparator = () => {
|
|
95
|
+
const { labels } = useDateRangePickerContext();
|
|
96
|
+
return <Text className="body-md text-content-secondary px-1">{labels.rangeSeparator}</Text>;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
DateRangePickerRangeSeparator.displayName = 'DateRangePicker.RangeSeparator';
|
|
100
|
+
|
|
101
|
+
type DateRangePickerCalendarProps = Omit<
|
|
102
|
+
RangeCalendarProps,
|
|
103
|
+
'startValue' | 'endValue' | 'onRangeChange' | 'focusedField' | 'onFocusedFieldChange'
|
|
104
|
+
>;
|
|
105
|
+
|
|
106
|
+
const DateRangePickerCalendar = forwardRef<View, DateRangePickerCalendarProps>(
|
|
107
|
+
({ ...props }, ref) => {
|
|
108
|
+
const { startValue, endValue, onRangeChange, focusedField, setFocusedField, locale, labels } =
|
|
109
|
+
useDateRangePickerContext();
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<RangeCalendar
|
|
113
|
+
ref={ref}
|
|
114
|
+
startValue={startValue}
|
|
115
|
+
endValue={endValue}
|
|
116
|
+
focusedField={focusedField}
|
|
117
|
+
onFocusedFieldChange={setFocusedField}
|
|
118
|
+
locale={locale}
|
|
119
|
+
labels={labels}
|
|
120
|
+
onRangeChange={(range) => {
|
|
121
|
+
if (!range.startId) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
onRangeChange?.({ startId: range.startId, endId: range.endId });
|
|
125
|
+
}}
|
|
126
|
+
{...props}
|
|
127
|
+
/>
|
|
128
|
+
);
|
|
129
|
+
},
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
DateRangePickerCalendar.displayName = 'DateRangePicker.Calendar';
|
|
133
|
+
|
|
134
|
+
function DateRangePickerDialog({ children }: { children: ReactNode }) {
|
|
135
|
+
const ctx = useDateRangePickerContext();
|
|
136
|
+
return (
|
|
137
|
+
<PickerDialogSurface
|
|
138
|
+
open={ctx.open}
|
|
139
|
+
setOpen={ctx.setOpen}
|
|
140
|
+
registerSurface={ctx.registerSurface}
|
|
141
|
+
>
|
|
142
|
+
<Dialog.Popup className="p-4">
|
|
143
|
+
<DateRangePickerContext.Provider value={ctx}>{children}</DateRangePickerContext.Provider>
|
|
144
|
+
</Dialog.Popup>
|
|
145
|
+
</PickerDialogSurface>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function DateRangePickerBottomSheet({ children }: { children: ReactNode }) {
|
|
150
|
+
const ctx = useDateRangePickerContext();
|
|
151
|
+
return (
|
|
152
|
+
<PickerBottomSheetSurface
|
|
153
|
+
open={ctx.open}
|
|
154
|
+
setOpen={ctx.setOpen}
|
|
155
|
+
registerSurface={ctx.registerSurface}
|
|
156
|
+
>
|
|
157
|
+
<DateRangePickerContext.Provider value={ctx}>{children}</DateRangePickerContext.Provider>
|
|
158
|
+
</PickerBottomSheetSurface>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function DateRangePickerPopover({
|
|
163
|
+
children,
|
|
164
|
+
className,
|
|
165
|
+
}: {
|
|
166
|
+
children: ReactNode;
|
|
167
|
+
className?: string;
|
|
168
|
+
}) {
|
|
169
|
+
const ctx = useDateRangePickerContext();
|
|
170
|
+
return (
|
|
171
|
+
<PickerPopoverSurface
|
|
172
|
+
open={ctx.open}
|
|
173
|
+
setOpen={ctx.setOpen}
|
|
174
|
+
registerSurface={ctx.registerSurface}
|
|
175
|
+
anchorRef={ctx.anchorRef}
|
|
176
|
+
triggerRef={ctx.triggerRef}
|
|
177
|
+
className={className}
|
|
178
|
+
>
|
|
179
|
+
<DateRangePickerContext.Provider value={ctx}>{children}</DateRangePickerContext.Provider>
|
|
180
|
+
</PickerPopoverSurface>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
type DateRangePickerCompound = typeof DateRangePickerRoot & {
|
|
185
|
+
Trigger: typeof DateRangePickerTrigger;
|
|
186
|
+
TriggerIndicator: typeof DateRangePickerTriggerIndicator;
|
|
187
|
+
RangeSeparator: typeof DateRangePickerRangeSeparator;
|
|
188
|
+
Calendar: typeof DateRangePickerCalendar;
|
|
189
|
+
Popover: typeof DateRangePickerPopover;
|
|
190
|
+
Dialog: typeof DateRangePickerDialog;
|
|
191
|
+
BottomSheet: typeof DateRangePickerBottomSheet;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export const DateRangePicker = Object.assign(DateRangePickerRoot, {
|
|
195
|
+
Trigger: DateRangePickerTrigger,
|
|
196
|
+
TriggerIndicator: DateRangePickerTriggerIndicator,
|
|
197
|
+
RangeSeparator: DateRangePickerRangeSeparator,
|
|
198
|
+
Calendar: DateRangePickerCalendar,
|
|
199
|
+
Popover: DateRangePickerPopover,
|
|
200
|
+
Dialog: DateRangePickerDialog,
|
|
201
|
+
BottomSheet: DateRangePickerBottomSheet,
|
|
202
|
+
}) as DateRangePickerCompound;
|