@impulse-ui-native/datetime 2.8.0 → 3.0.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.
@@ -1,9 +1,9 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { memo, useMemo } from "react";
3
- import { ScrollView } from "react-native";
2
+ import { memo } from "react";
3
+ import { ScrollView, StyleSheet } from "react-native";
4
4
  import { useEventCallback } from "@impulse-ui-native/core";
5
5
  import { Tag } from "@impulse-ui-native/primitives";
6
- import { useComponentsTokens } from "@impulse-ui-native/theme";
6
+ import { useThemedStyles } from "@impulse-ui-native/theme";
7
7
  import { getQuickOptionKey } from "../../utils";
8
8
  const QuickDateOptionTag = memo(function QuickDateOptionTag2(props) {
9
9
  const handlePress = useEventCallback(
@@ -12,16 +12,12 @@ const QuickDateOptionTag = memo(function QuickDateOptionTag2(props) {
12
12
  return /* @__PURE__ */ jsx(Tag, { label: props.option.label, onPress: handlePress });
13
13
  });
14
14
  const QuickDateOptions = memo(function QuickDateOptions2(props) {
15
- const tokens = useComponentsTokens();
16
- const style = useMemo(
17
- () => ({ gap: tokens.datetimePicker.quickDateOptions.gap }),
18
- [tokens.datetimePicker.quickDateOptions]
19
- );
15
+ const styles = useThemedStyles(themedStyles);
20
16
  return /* @__PURE__ */ jsx(
21
17
  ScrollView,
22
18
  {
23
19
  horizontal: true,
24
- contentContainerStyle: style,
20
+ contentContainerStyle: styles.content,
25
21
  showsHorizontalScrollIndicator: false,
26
22
  children: props.options.map((option, index) => /* @__PURE__ */ jsx(
27
23
  QuickDateOptionTag,
@@ -34,6 +30,13 @@ const QuickDateOptions = memo(function QuickDateOptions2(props) {
34
30
  }
35
31
  );
36
32
  });
33
+ function themedStyles(theme) {
34
+ return StyleSheet.create({
35
+ content: {
36
+ gap: theme.components.datetimePicker.quickDateOptions.gap
37
+ }
38
+ });
39
+ }
37
40
  export {
38
41
  QuickDateOptions
39
42
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/common/quick-date-options.tsx"],"sourcesContent":["import { memo, useMemo } from \"react\";\nimport { ScrollView, ViewStyle } from \"react-native\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { Tag } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport { QuickDateOption, TimeRange } from \"../../types\";\nimport { getQuickOptionKey } from \"../../utils\";\n\ninterface QuickDateOptionsProps {\n options: QuickDateOption<Date | TimeRange>[];\n onPress?: (date: QuickDateOption<Date | TimeRange>[\"value\"]) => void;\n}\n\ninterface QuickDateOptionTagProps {\n option: QuickDateOption<Date | TimeRange>;\n onPress?: QuickDateOptionsProps[\"onPress\"];\n}\n\nconst QuickDateOptionTag = memo(function QuickDateOptionTag(\n props: QuickDateOptionTagProps,\n) {\n const handlePress = useEventCallback(() =>\n props.onPress?.(props.option.value),\n );\n\n return <Tag label={props.option.label} onPress={handlePress} />;\n});\n\nexport const QuickDateOptions = memo(function QuickDateOptions(\n props: QuickDateOptionsProps,\n) {\n const tokens = useComponentsTokens();\n\n const style = useMemo<ViewStyle>(\n () => ({ gap: tokens.datetimePicker.quickDateOptions.gap }),\n [tokens.datetimePicker.quickDateOptions],\n );\n\n return (\n <ScrollView\n horizontal\n contentContainerStyle={style}\n showsHorizontalScrollIndicator={false}\n >\n {props.options.map((option, index) => (\n <QuickDateOptionTag\n key={getQuickOptionKey(option.value) ?? index}\n option={option}\n onPress={props.onPress}\n />\n ))}\n </ScrollView>\n );\n});\n"],"mappings":"AA2BS;AA3BT,SAAS,MAAM,eAAe;AAC9B,SAAS,kBAA6B;AAEtC,SAAS,wBAAwB;AACjC,SAAS,WAAW;AACpB,SAAS,2BAA2B;AAGpC,SAAS,yBAAyB;AAYlC,MAAM,qBAAqB,KAAK,SAASA,oBACvC,OACA;AACA,QAAM,cAAc;AAAA,IAAiB,MACnC,MAAM,UAAU,MAAM,OAAO,KAAK;AAAA,EACpC;AAEA,SAAO,oBAAC,OAAI,OAAO,MAAM,OAAO,OAAO,SAAS,aAAa;AAC/D,CAAC;AAEM,MAAM,mBAAmB,KAAK,SAASC,kBAC5C,OACA;AACA,QAAM,SAAS,oBAAoB;AAEnC,QAAM,QAAQ;AAAA,IACZ,OAAO,EAAE,KAAK,OAAO,eAAe,iBAAiB,IAAI;AAAA,IACzD,CAAC,OAAO,eAAe,gBAAgB;AAAA,EACzC;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,YAAU;AAAA,MACV,uBAAuB;AAAA,MACvB,gCAAgC;AAAA,MAE/B,gBAAM,QAAQ,IAAI,CAAC,QAAQ,UAC1B;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA,SAAS,MAAM;AAAA;AAAA,QAFV,kBAAkB,OAAO,KAAK,KAAK;AAAA,MAG1C,CACD;AAAA;AAAA,EACH;AAEJ,CAAC;","names":["QuickDateOptionTag","QuickDateOptions"]}
1
+ {"version":3,"sources":["../../../src/components/common/quick-date-options.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport { ScrollView, StyleSheet } from \"react-native\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { Tag } from \"@impulse-ui-native/primitives\";\nimport { useThemedStyles } from \"@impulse-ui-native/theme\";\n\nimport type { QuickDateOption, TimeRange } from \"../../types\";\nimport { getQuickOptionKey } from \"../../utils\";\n\ninterface QuickDateOptionsProps {\n options: QuickDateOption<Date | TimeRange>[];\n onPress?: (date: QuickDateOption<Date | TimeRange>[\"value\"]) => void;\n}\n\ninterface QuickDateOptionTagProps {\n option: QuickDateOption<Date | TimeRange>;\n onPress?: QuickDateOptionsProps[\"onPress\"];\n}\n\nconst QuickDateOptionTag = memo(function QuickDateOptionTag(\n props: QuickDateOptionTagProps,\n) {\n const handlePress = useEventCallback(() =>\n props.onPress?.(props.option.value),\n );\n\n return <Tag label={props.option.label} onPress={handlePress} />;\n});\n\nexport const QuickDateOptions = memo(function QuickDateOptions(\n props: QuickDateOptionsProps,\n) {\n const styles = useThemedStyles(themedStyles);\n\n return (\n <ScrollView\n horizontal\n contentContainerStyle={styles.content}\n showsHorizontalScrollIndicator={false}\n >\n {props.options.map((option, index) => (\n <QuickDateOptionTag\n key={getQuickOptionKey(option.value) ?? index}\n option={option}\n onPress={props.onPress}\n />\n ))}\n </ScrollView>\n );\n});\n\nfunction themedStyles(theme: AppTheme) {\n return StyleSheet.create({\n content: {\n gap: theme.components.datetimePicker.quickDateOptions.gap,\n },\n });\n}\n"],"mappings":"AA4BS;AA5BT,SAAS,YAAY;AACrB,SAAS,YAAY,kBAAkB;AAGvC,SAAS,wBAAwB;AACjC,SAAS,WAAW;AACpB,SAAS,uBAAuB;AAGhC,SAAS,yBAAyB;AAYlC,MAAM,qBAAqB,KAAK,SAASA,oBACvC,OACA;AACA,QAAM,cAAc;AAAA,IAAiB,MACnC,MAAM,UAAU,MAAM,OAAO,KAAK;AAAA,EACpC;AAEA,SAAO,oBAAC,OAAI,OAAO,MAAM,OAAO,OAAO,SAAS,aAAa;AAC/D,CAAC;AAEM,MAAM,mBAAmB,KAAK,SAASC,kBAC5C,OACA;AACA,QAAM,SAAS,gBAAgB,YAAY;AAE3C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,YAAU;AAAA,MACV,uBAAuB,OAAO;AAAA,MAC9B,gCAAgC;AAAA,MAE/B,gBAAM,QAAQ,IAAI,CAAC,QAAQ,UAC1B;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA,SAAS,MAAM;AAAA;AAAA,QAFV,kBAAkB,OAAO,KAAK,KAAK;AAAA,MAG1C,CACD;AAAA;AAAA,EACH;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB;AACrC,SAAO,WAAW,OAAO;AAAA,IACvB,SAAS;AAAA,MACP,KAAK,MAAM,WAAW,eAAe,iBAAiB;AAAA,IACxD;AAAA,EACF,CAAC;AACH;","names":["QuickDateOptionTag","QuickDateOptions"]}
@@ -1,39 +1,16 @@
1
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";
2
+ import { memo, useCallback, useEffect, useRef } from "react";
3
+ import { FlatList, StyleSheet } from "react-native";
7
4
  import { Pressable, Typography, View } from "@impulse-ui-native/primitives";
8
- import {
9
- useComponentsTokens
10
- } from "@impulse-ui-native/theme";
5
+ import { useComponentsTokens, useThemedStyles } from "@impulse-ui-native/theme";
11
6
  import { getClosestIndexByValue } from "../../utils";
12
7
  const PickerColumn = memo(function PickerColumn2(props) {
13
8
  const { data, label, value, initialScrollIndex = 0, onChange } = props;
14
- const tokens = useComponentsTokens();
15
- const columnTokens = tokens.timePicker.column;
16
9
  const listRef = useRef(null);
17
10
  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
- );
11
+ const tokens = useComponentsTokens();
12
+ const columnTokens = tokens.timePicker.column;
13
+ const styles = useThemedStyles(themedStyles);
37
14
  const keyExtractor = useCallback((item, index) => {
38
15
  return `${item}-${index}`;
39
16
  }, []);
@@ -58,7 +35,7 @@ const PickerColumn = memo(function PickerColumn2(props) {
58
35
  ({ item }) => {
59
36
  const selected = item === value;
60
37
  const fontWeight = selected ? columnTokens.selectedFontWeight : columnTokens.fontWeight;
61
- return /* @__PURE__ */ jsx(Pressable, { style: pressableStyle, children: /* @__PURE__ */ jsx(
38
+ return /* @__PURE__ */ jsx(Pressable, { style: styles.pressable, children: /* @__PURE__ */ jsx(
62
39
  Typography.Master,
63
40
  {
64
41
  fontSize: columnTokens.fontSize,
@@ -77,7 +54,7 @@ const PickerColumn = memo(function PickerColumn2(props) {
77
54
  columnTokens.fontWeight,
78
55
  columnTokens.selectedColor,
79
56
  columnTokens.selectedFontWeight,
80
- pressableStyle,
57
+ styles.pressable,
81
58
  value
82
59
  ]
83
60
  );
@@ -146,7 +123,7 @@ const PickerColumn = memo(function PickerColumn2(props) {
146
123
  decelerationRate: "fast",
147
124
  initialScrollIndex,
148
125
  showsVerticalScrollIndicator: false,
149
- contentContainerStyle,
126
+ contentContainerStyle: styles.contentContainer,
150
127
  onMomentumScrollEnd,
151
128
  onScrollToIndexFailed,
152
129
  removeClippedSubviews: true,
@@ -164,13 +141,20 @@ const PickerColumn = memo(function PickerColumn2(props) {
164
141
  }
165
142
  );
166
143
  });
167
- const styles = StyleSheet.create({
168
- pressableStyle: {
169
- alignItems: "center",
170
- justifyContent: "center"
171
- },
172
- contentContainerStyle: {}
173
- });
144
+ function themedStyles(theme) {
145
+ const columnTokens = theme.components.timePicker.column;
146
+ return StyleSheet.create({
147
+ contentContainer: {
148
+ paddingVertical: columnTokens.verticalPadding
149
+ },
150
+ pressable: {
151
+ alignItems: "center",
152
+ height: columnTokens.itemHeight,
153
+ justifyContent: "center",
154
+ width: columnTokens.listWidth
155
+ }
156
+ });
157
+ }
174
158
  export {
175
159
  PickerColumn
176
160
  };
@@ -1 +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"]}
1
+ {"version":3,"sources":["../../../src/components/time/picker-column.tsx"],"sourcesContent":["import type {\n ListRenderItemInfo,\n NativeScrollEvent,\n NativeSyntheticEvent,\n} from \"react-native\";\nimport { memo, useCallback, useEffect, useRef } from \"react\";\nimport { FlatList, StyleSheet } from \"react-native\";\n\nimport type { AppTheme, FontWeightValue } from \"@impulse-ui-native/theme\";\nimport { Pressable, Typography, View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens, useThemedStyles } 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 listRef = useRef<FlatList<number>>(null);\n const currentIndexRef = useRef(initialScrollIndex);\n const tokens = useComponentsTokens();\n const columnTokens = tokens.timePicker.column;\n const styles = useThemedStyles(themedStyles);\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={styles.pressable}>\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 styles.pressable,\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={styles.contentContainer}\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\nfunction themedStyles(theme: AppTheme) {\n const columnTokens = theme.components.timePicker.column;\n\n return StyleSheet.create({\n contentContainer: {\n paddingVertical: columnTokens.verticalPadding,\n },\n pressable: {\n alignItems: \"center\",\n height: columnTokens.itemHeight,\n justifyContent: \"center\",\n width: columnTokens.listWidth,\n },\n });\n}\n"],"mappings":"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","names":["PickerColumn"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impulse-ui-native/datetime",
3
- "version": "2.8.0",
3
+ "version": "3.0.0",
4
4
  "description": "Date and time selection components for ImpulseUI Native applications.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -28,13 +28,13 @@
28
28
  ],
29
29
  "sideEffects": false,
30
30
  "dependencies": {
31
- "@impulse-ui-native/core": "2.8.0",
32
- "@impulse-ui-native/theme": "2.8.0",
33
- "@impulse-ui-native/primitives": "2.8.0",
34
- "@impulse-ui-native/flyout": "2.8.0",
35
- "@impulse-ui-native/icon": "2.8.0",
36
- "@impulse-ui-native/select": "2.8.0",
37
- "@impulse-ui-native/portal": "2.8.0"
31
+ "@impulse-ui-native/core": "3.0.0",
32
+ "@impulse-ui-native/flyout": "3.0.0",
33
+ "@impulse-ui-native/theme": "3.0.0",
34
+ "@impulse-ui-native/primitives": "3.0.0",
35
+ "@impulse-ui-native/select": "3.0.0",
36
+ "@impulse-ui-native/icon": "3.0.0",
37
+ "@impulse-ui-native/portal": "3.0.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/react": "~19.2.14",