@impulse-ui-native/datetime 2.0.1 → 2.1.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/LICENSE +21 -0
- package/dist/components/common/calendar-day.d.mts +16 -0
- package/dist/components/common/calendar-day.js +56 -0
- package/dist/components/common/calendar-day.js.map +1 -0
- package/dist/components/common/calendar.d.mts +14 -0
- package/dist/components/common/calendar.js +58 -0
- package/dist/components/common/calendar.js.map +1 -0
- package/dist/components/common/date-control.d.mts +14 -0
- package/dist/components/common/date-control.js +57 -0
- package/dist/components/common/date-control.js.map +1 -0
- package/dist/components/common/datetime-picker-flyout-actions.d.mts +15 -0
- package/dist/components/common/datetime-picker-flyout-actions.js +26 -0
- package/dist/components/common/datetime-picker-flyout-actions.js.map +1 -0
- package/dist/components/common/quick-date-options.d.mts +13 -0
- package/dist/components/common/quick-date-options.js +33 -0
- package/dist/components/common/quick-date-options.js.map +1 -0
- package/dist/components/common/visible-date-select.d.mts +11 -0
- package/dist/components/common/visible-date-select.js +70 -0
- package/dist/components/common/visible-date-select.js.map +1 -0
- package/dist/components/date/date-picker.d.mts +10 -0
- package/dist/components/date/date-picker.flyout.d.mts +12 -0
- package/dist/components/date/date-picker.flyout.js +58 -0
- package/dist/components/date/date-picker.flyout.js.map +1 -0
- package/dist/components/date/date-picker.js +61 -0
- package/dist/components/date/date-picker.js.map +1 -0
- package/dist/components/date/date-range-picker.d.mts +10 -0
- package/dist/components/date/date-range-picker.js +63 -0
- package/dist/components/date/date-range-picker.js.map +1 -0
- package/dist/components/datetime/datetime-picker.d.mts +10 -0
- package/dist/components/datetime/datetime-picker.flyout.d.mts +13 -0
- package/dist/components/datetime/datetime-picker.flyout.js +80 -0
- package/dist/components/datetime/datetime-picker.flyout.js.map +1 -0
- package/dist/components/datetime/datetime-picker.js +63 -0
- package/dist/components/datetime/datetime-picker.js.map +1 -0
- package/dist/components/datetime/datetime-range-picker.d.mts +10 -0
- package/dist/components/datetime/datetime-range-picker.flyout.d.mts +14 -0
- package/dist/components/datetime/datetime-range-picker.flyout.js +114 -0
- package/dist/components/datetime/datetime-range-picker.flyout.js.map +1 -0
- package/dist/components/datetime/datetime-range-picker.js +69 -0
- package/dist/components/datetime/datetime-range-picker.js.map +1 -0
- package/dist/components/index.d.mts +12 -0
- package/dist/components/index.js +13 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/time/picker-column.d.mts +15 -0
- package/dist/components/time/picker-column.js +177 -0
- package/dist/components/time/picker-column.js.map +1 -0
- package/dist/components/time/time-picker.d.mts +14 -0
- package/dist/components/time/time-picker.flyout.d.mts +13 -0
- package/dist/components/time/time-picker.flyout.js +153 -0
- package/dist/components/time/time-picker.flyout.js.map +1 -0
- package/dist/components/time/time-picker.js +111 -0
- package/dist/components/time/time-picker.js.map +1 -0
- package/dist/constants/index.d.mts +1 -0
- package/dist/constants/index.js +2 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/picker.constants.d.mts +11 -0
- package/dist/constants/picker.constants.js +17 -0
- package/dist/constants/picker.constants.js.map +1 -0
- package/dist/hooks/index.d.mts +6 -0
- package/dist/hooks/index.js +7 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/use-datetime-picker.hook.d.mts +32 -0
- package/dist/hooks/use-datetime-picker.hook.js +112 -0
- package/dist/hooks/use-datetime-picker.hook.js.map +1 -0
- package/dist/hooks/use-datetime-range-picker.hook.d.mts +34 -0
- package/dist/hooks/use-datetime-range-picker.hook.js +161 -0
- package/dist/hooks/use-datetime-range-picker.hook.js.map +1 -0
- package/dist/index.d.mts +14 -116
- package/dist/index.js +3 -1741
- package/dist/index.js.map +1 -1
- package/dist/types/common.types.d.mts +42 -0
- package/dist/types/common.types.js +1 -0
- package/dist/types/common.types.js.map +1 -0
- package/dist/types/datetime-picker.types.d.mts +12 -0
- package/dist/types/datetime-picker.types.js +1 -0
- package/dist/types/datetime-picker.types.js.map +1 -0
- package/dist/types/datetime-range-picker.types.d.mts +12 -0
- package/dist/types/datetime-range-picker.types.js +1 -0
- package/dist/types/datetime-range-picker.types.js.map +1 -0
- package/dist/types/index.d.mts +5 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/calendar-day.utils.d.mts +32 -0
- package/dist/utils/calendar-day.utils.js +120 -0
- package/dist/utils/calendar-day.utils.js.map +1 -0
- package/dist/utils/datetime.utils.d.mts +22 -0
- package/dist/utils/datetime.utils.js +165 -0
- package/dist/utils/datetime.utils.js.map +1 -0
- package/dist/utils/index.d.mts +5 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +14 -13
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useCallback, useEffect, useMemo, useRef } from "react";
|
|
3
|
+
import {
|
|
4
|
+
FlatList,
|
|
5
|
+
StyleSheet
|
|
6
|
+
} from "react-native";
|
|
7
|
+
import { Pressable, Typography, View } from "@impulse-ui-native/primitives";
|
|
8
|
+
import {
|
|
9
|
+
useComponentsTokens
|
|
10
|
+
} from "@impulse-ui-native/theme";
|
|
11
|
+
import { getClosestIndexByValue } from "../../utils";
|
|
12
|
+
const PickerColumn = memo(function PickerColumn2(props) {
|
|
13
|
+
const { data, label, value, initialScrollIndex = 0, onChange } = props;
|
|
14
|
+
const tokens = useComponentsTokens();
|
|
15
|
+
const columnTokens = tokens.timePicker.column;
|
|
16
|
+
const listRef = useRef(null);
|
|
17
|
+
const currentIndexRef = useRef(initialScrollIndex);
|
|
18
|
+
const pressableStyle = useMemo(
|
|
19
|
+
() => [
|
|
20
|
+
styles.pressableStyle,
|
|
21
|
+
{
|
|
22
|
+
width: columnTokens.listWidth,
|
|
23
|
+
height: columnTokens.itemHeight
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
[columnTokens.listWidth, columnTokens.itemHeight]
|
|
27
|
+
);
|
|
28
|
+
const contentContainerStyle = useMemo(
|
|
29
|
+
() => [
|
|
30
|
+
styles.contentContainerStyle,
|
|
31
|
+
{
|
|
32
|
+
paddingVertical: columnTokens.verticalPadding
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
[columnTokens.verticalPadding]
|
|
36
|
+
);
|
|
37
|
+
const keyExtractor = useCallback((item, index) => {
|
|
38
|
+
return `${item}-${index}`;
|
|
39
|
+
}, []);
|
|
40
|
+
const getItemLayout = useCallback(
|
|
41
|
+
(_, index) => {
|
|
42
|
+
return {
|
|
43
|
+
length: columnTokens.itemHeight,
|
|
44
|
+
offset: columnTokens.itemHeight * index,
|
|
45
|
+
index
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
[columnTokens.itemHeight]
|
|
49
|
+
);
|
|
50
|
+
const scrollToIndex = useCallback((index, animated) => {
|
|
51
|
+
currentIndexRef.current = index;
|
|
52
|
+
listRef.current?.scrollToIndex({
|
|
53
|
+
index,
|
|
54
|
+
animated
|
|
55
|
+
});
|
|
56
|
+
}, []);
|
|
57
|
+
const renderItem = useCallback(
|
|
58
|
+
({ item }) => {
|
|
59
|
+
const selected = item === value;
|
|
60
|
+
const fontWeight = selected ? columnTokens.selectedFontWeight : columnTokens.fontWeight;
|
|
61
|
+
return /* @__PURE__ */ jsx(Pressable, { style: pressableStyle, children: /* @__PURE__ */ jsx(
|
|
62
|
+
Typography.Master,
|
|
63
|
+
{
|
|
64
|
+
fontSize: columnTokens.fontSize,
|
|
65
|
+
color: selected ? columnTokens.selectedColor : columnTokens.color,
|
|
66
|
+
textAlign: "center",
|
|
67
|
+
numberOfLines: 1,
|
|
68
|
+
fontWeight,
|
|
69
|
+
numeric: true,
|
|
70
|
+
children: String(item).padStart(2, "0")
|
|
71
|
+
}
|
|
72
|
+
) });
|
|
73
|
+
},
|
|
74
|
+
[
|
|
75
|
+
columnTokens.color,
|
|
76
|
+
columnTokens.fontSize,
|
|
77
|
+
columnTokens.fontWeight,
|
|
78
|
+
columnTokens.selectedColor,
|
|
79
|
+
columnTokens.selectedFontWeight,
|
|
80
|
+
pressableStyle,
|
|
81
|
+
value
|
|
82
|
+
]
|
|
83
|
+
);
|
|
84
|
+
const onMomentumScrollEnd = useCallback(
|
|
85
|
+
(event) => {
|
|
86
|
+
const offset = event.nativeEvent.contentOffset.y;
|
|
87
|
+
const index = Math.round(offset / columnTokens.itemHeight);
|
|
88
|
+
const newValue = data[index];
|
|
89
|
+
if (newValue === value) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
currentIndexRef.current = index;
|
|
93
|
+
if (newValue !== void 0) {
|
|
94
|
+
onChange?.(newValue);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
[columnTokens.itemHeight, data, onChange, value]
|
|
98
|
+
);
|
|
99
|
+
const onScrollToIndexFailed = useCallback(() => {
|
|
100
|
+
requestAnimationFrame(() => {
|
|
101
|
+
listRef.current?.scrollToOffset({
|
|
102
|
+
offset: initialScrollIndex * columnTokens.itemHeight,
|
|
103
|
+
animated: false
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}, [columnTokens.itemHeight, initialScrollIndex]);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (value === void 0) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const closestIndex = getClosestIndexByValue(
|
|
112
|
+
data,
|
|
113
|
+
value,
|
|
114
|
+
currentIndexRef.current
|
|
115
|
+
);
|
|
116
|
+
if (closestIndex === -1 || closestIndex === currentIndexRef.current) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
scrollToIndex(closestIndex, true);
|
|
120
|
+
}, [data, scrollToIndex, value]);
|
|
121
|
+
return /* @__PURE__ */ jsxs(
|
|
122
|
+
View,
|
|
123
|
+
{
|
|
124
|
+
width: columnTokens.width,
|
|
125
|
+
height: columnTokens.height,
|
|
126
|
+
flexDirection: "row",
|
|
127
|
+
justifyContent: "center",
|
|
128
|
+
gap: columnTokens.gap,
|
|
129
|
+
children: [
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
View,
|
|
132
|
+
{
|
|
133
|
+
width: columnTokens.listWidth,
|
|
134
|
+
height: columnTokens.height,
|
|
135
|
+
overflow: "hidden",
|
|
136
|
+
children: /* @__PURE__ */ jsx(
|
|
137
|
+
FlatList,
|
|
138
|
+
{
|
|
139
|
+
ref: listRef,
|
|
140
|
+
data,
|
|
141
|
+
renderItem,
|
|
142
|
+
keyExtractor,
|
|
143
|
+
getItemLayout,
|
|
144
|
+
snapToInterval: columnTokens.itemHeight,
|
|
145
|
+
snapToAlignment: "start",
|
|
146
|
+
decelerationRate: "fast",
|
|
147
|
+
initialScrollIndex,
|
|
148
|
+
showsVerticalScrollIndicator: false,
|
|
149
|
+
contentContainerStyle,
|
|
150
|
+
onMomentumScrollEnd,
|
|
151
|
+
onScrollToIndexFailed,
|
|
152
|
+
removeClippedSubviews: true,
|
|
153
|
+
windowSize: 3,
|
|
154
|
+
initialNumToRender: 7,
|
|
155
|
+
maxToRenderPerBatch: 7,
|
|
156
|
+
updateCellsBatchingPeriod: 50,
|
|
157
|
+
scrollEventThrottle: 16
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
),
|
|
162
|
+
/* @__PURE__ */ jsx(Typography.Body, { alignSelf: "center", children: label })
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
});
|
|
167
|
+
const styles = StyleSheet.create({
|
|
168
|
+
pressableStyle: {
|
|
169
|
+
alignItems: "center",
|
|
170
|
+
justifyContent: "center"
|
|
171
|
+
},
|
|
172
|
+
contentContainerStyle: {}
|
|
173
|
+
});
|
|
174
|
+
export {
|
|
175
|
+
PickerColumn
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=picker-column.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/time/picker-column.tsx"],"sourcesContent":["import { memo, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport {\n FlatList,\n ListRenderItemInfo,\n NativeScrollEvent,\n NativeSyntheticEvent,\n StyleSheet,\n} from \"react-native\";\n\nimport { Pressable, Typography, View } from \"@impulse-ui-native/primitives\";\nimport {\n FontWeightValue,\n useComponentsTokens,\n useTheme,\n} from \"@impulse-ui-native/theme\";\n\nimport { getClosestIndexByValue } from \"../../utils\";\n\ninterface PickerColumnProps {\n data: number[];\n label: string;\n type: \"hour\" | \"minute\" | \"second\";\n format: \"12h\" | \"24h\";\n value?: number;\n initialScrollIndex?: number;\n onChange?: (value: number) => void;\n}\n\nexport const PickerColumn = memo(function PickerColumn(\n props: PickerColumnProps,\n) {\n const { data, label, value, initialScrollIndex = 0, onChange } = props;\n\n const tokens = useComponentsTokens();\n const columnTokens = tokens.timePicker.column;\n\n const listRef = useRef<FlatList<number>>(null);\n const currentIndexRef = useRef(initialScrollIndex);\n\n const pressableStyle = useMemo(\n () => [\n styles.pressableStyle,\n {\n width: columnTokens.listWidth,\n height: columnTokens.itemHeight,\n },\n ],\n [columnTokens.listWidth, columnTokens.itemHeight],\n );\n\n const contentContainerStyle = useMemo(\n () => [\n styles.contentContainerStyle,\n {\n paddingVertical: columnTokens.verticalPadding,\n },\n ],\n [columnTokens.verticalPadding],\n );\n\n const keyExtractor = useCallback((item: number, index: number) => {\n return `${item}-${index}`;\n }, []);\n\n const getItemLayout = useCallback(\n (_: ArrayLike<number> | null | undefined, index: number) => {\n return {\n length: columnTokens.itemHeight,\n offset: columnTokens.itemHeight * index,\n index,\n };\n },\n [columnTokens.itemHeight],\n );\n\n const scrollToIndex = useCallback((index: number, animated: boolean) => {\n currentIndexRef.current = index;\n\n listRef.current?.scrollToIndex({\n index,\n animated,\n });\n }, []);\n\n const renderItem = useCallback(\n ({ item }: ListRenderItemInfo<number>) => {\n const selected = item === value;\n const fontWeight: FontWeightValue = (\n selected ? columnTokens.selectedFontWeight : columnTokens.fontWeight\n ) as FontWeightValue;\n\n return (\n <Pressable style={pressableStyle}>\n <Typography.Master\n fontSize={columnTokens.fontSize}\n color={selected ? columnTokens.selectedColor : columnTokens.color}\n textAlign=\"center\"\n numberOfLines={1}\n fontWeight={fontWeight}\n numeric\n >\n {String(item).padStart(2, \"0\")}\n </Typography.Master>\n </Pressable>\n );\n },\n [\n columnTokens.color,\n columnTokens.fontSize,\n columnTokens.fontWeight,\n columnTokens.selectedColor,\n columnTokens.selectedFontWeight,\n pressableStyle,\n value,\n ],\n );\n\n const onMomentumScrollEnd = useCallback(\n (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n const offset = event.nativeEvent.contentOffset.y;\n const index = Math.round(offset / columnTokens.itemHeight);\n const newValue = data[index];\n\n if (newValue === value) {\n return;\n }\n\n currentIndexRef.current = index;\n\n if (newValue !== undefined) {\n onChange?.(newValue);\n }\n },\n [columnTokens.itemHeight, data, onChange, value],\n );\n\n const onScrollToIndexFailed = useCallback(() => {\n requestAnimationFrame(() => {\n listRef.current?.scrollToOffset({\n offset: initialScrollIndex * columnTokens.itemHeight,\n animated: false,\n });\n });\n }, [columnTokens.itemHeight, initialScrollIndex]);\n\n useEffect(() => {\n if (value === undefined) {\n return;\n }\n\n const closestIndex = getClosestIndexByValue(\n data,\n value,\n currentIndexRef.current,\n );\n\n if (closestIndex === -1 || closestIndex === currentIndexRef.current) {\n return;\n }\n\n scrollToIndex(closestIndex, true);\n }, [data, scrollToIndex, value]);\n\n return (\n <View\n width={columnTokens.width}\n height={columnTokens.height}\n flexDirection=\"row\"\n justifyContent=\"center\"\n gap={columnTokens.gap}\n >\n <View\n width={columnTokens.listWidth}\n height={columnTokens.height}\n overflow=\"hidden\"\n >\n <FlatList\n ref={listRef}\n data={data}\n renderItem={renderItem}\n keyExtractor={keyExtractor}\n getItemLayout={getItemLayout}\n snapToInterval={columnTokens.itemHeight}\n snapToAlignment=\"start\"\n decelerationRate=\"fast\"\n initialScrollIndex={initialScrollIndex}\n showsVerticalScrollIndicator={false}\n contentContainerStyle={contentContainerStyle}\n onMomentumScrollEnd={onMomentumScrollEnd}\n onScrollToIndexFailed={onScrollToIndexFailed}\n removeClippedSubviews\n windowSize={3}\n initialNumToRender={7}\n maxToRenderPerBatch={7}\n updateCellsBatchingPeriod={50}\n scrollEventThrottle={16}\n />\n </View>\n\n <Typography.Body alignSelf=\"center\">{label}</Typography.Body>\n </View>\n );\n});\n\nconst styles = StyleSheet.create({\n pressableStyle: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n contentContainerStyle: {},\n});\n"],"mappings":"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","names":["PickerColumn"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
import { DatetimePickerCommonProps, TimePickerValue } from '../../types/common.types.mjs';
|
|
4
|
+
import '@impulse-ui-native/flyout';
|
|
5
|
+
import '@impulse-ui-native/primitives';
|
|
6
|
+
|
|
7
|
+
interface TimePickerProps extends DatetimePickerCommonProps {
|
|
8
|
+
value?: TimePickerValue | null;
|
|
9
|
+
defaultValue?: TimePickerValue | null;
|
|
10
|
+
onChange?: (value: TimePickerValue | null) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const TimePicker: react.MemoExoticComponent<(props: TimePickerProps) => react_jsx_runtime.JSX.Element>;
|
|
13
|
+
|
|
14
|
+
export { TimePicker };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
import { FlyoutProps } from '@impulse-ui-native/flyout';
|
|
4
|
+
import { PickerFlyoutActions, TimePickerValue } from '../../types/common.types.mjs';
|
|
5
|
+
import '@impulse-ui-native/primitives';
|
|
6
|
+
|
|
7
|
+
interface TimePickerFlyoutProps extends FlyoutProps, PickerFlyoutActions {
|
|
8
|
+
value: Partial<TimePickerValue> | null | undefined;
|
|
9
|
+
onChange: (value: TimePickerValue | null) => void;
|
|
10
|
+
}
|
|
11
|
+
declare const TimePickerFlyout: react.MemoExoticComponent<(props: TimePickerFlyoutProps) => react_jsx_runtime.JSX.Element>;
|
|
12
|
+
|
|
13
|
+
export { TimePickerFlyout };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useCallback, useMemo } from "react";
|
|
3
|
+
import { Flyout } from "@impulse-ui-native/flyout";
|
|
4
|
+
import { Portal } from "@impulse-ui-native/portal";
|
|
5
|
+
import { View } from "@impulse-ui-native/primitives";
|
|
6
|
+
import { useComponentsTokens } from "@impulse-ui-native/theme";
|
|
7
|
+
import { createInfiniteRange, getInfiniteRangeInitialIndex } from "../../utils";
|
|
8
|
+
import { DatetimePickerFlyoutActions } from "../common/datetime-picker-flyout-actions";
|
|
9
|
+
import { PickerColumn } from "./picker-column";
|
|
10
|
+
const DefaultTimePickerValue = {
|
|
11
|
+
hours: 0,
|
|
12
|
+
minutes: 0,
|
|
13
|
+
seconds: 0
|
|
14
|
+
};
|
|
15
|
+
const TimePickerFlyout = memo(function TimePickerFlyout2(props) {
|
|
16
|
+
const {
|
|
17
|
+
value,
|
|
18
|
+
onChange,
|
|
19
|
+
onPressApply,
|
|
20
|
+
onPressCancel,
|
|
21
|
+
onPressClear,
|
|
22
|
+
clearable,
|
|
23
|
+
...rest
|
|
24
|
+
} = props;
|
|
25
|
+
const tokens = useComponentsTokens();
|
|
26
|
+
const timePickerTokens = tokens.timePicker;
|
|
27
|
+
const selectedHours = value?.hours ?? DefaultTimePickerValue.hours;
|
|
28
|
+
const selectedMinutes = value?.minutes ?? DefaultTimePickerValue.minutes;
|
|
29
|
+
const selectedSeconds = value?.seconds ?? DefaultTimePickerValue.seconds;
|
|
30
|
+
const hours = useMemo(() => {
|
|
31
|
+
return createInfiniteRange(24, 4);
|
|
32
|
+
}, []);
|
|
33
|
+
const minutes = useMemo(() => {
|
|
34
|
+
return createInfiniteRange(60, 4);
|
|
35
|
+
}, []);
|
|
36
|
+
const seconds = useMemo(() => {
|
|
37
|
+
return createInfiniteRange(60, 4);
|
|
38
|
+
}, []);
|
|
39
|
+
const hoursInitialIndex = useMemo(() => {
|
|
40
|
+
return getInfiniteRangeInitialIndex(24, selectedHours, 4);
|
|
41
|
+
}, [selectedHours]);
|
|
42
|
+
const minutesInitialIndex = useMemo(() => {
|
|
43
|
+
return getInfiniteRangeInitialIndex(60, selectedMinutes, 4);
|
|
44
|
+
}, [selectedMinutes]);
|
|
45
|
+
const secondsInitialIndex = useMemo(() => {
|
|
46
|
+
return getInfiniteRangeInitialIndex(60, selectedSeconds, 4);
|
|
47
|
+
}, [selectedSeconds]);
|
|
48
|
+
const handleHoursChange = useCallback(
|
|
49
|
+
(hours2) => {
|
|
50
|
+
onChange({
|
|
51
|
+
hours: hours2,
|
|
52
|
+
minutes: selectedMinutes,
|
|
53
|
+
seconds: selectedSeconds
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
[onChange, selectedMinutes, selectedSeconds]
|
|
57
|
+
);
|
|
58
|
+
const handleMinutesChange = useCallback(
|
|
59
|
+
(minutes2) => {
|
|
60
|
+
onChange({
|
|
61
|
+
hours: selectedHours,
|
|
62
|
+
minutes: minutes2,
|
|
63
|
+
seconds: selectedSeconds
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
[onChange, selectedHours, selectedSeconds]
|
|
67
|
+
);
|
|
68
|
+
const handleSecondsChange = useCallback(
|
|
69
|
+
(seconds2) => {
|
|
70
|
+
onChange({
|
|
71
|
+
hours: selectedHours,
|
|
72
|
+
minutes: selectedMinutes,
|
|
73
|
+
seconds: seconds2
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
[onChange, selectedHours, selectedMinutes]
|
|
77
|
+
);
|
|
78
|
+
return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Flyout, { ...rest, children: /* @__PURE__ */ jsxs(View, { gap: timePickerTokens.flyout.gap, children: [
|
|
79
|
+
/* @__PURE__ */ jsxs(
|
|
80
|
+
View,
|
|
81
|
+
{
|
|
82
|
+
height: timePickerTokens.columns.height,
|
|
83
|
+
gap: timePickerTokens.columns.gap,
|
|
84
|
+
flexDirection: "row",
|
|
85
|
+
alignItems: "center",
|
|
86
|
+
justifyContent: "center",
|
|
87
|
+
children: [
|
|
88
|
+
/* @__PURE__ */ jsx(
|
|
89
|
+
View,
|
|
90
|
+
{
|
|
91
|
+
pointerEvents: "none",
|
|
92
|
+
position: "absolute",
|
|
93
|
+
height: timePickerTokens.columns.indicatorHeight,
|
|
94
|
+
width: timePickerTokens.columns.indicatorWidth,
|
|
95
|
+
borderRadius: timePickerTokens.columns.indicatorBorderRadius,
|
|
96
|
+
backgroundColor: timePickerTokens.columns.indicatorBackgroundColor,
|
|
97
|
+
top: timePickerTokens.columns.indicatorTop
|
|
98
|
+
}
|
|
99
|
+
),
|
|
100
|
+
/* @__PURE__ */ jsx(
|
|
101
|
+
PickerColumn,
|
|
102
|
+
{
|
|
103
|
+
data: hours,
|
|
104
|
+
label: "h",
|
|
105
|
+
format: "24h",
|
|
106
|
+
type: "hour",
|
|
107
|
+
value: selectedHours,
|
|
108
|
+
initialScrollIndex: hoursInitialIndex,
|
|
109
|
+
onChange: handleHoursChange
|
|
110
|
+
}
|
|
111
|
+
),
|
|
112
|
+
/* @__PURE__ */ jsx(
|
|
113
|
+
PickerColumn,
|
|
114
|
+
{
|
|
115
|
+
data: minutes,
|
|
116
|
+
label: "m",
|
|
117
|
+
format: "24h",
|
|
118
|
+
type: "minute",
|
|
119
|
+
value: selectedMinutes,
|
|
120
|
+
initialScrollIndex: minutesInitialIndex,
|
|
121
|
+
onChange: handleMinutesChange
|
|
122
|
+
}
|
|
123
|
+
),
|
|
124
|
+
/* @__PURE__ */ jsx(
|
|
125
|
+
PickerColumn,
|
|
126
|
+
{
|
|
127
|
+
data: seconds,
|
|
128
|
+
label: "s",
|
|
129
|
+
format: "24h",
|
|
130
|
+
type: "second",
|
|
131
|
+
value: selectedSeconds,
|
|
132
|
+
initialScrollIndex: secondsInitialIndex,
|
|
133
|
+
onChange: handleSecondsChange
|
|
134
|
+
}
|
|
135
|
+
)
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
),
|
|
139
|
+
/* @__PURE__ */ jsx(
|
|
140
|
+
DatetimePickerFlyoutActions,
|
|
141
|
+
{
|
|
142
|
+
canClear: Boolean(value && clearable),
|
|
143
|
+
onPressApply,
|
|
144
|
+
onPressCancel,
|
|
145
|
+
onPressClear
|
|
146
|
+
}
|
|
147
|
+
)
|
|
148
|
+
] }) }) });
|
|
149
|
+
});
|
|
150
|
+
export {
|
|
151
|
+
TimePickerFlyout
|
|
152
|
+
};
|
|
153
|
+
//# sourceMappingURL=time-picker.flyout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/time/time-picker.flyout.tsx"],"sourcesContent":["import { memo, useCallback, useMemo } from \"react\";\n\nimport { Flyout, FlyoutProps } from \"@impulse-ui-native/flyout\";\nimport { Portal } from \"@impulse-ui-native/portal\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens, useTheme } from \"@impulse-ui-native/theme\";\n\nimport { PickerFlyoutActions, TimePickerValue } from \"../../types\";\nimport { createInfiniteRange, getInfiniteRangeInitialIndex } from \"../../utils\";\nimport { DatetimePickerFlyoutActions } from \"../common/datetime-picker-flyout-actions\";\nimport { PickerColumn } from \"./picker-column\";\n\ninterface TimePickerFlyoutProps extends FlyoutProps, PickerFlyoutActions {\n value: Partial<TimePickerValue> | null | undefined;\n onChange: (value: TimePickerValue | null) => void;\n}\n\nconst DefaultTimePickerValue: TimePickerValue = {\n hours: 0,\n minutes: 0,\n seconds: 0,\n};\n\nexport const TimePickerFlyout = memo(function TimePickerFlyout(\n props: TimePickerFlyoutProps,\n) {\n const {\n value,\n onChange,\n onPressApply,\n onPressCancel,\n onPressClear,\n clearable,\n ...rest\n } = props;\n\n const tokens = useComponentsTokens();\n const timePickerTokens = tokens.timePicker;\n\n const selectedHours = value?.hours ?? DefaultTimePickerValue.hours;\n const selectedMinutes = value?.minutes ?? DefaultTimePickerValue.minutes;\n const selectedSeconds = value?.seconds ?? DefaultTimePickerValue.seconds;\n\n const hours = useMemo(() => {\n return createInfiniteRange(24, 4);\n }, []);\n\n const minutes = useMemo(() => {\n return createInfiniteRange(60, 4);\n }, []);\n\n const seconds = useMemo(() => {\n return createInfiniteRange(60, 4);\n }, []);\n\n const hoursInitialIndex = useMemo(() => {\n return getInfiniteRangeInitialIndex(24, selectedHours, 4);\n }, [selectedHours]);\n\n const minutesInitialIndex = useMemo(() => {\n return getInfiniteRangeInitialIndex(60, selectedMinutes, 4);\n }, [selectedMinutes]);\n\n const secondsInitialIndex = useMemo(() => {\n return getInfiniteRangeInitialIndex(60, selectedSeconds, 4);\n }, [selectedSeconds]);\n\n const handleHoursChange = useCallback(\n (hours: number) => {\n onChange({\n hours,\n minutes: selectedMinutes,\n seconds: selectedSeconds,\n });\n },\n [onChange, selectedMinutes, selectedSeconds],\n );\n\n const handleMinutesChange = useCallback(\n (minutes: number) => {\n onChange({\n hours: selectedHours,\n minutes,\n seconds: selectedSeconds,\n });\n },\n [onChange, selectedHours, selectedSeconds],\n );\n\n const handleSecondsChange = useCallback(\n (seconds: number) => {\n onChange({\n hours: selectedHours,\n minutes: selectedMinutes,\n seconds,\n });\n },\n [onChange, selectedHours, selectedMinutes],\n );\n\n return (\n <Portal>\n <Flyout {...rest}>\n <View gap={timePickerTokens.flyout.gap}>\n <View\n height={timePickerTokens.columns.height}\n gap={timePickerTokens.columns.gap}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <View\n pointerEvents=\"none\"\n position=\"absolute\"\n height={timePickerTokens.columns.indicatorHeight}\n width={timePickerTokens.columns.indicatorWidth}\n borderRadius={timePickerTokens.columns.indicatorBorderRadius}\n backgroundColor={\n timePickerTokens.columns.indicatorBackgroundColor\n }\n top={timePickerTokens.columns.indicatorTop}\n />\n\n <PickerColumn\n data={hours}\n label=\"h\"\n format=\"24h\"\n type=\"hour\"\n value={selectedHours}\n initialScrollIndex={hoursInitialIndex}\n onChange={handleHoursChange}\n />\n\n <PickerColumn\n data={minutes}\n label=\"m\"\n format=\"24h\"\n type=\"minute\"\n value={selectedMinutes}\n initialScrollIndex={minutesInitialIndex}\n onChange={handleMinutesChange}\n />\n\n <PickerColumn\n data={seconds}\n label=\"s\"\n format=\"24h\"\n type=\"second\"\n value={selectedSeconds}\n initialScrollIndex={secondsInitialIndex}\n onChange={handleSecondsChange}\n />\n </View>\n\n <DatetimePickerFlyoutActions\n canClear={Boolean(value && clearable)}\n onPressApply={onPressApply}\n onPressCancel={onPressCancel}\n onPressClear={onPressClear}\n />\n </View>\n </Flyout>\n </Portal>\n );\n});\n"],"mappings":"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","names":["TimePickerFlyout","hours","minutes","seconds"]}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useCallback, useEffect, useId, useState } from "react";
|
|
3
|
+
import { useControllableState, useIsOpen } from "@impulse-ui-native/core";
|
|
4
|
+
import { ClockIcon } from "@impulse-ui-native/icon/icons/clock";
|
|
5
|
+
import { Control, Pressable } from "@impulse-ui-native/primitives";
|
|
6
|
+
import { formatTimepickerValue } from "../../utils";
|
|
7
|
+
import { TimePickerFlyout } from "./time-picker.flyout";
|
|
8
|
+
const TimePicker = memo(function TimePicker2(props) {
|
|
9
|
+
const {
|
|
10
|
+
value,
|
|
11
|
+
defaultValue,
|
|
12
|
+
placeholder,
|
|
13
|
+
clearable = true,
|
|
14
|
+
size = "medium",
|
|
15
|
+
onChange,
|
|
16
|
+
variant = "outlined",
|
|
17
|
+
label,
|
|
18
|
+
error,
|
|
19
|
+
disabled,
|
|
20
|
+
PrefixIcon = ClockIcon,
|
|
21
|
+
Prefix,
|
|
22
|
+
onPressPrefix: onPrefixPress,
|
|
23
|
+
SuffixIcon,
|
|
24
|
+
Suffix,
|
|
25
|
+
onPressSuffix: onSuffixPress
|
|
26
|
+
} = props;
|
|
27
|
+
const id = useId();
|
|
28
|
+
const { isOpen, isClosed, finishClose, open, close } = useIsOpen();
|
|
29
|
+
const [selected, setSelected] = useControllableState({
|
|
30
|
+
prop: value,
|
|
31
|
+
defaultProp: defaultValue ?? null,
|
|
32
|
+
onChange
|
|
33
|
+
});
|
|
34
|
+
const [tempTime, setTempTime] = useState(selected);
|
|
35
|
+
const onPressOpen = useCallback(() => {
|
|
36
|
+
setTempTime(selected);
|
|
37
|
+
open();
|
|
38
|
+
}, [open, selected]);
|
|
39
|
+
const onPressApply = useCallback(() => {
|
|
40
|
+
setSelected(tempTime);
|
|
41
|
+
close();
|
|
42
|
+
}, [tempTime, close]);
|
|
43
|
+
const onPressClear = useCallback(() => {
|
|
44
|
+
setTempTime(null);
|
|
45
|
+
}, []);
|
|
46
|
+
const syncState = useCallback(() => {
|
|
47
|
+
setTempTime(selected);
|
|
48
|
+
}, [selected]);
|
|
49
|
+
const onCloseFinished = useCallback(() => {
|
|
50
|
+
syncState();
|
|
51
|
+
finishClose();
|
|
52
|
+
}, [syncState, finishClose]);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (!isOpen && isClosed) {
|
|
55
|
+
setTempTime(selected);
|
|
56
|
+
}
|
|
57
|
+
}, [isOpen, selected, isClosed]);
|
|
58
|
+
return /* @__PURE__ */ jsx(
|
|
59
|
+
Control.Provider,
|
|
60
|
+
{
|
|
61
|
+
size,
|
|
62
|
+
variant,
|
|
63
|
+
error,
|
|
64
|
+
disabled,
|
|
65
|
+
children: /* @__PURE__ */ jsxs(Control.Root, { children: [
|
|
66
|
+
/* @__PURE__ */ jsx(Control.Label, { children: label }),
|
|
67
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: onPressOpen, children: /* @__PURE__ */ jsxs(Control.Container, { children: [
|
|
68
|
+
/* @__PURE__ */ jsx(
|
|
69
|
+
Control.Addon,
|
|
70
|
+
{
|
|
71
|
+
icon: PrefixIcon,
|
|
72
|
+
Content: Prefix,
|
|
73
|
+
onPress: onPrefixPress
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
selected === null && placeholder ? /* @__PURE__ */ jsx(Control.Placeholder, { children: placeholder }) : null,
|
|
77
|
+
selected !== null ? /* @__PURE__ */ jsx(Control.Value, { children: formatTimepickerValue(selected) }) : null,
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
TimePickerFlyout,
|
|
80
|
+
{
|
|
81
|
+
id,
|
|
82
|
+
title: "Time",
|
|
83
|
+
open: isOpen,
|
|
84
|
+
value: tempTime,
|
|
85
|
+
clearable,
|
|
86
|
+
onClose: close,
|
|
87
|
+
onCloseFinished,
|
|
88
|
+
onChange: setTempTime,
|
|
89
|
+
onPressApply,
|
|
90
|
+
onPressClear,
|
|
91
|
+
onPressCancel: close
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
/* @__PURE__ */ jsx(
|
|
95
|
+
Control.Addon,
|
|
96
|
+
{
|
|
97
|
+
icon: SuffixIcon,
|
|
98
|
+
Content: Suffix,
|
|
99
|
+
onPress: onSuffixPress
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
] }) }),
|
|
103
|
+
/* @__PURE__ */ jsx(Control.Error, {})
|
|
104
|
+
] })
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
export {
|
|
109
|
+
TimePicker
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=time-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/time/time-picker.tsx"],"sourcesContent":["import { memo, useCallback, useEffect, useId, useState } from \"react\";\n\nimport { useControllableState, useIsOpen } from \"@impulse-ui-native/core\";\nimport { ClockIcon } from \"@impulse-ui-native/icon/icons/clock\";\nimport { Control, Pressable } from \"@impulse-ui-native/primitives\";\n\nimport { DatetimePickerCommonProps, TimePickerValue } from \"../../types\";\nimport { formatTimepickerValue } from \"../../utils\";\nimport { TimePickerFlyout } from \"./time-picker.flyout\";\n\ninterface TimePickerProps extends DatetimePickerCommonProps {\n value?: TimePickerValue | null;\n defaultValue?: TimePickerValue | null;\n onChange?: (value: TimePickerValue | null) => void;\n}\n\nexport const TimePicker = memo(function TimePicker(props: TimePickerProps) {\n const {\n value,\n defaultValue,\n placeholder,\n clearable = true,\n size = \"medium\",\n onChange,\n variant = \"outlined\",\n label,\n error,\n disabled,\n PrefixIcon = ClockIcon,\n Prefix,\n onPressPrefix: onPrefixPress,\n SuffixIcon,\n Suffix,\n onPressSuffix: onSuffixPress,\n } = props;\n\n const id = useId();\n const { isOpen, isClosed, finishClose, open, close } = useIsOpen();\n\n const [selected, setSelected] = useControllableState<TimePickerValue | null>({\n prop: value,\n defaultProp: defaultValue ?? null,\n onChange,\n });\n\n const [tempTime, setTempTime] = useState<TimePickerValue | null>(selected);\n\n const onPressOpen = useCallback(() => {\n setTempTime(selected);\n open();\n }, [open, selected]);\n\n const onPressApply = useCallback(() => {\n setSelected(tempTime);\n close();\n }, [tempTime, close]);\n\n const onPressClear = useCallback(() => {\n setTempTime(null);\n }, []);\n\n const syncState = useCallback(() => {\n setTempTime(selected);\n }, [selected]);\n\n const onCloseFinished = useCallback(() => {\n syncState();\n finishClose();\n }, [syncState, finishClose]);\n\n useEffect(() => {\n if (!isOpen && isClosed) {\n setTempTime(selected);\n }\n }, [isOpen, selected, isClosed]);\n\n return (\n <Control.Provider\n size={size}\n variant={variant}\n error={error}\n disabled={disabled}\n >\n <Control.Root>\n <Control.Label>{label}</Control.Label>\n <Pressable onPress={onPressOpen}>\n <Control.Container>\n <Control.Addon\n icon={PrefixIcon}\n Content={Prefix}\n onPress={onPrefixPress}\n />\n\n {selected === null && placeholder ? (\n <Control.Placeholder>{placeholder}</Control.Placeholder>\n ) : null}\n\n {selected !== null ? (\n <Control.Value>{formatTimepickerValue(selected)}</Control.Value>\n ) : null}\n\n <TimePickerFlyout\n id={id}\n title=\"Time\"\n open={isOpen}\n value={tempTime}\n clearable={clearable}\n onClose={close}\n onCloseFinished={onCloseFinished}\n onChange={setTempTime}\n onPressApply={onPressApply}\n onPressClear={onPressClear}\n onPressCancel={close}\n />\n\n <Control.Addon\n icon={SuffixIcon}\n Content={Suffix}\n onPress={onSuffixPress}\n />\n </Control.Container>\n </Pressable>\n <Control.Error />\n </Control.Root>\n </Control.Provider>\n );\n});\n"],"mappings":"AAoFQ,cAEE,YAFF;AApFR,SAAS,MAAM,aAAa,WAAW,OAAO,gBAAgB;AAE9D,SAAS,sBAAsB,iBAAiB;AAChD,SAAS,iBAAiB;AAC1B,SAAS,SAAS,iBAAiB;AAGnC,SAAS,6BAA6B;AACtC,SAAS,wBAAwB;AAQ1B,MAAM,aAAa,KAAK,SAASA,YAAW,OAAwB;AACzE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,OAAO;AAAA,IACP;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB,IAAI;AAEJ,QAAM,KAAK,MAAM;AACjB,QAAM,EAAE,QAAQ,UAAU,aAAa,MAAM,MAAM,IAAI,UAAU;AAEjE,QAAM,CAAC,UAAU,WAAW,IAAI,qBAA6C;AAAA,IAC3E,MAAM;AAAA,IACN,aAAa,gBAAgB;AAAA,IAC7B;AAAA,EACF,CAAC;AAED,QAAM,CAAC,UAAU,WAAW,IAAI,SAAiC,QAAQ;AAEzE,QAAM,cAAc,YAAY,MAAM;AACpC,gBAAY,QAAQ;AACpB,SAAK;AAAA,EACP,GAAG,CAAC,MAAM,QAAQ,CAAC;AAEnB,QAAM,eAAe,YAAY,MAAM;AACrC,gBAAY,QAAQ;AACpB,UAAM;AAAA,EACR,GAAG,CAAC,UAAU,KAAK,CAAC;AAEpB,QAAM,eAAe,YAAY,MAAM;AACrC,gBAAY,IAAI;AAAA,EAClB,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,YAAY,MAAM;AAClC,gBAAY,QAAQ;AAAA,EACtB,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,kBAAkB,YAAY,MAAM;AACxC,cAAU;AACV,gBAAY;AAAA,EACd,GAAG,CAAC,WAAW,WAAW,CAAC;AAE3B,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,UAAU;AACvB,kBAAY,QAAQ;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,QAAQ,UAAU,QAAQ,CAAC;AAE/B,SACE;AAAA,IAAC,QAAQ;AAAA,IAAR;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEA,+BAAC,QAAQ,MAAR,EACC;AAAA,4BAAC,QAAQ,OAAR,EAAe,iBAAM;AAAA,QACtB,oBAAC,aAAU,SAAS,aAClB,+BAAC,QAAQ,WAAR,EACC;AAAA;AAAA,YAAC,QAAQ;AAAA,YAAR;AAAA,cACC,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS;AAAA;AAAA,UACX;AAAA,UAEC,aAAa,QAAQ,cACpB,oBAAC,QAAQ,aAAR,EAAqB,uBAAY,IAChC;AAAA,UAEH,aAAa,OACZ,oBAAC,QAAQ,OAAR,EAAe,gCAAsB,QAAQ,GAAE,IAC9C;AAAA,UAEJ;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,OAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,cACP;AAAA,cACA,SAAS;AAAA,cACT;AAAA,cACA,UAAU;AAAA,cACV;AAAA,cACA;AAAA,cACA,eAAe;AAAA;AAAA,UACjB;AAAA,UAEA;AAAA,YAAC,QAAQ;AAAA,YAAR;AAAA,cACC,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS;AAAA;AAAA,UACX;AAAA,WACF,GACF;AAAA,QACA,oBAAC,QAAQ,OAAR,EAAc;AAAA,SACjB;AAAA;AAAA,EACF;AAEJ,CAAC;","names":["TimePicker"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ColumnWidth, ContainerHeight, InitialScrollIndexConfiguration, ItemHeight, ListWidth, VerticalPadding, VisibleItems } from './picker.constants.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/constants/index.ts"],"sourcesContent":["export * from \"./picker.constants\";\n"],"mappings":"AAAA,cAAc;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const ItemHeight = 50;
|
|
2
|
+
declare const VisibleItems = 5;
|
|
3
|
+
declare const ContainerHeight: number;
|
|
4
|
+
declare const VerticalPadding: number;
|
|
5
|
+
declare const ColumnWidth = 70;
|
|
6
|
+
declare const ListWidth = 30;
|
|
7
|
+
declare const InitialScrollIndexConfiguration: {
|
|
8
|
+
viewOffset: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { ColumnWidth, ContainerHeight, InitialScrollIndexConfiguration, ItemHeight, ListWidth, VerticalPadding, VisibleItems };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const ItemHeight = 50;
|
|
2
|
+
const VisibleItems = 5;
|
|
3
|
+
const ContainerHeight = ItemHeight * VisibleItems;
|
|
4
|
+
const VerticalPadding = ContainerHeight / 2 - ItemHeight / 2;
|
|
5
|
+
const ColumnWidth = 70;
|
|
6
|
+
const ListWidth = 30;
|
|
7
|
+
const InitialScrollIndexConfiguration = { viewOffset: -VerticalPadding };
|
|
8
|
+
export {
|
|
9
|
+
ColumnWidth,
|
|
10
|
+
ContainerHeight,
|
|
11
|
+
InitialScrollIndexConfiguration,
|
|
12
|
+
ItemHeight,
|
|
13
|
+
ListWidth,
|
|
14
|
+
VerticalPadding,
|
|
15
|
+
VisibleItems
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=picker.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/constants/picker.constants.ts"],"sourcesContent":["export const ItemHeight = 50;\nexport const VisibleItems = 5;\nexport const ContainerHeight = ItemHeight * VisibleItems;\nexport const VerticalPadding = ContainerHeight / 2 - ItemHeight / 2;\nexport const ColumnWidth = 70;\nexport const ListWidth = 30;\nexport const InitialScrollIndexConfiguration = { viewOffset: -VerticalPadding };\n"],"mappings":"AAAO,MAAM,aAAa;AACnB,MAAM,eAAe;AACrB,MAAM,kBAAkB,aAAa;AACrC,MAAM,kBAAkB,kBAAkB,IAAI,aAAa;AAC3D,MAAM,cAAc;AACpB,MAAM,YAAY;AAClB,MAAM,kCAAkC,EAAE,YAAY,CAAC,gBAAgB;","names":[]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { useDatetimePicker } from './use-datetime-picker.hook.mjs';
|
|
2
|
+
export { useDatetimeRangePicker } from './use-datetime-range-picker.hook.mjs';
|
|
3
|
+
import 'react';
|
|
4
|
+
import '../types/common.types.mjs';
|
|
5
|
+
import '@impulse-ui-native/flyout';
|
|
6
|
+
import '@impulse-ui-native/primitives';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/index.ts"],"sourcesContent":["export { useDatetimePicker } from \"./use-datetime-picker.hook\";\nexport { useDatetimeRangePicker } from \"./use-datetime-range-picker.hook\";\n"],"mappings":"AAAA,SAAS,yBAAyB;AAClC,SAAS,8BAA8B;","names":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { TimePickerValue, TimeRange } from '../types/common.types.mjs';
|
|
3
|
+
import '@impulse-ui-native/flyout';
|
|
4
|
+
import '@impulse-ui-native/primitives';
|
|
5
|
+
|
|
6
|
+
interface UseDatetimePickerStateOptions {
|
|
7
|
+
value?: Date | null;
|
|
8
|
+
defaultValue?: Date | null;
|
|
9
|
+
onChange?: (value: Date | null) => void;
|
|
10
|
+
}
|
|
11
|
+
declare function useDatetimePicker({ value, defaultValue, onChange, }: UseDatetimePickerStateOptions): {
|
|
12
|
+
id: string;
|
|
13
|
+
isOpen: boolean;
|
|
14
|
+
visible: Date;
|
|
15
|
+
tempDate: Date | null;
|
|
16
|
+
selected: Date | null;
|
|
17
|
+
setVisible: react.Dispatch<react.SetStateAction<Date>>;
|
|
18
|
+
setTempDate: react.Dispatch<react.SetStateAction<Date | null>>;
|
|
19
|
+
setSelected: (nextValue: react.SetStateAction<Date | null>) => void;
|
|
20
|
+
open: () => void;
|
|
21
|
+
close: () => void;
|
|
22
|
+
onPressOpen: () => void;
|
|
23
|
+
onPressApply: () => void;
|
|
24
|
+
onPressCancel: () => void;
|
|
25
|
+
onPressCalendarDay: (date: Date) => void;
|
|
26
|
+
onChangeTime: (time: TimePickerValue | null) => void;
|
|
27
|
+
onPressClear: () => void;
|
|
28
|
+
onPressQuickDateOption: (optionValue: Date | TimeRange) => void;
|
|
29
|
+
syncState: () => void;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { useDatetimePicker };
|