diff --git a/.eslintrc.js b/.eslintrc.js
index 63053cf..147b7ab 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,119 +1,119 @@
module.exports = {
env: {
- es2021: true,
- node: true,
+ es2021: true,
+ node: true,
},
settings: {
- react: {
- version: "detect",
- },
+ react: {
+ version: "detect",
+ },
},
extends: [
- "eslint:recommended",
- "plugin:react/recommended",
- "plugin:@typescript-eslint/recommended",
+ "eslint:recommended",
+ "plugin:react/recommended",
+ "plugin:@typescript-eslint/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
- ecmaFeatures: {
- jsx: true,
- },
- ecmaVersion: 12,
- sourceType: "module",
+ ecmaFeatures: {
+ jsx: true,
+ },
+ ecmaVersion: 12,
+ sourceType: "module",
},
plugins: [
- "react",
- "react-hooks",
- "@typescript-eslint",
- "typescript-sort-keys",
- "sort-destructure-keys",
- "import",
+ "react",
+ "react-hooks",
+ "@typescript-eslint",
+ "typescript-sort-keys",
+ "sort-destructure-keys",
+ "import",
],
rules: {
- "linebreak-style": ["error", "unix"],
- quotes: ["warn", "double"],
- semi: ["warn", "always"],
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "error",
- "react/display-name": "off",
- "react/prop-types": "off",
- "no-unused-vars": "off", // disable the base rule as it can report incorrect errors
- "@typescript-eslint/consistent-type-imports": [
- "warn",
- { prefer: "type-imports" },
- ],
- "@typescript-eslint/no-unused-vars": [
- "warn",
- {
- vars: "all",
- args: "after-used",
- ignoreRestSiblings: true,
- },
- ],
- "no-unreachable": "warn",
- "typescript-sort-keys/interface": "warn",
- "typescript-sort-keys/string-enum": "warn",
- "sort-destructure-keys/sort-destructure-keys": [
- "warn",
- { caseSensitive: false },
- ],
- "react/jsx-sort-props": [
- "warn",
- {
- ignoreCase: true,
- reservedFirst: ["key", "children", "ref"],
- },
- ],
- "import/order": [
- "warn",
- {
- "newlines-between": "always",
- distinctGroup: true,
- alphabetize: {
- order: "asc",
- caseInsensitive: true,
- orderImportKind: "desc",
- },
- groups: [
- "builtin",
- "external",
- "parent",
- "sibling",
- "internal",
- "unknown",
- ],
- pathGroupsExcludedImportTypes: ["react"],
- pathGroups: [
- {
- pattern: "react",
- group: "builtin",
- position: "before",
- },
+ "linebreak-style": ["error", "unix"],
+ quotes: ["off"],
+ semi: ["warn", "always"],
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ "react/display-name": "off",
+ "react/prop-types": "off",
+ "no-unused-vars": "off", // disable the base rule as it can report incorrect errors
+ "@typescript-eslint/consistent-type-imports": [
+ "warn",
+ { prefer: "type-imports" },
+ ],
+ "@typescript-eslint/no-unused-vars": [
+ "warn",
{
- pattern: "([a-z]|@)**",
- group: "external",
+ vars: "all",
+ args: "after-used",
+ ignoreRestSiblings: true,
},
+ ],
+ "no-unreachable": "warn",
+ "typescript-sort-keys/interface": "warn",
+ "typescript-sort-keys/string-enum": "warn",
+ "sort-destructure-keys/sort-destructure-keys": [
+ "warn",
+ { caseSensitive: false },
+ ],
+ "react/jsx-sort-props": [
+ "warn",
{
- pattern: "**/styles",
- group: "internal",
- position: "before",
+ ignoreCase: true,
+ reservedFirst: ["key", "children", "ref"],
},
+ ],
+ "import/order": [
+ "warn",
{
- pattern: "**/types",
- group: "internal",
- position: "before",
+ "newlines-between": "always",
+ distinctGroup: true,
+ alphabetize: {
+ order: "asc",
+ caseInsensitive: true,
+ orderImportKind: "desc",
+ },
+ groups: [
+ "builtin",
+ "external",
+ "parent",
+ "sibling",
+ "internal",
+ "unknown",
+ ],
+ pathGroupsExcludedImportTypes: ["react"],
+ pathGroups: [
+ {
+ pattern: "react",
+ group: "builtin",
+ position: "before",
+ },
+ {
+ pattern: "([a-z]|@)**",
+ group: "external",
+ },
+ {
+ pattern: "**/styles",
+ group: "internal",
+ position: "before",
+ },
+ {
+ pattern: "**/types",
+ group: "internal",
+ position: "before",
+ },
+ {
+ pattern: "**/components/**",
+ group: "internal",
+ },
+ {
+ pattern: "**/utils/**",
+ group: "internal",
+ position: "after",
+ },
+ ],
},
- {
- pattern: "**/components/**",
- group: "internal",
- },
- {
- pattern: "**/utils/**",
- group: "internal",
- position: "after",
- },
- ],
- },
- ],
+ ],
},
- };
\ No newline at end of file
+};
diff --git a/README.md b/README.md
index ac6001c..7ce2e87 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[]()

[](https://www.npmjs.com/package/react-native-timer-picker)
-
+[](https://www.npmjs.com/package/react-native-timer-picker)
A simple, flexible, performant duration picker component for React Native apps 🔥
@@ -13,37 +13,37 @@ Works with Expo and bare React Native apps ✅
Includes iOS-style haptic and audio feedback 🍏
-- [Demos 📱](#demos-)
-- [Installation 🚀](#installation-)
-- [Peer Dependencies 👶](#peer-dependencies-)
- - [Linear Gradient](#linear-gradient)
- - [Masked View](#masked-view)
-- [Examples 😎](#examples-)
-- [Timer Picker Modal (Dark Mode) 🌚](#timer-picker-modal-dark-mode-)
-- [Timer Picker Modal (Light Mode) 🌞](#timer-picker-modal-light-mode-)
-- [Timer Picker Modal with Custom Buttons 🎨](#timer-picker-modal-with-custom-buttons-)
-- [Timer Picker with Transparent Fade-Out (Dark Mode) 🌒](#timer-picker-with-transparent-fade-out-dark-mode-)
-- [Timer Picker with Customisation (Light Mode) 🌔](#timer-picker-with-customisation-light-mode-)
-- [Props 💅](#props-)
-- [TimerPicker ⏲️](#timerpicker-️)
- - [Custom Styles 👗](#custom-styles-)
- - [Performance](#performance)
- - [Custom FlatList](#custom-flatlist)
-- [TimerPickerModal ⏰](#timerpickermodal-)
- - [Custom Styles 👕](#custom-styles--1)
-- [Methods 🔄](#methods-)
-- [TimerPicker](#timerpicker)
-- [TimerPickerModal](#timerpickermodal)
-- [Picker Feedback 📳🔉](#picker-feedback-)
-- [Audio Feedack](#audio-feedack)
-- [Haptic Feedback](#haptic-feedback)
-- [Feedback Example](#feedback-example)
-- [Expo-Specific Audio/Haptic Feedback (DEPRECATED)](#expo-specific-audiohaptic-feedback-deprecated)
-- [Contributing 🧑🤝🧑](#contributing-)
-- [Dev Setup](#dev-setup)
-- [GitHub Guidelines](#github-guidelines)
-- [Limitations ⚠](#limitations-)
-- [License 📝](#license-)
+ - [Demos 📱](#demos-)
+ - [Installation 🚀](#installation-)
+ - [Peer Dependencies 👶](#peer-dependencies-)
+ - [Linear Gradient](#linear-gradient)
+ - [Masked View](#masked-view)
+ - [Examples 😎](#examples-)
+ - [Timer Picker Modal (Dark Mode) 🌚](#timer-picker-modal-dark-mode-)
+ - [Timer Picker Modal (Light Mode) 🌞](#timer-picker-modal-light-mode-)
+ - [Timer Picker Modal with Custom Buttons 🎨](#timer-picker-modal-with-custom-buttons-)
+ - [Timer Picker with Transparent Fade-Out (Dark Mode) 🌒](#timer-picker-with-transparent-fade-out-dark-mode-)
+ - [Timer Picker with Customisation (Light Mode) 🌔](#timer-picker-with-customisation-light-mode-)
+ - [Props 💅](#props-)
+ - [TimerPicker ⏲️](#timerpicker-️)
+ - [Custom Styles 👗](#custom-styles-)
+ - [Performance](#performance)
+ - [Custom FlatList](#custom-flatlist)
+ - [TimerPickerModal ⏰](#timerpickermodal-)
+ - [Custom Styles 👕](#custom-styles--1)
+ - [Methods 🔄](#methods-)
+ - [TimerPicker](#timerpicker)
+ - [TimerPickerModal](#timerpickermodal)
+ - [Picker Feedback 📳🔉](#picker-feedback-)
+ - [Audio Feedack](#audio-feedack)
+ - [Haptic Feedback](#haptic-feedback)
+ - [Feedback Example](#feedback-example)
+ - [Expo-Specific Audio/Haptic Feedback (DEPRECATED)](#expo-specific-audiohaptic-feedback-deprecated)
+ - [Contributing 🧑🤝🧑](#contributing-)
+ - [Dev Setup](#dev-setup)
+ - [GitHub Guidelines](#github-guidelines)
+ - [Limitations ⚠](#limitations-)
+ - [License 📝](#license-)
@@ -99,7 +99,7 @@ To make the numbers fade in/out on a transparent background (e.g. if the picker
`import MaskedView from "@react-native-masked-view/masked-view";`
-**To enable the fade-out on a transparent background, you need to supply the imported `MaskedView` component AND one of the LinearGradient components as props to either TimerPickerModal or TimerPicker. (see [this example](#timer-picker-with-transparent-fade-out-dark-mode-))**
+**To enable the fade-out on a transparent background, you need to supply the imported `MaskedView` component AND one of the LinearGradient components as props to either TimerPickerModal or TimerPicker (see [this example](#timer-picker-with-transparent-fade-out-dark-mode-)).**
@@ -146,7 +146,7 @@ const formatTime = ({
return (
- {alarmStringExample !== null
+ {alarmString !== null
? "Alarm set for"
: "No alarm set"}
@@ -181,22 +181,22 @@ return (
setShowPicker(false)}
onConfirm={(pickedDuration) => {
setAlarmString(formatTime(pickedDuration));
setShowPicker(false);
}}
- modalTitle="Set Alarm"
- onCancel={() => setShowPicker(false)}
- closeOnOverlayPress
- LinearGradient={LinearGradient}
+ setIsVisible={setShowPicker}
styles={{
theme: "dark",
}}
- modalProps={{
- overlayOpacity: 0.2,
- }}
+ visible={showPicker}
/>
)
@@ -244,7 +244,7 @@ const formatTime = ({
return (
- {alarmStringExample !== null
+ {alarmString !== null
? "Alarm set for"
: "No alarm set"}
@@ -271,27 +271,27 @@ return (
borderColor: "#8C8C8C",
color: "#8C8C8C"
}}>
- Set Alarm 🔔
+ {"Set Alarm 🔔"}
setShowPicker(false)}
onConfirm={(pickedDuration) => {
setAlarmString(formatTime(pickedDuration));
setShowPicker(false);
}}
- modalTitle="Set Alarm"
- onCancel={() => setShowPicker(false)}
- closeOnOverlayPress
- use12HourPicker
- LinearGradient={LinearGradient}
+ setIsVisible={setShowPicker}
styles={{
theme: "light",
}}
+ use12HourPicker
+ visible={showPicker}
/>
)
@@ -305,15 +305,15 @@ return (
```jsx
import { TimerPickerModal } from "react-native-timer-picker";
import { LinearGradient } from "expo-linear-gradient"; // or `import LinearGradient from "react-native-linear-gradient"`
-import { TouchableOpacity, Text, StyleSheet, Platform } from "react-native";
+import { TouchableOpacity, Text, StyleSheet } from "react-native";
// Custom Button Component
-interface MyCustomButtonProps {
+interface CustomButtonProps {
label: string;
onPress?: () => void;
}
-const MyCustomButton: React.FC = ({ label, onPress }) => {
+const CustomButton: React.FC = ({ label, onPress }) => {
return (
}
+ closeOnOverlayPress
+ confirmButton={}
+ LinearGradient={LinearGradient}
+ modalProps={{
+ overlayOpacity: 0.2,
+ }}
+ modalTitle="Set Alarm"
+ onCancel={() => setShowPicker(false)}
onConfirm={(pickedDuration) => {
setAlarmString(formatTime(pickedDuration));
setShowPicker(false);
}}
- modalTitle="Set Alarm"
- onCancel={() => setShowPicker(false)}
- closeOnOverlayPress
- use12HourPicker
- LinearGradient={LinearGradient}
- // Custom buttons
- cancelButton={}
- confirmButton={}
+ setIsVisible={setShowPicker}
styles={{
- theme: "light",
+ theme: "dark",
}}
+ visible={showPicker}
/>
)
@@ -443,46 +444,36 @@ import MaskedView from "@react-native-masked-view/masked-view"; // for transpare
import { LinearGradient } from "expo-linear-gradient"; // or `import LinearGradient from "react-native-linear-gradient"`
....
-const [showPicker, setShowPicker] = useState(false);
-const [alarmString, setAlarmString] = useState<
- string | null
- >(null);
return (
@@ -500,33 +491,26 @@ import { TimerPicker } from "react-native-timer-picker";
import { LinearGradient } from "expo-linear-gradient"; // or `import LinearGradient from "react-native-linear-gradient"`
....
-const [showPicker, setShowPicker] = useState(false);
-const [alarmString, setAlarmString] = useState<
- string | null
- >(null);
return (
@@ -596,15 +580,21 @@ return (
| styles | Custom styles for the timer picker | [CustomTimerPickerStyles](#custom-styles-) | - | false |
| decelerationRate | Set how quickly the picker decelerates after the user lifts their finger | 'fast', 'normal', or Number | 0.88 | false |
-#### Custom Styles 👗
+#### Custom Styles 👗
-The following custom styles can be supplied to re-style the component in any way. Various styles are applied by default - you can take a look at these [here](src/components/TimerPicker/styles.ts).
+The component should look good straight out of the box, but you can use these styles to make it fit in with your App's theme:
| Style Prop | Description | Type |
| :------------------------------------: | :------------------------------------------------------------------- | :--------------------------------------: |
| theme | Theme of the component | "light" \| "dark" |
| backgroundColor | Main background color | string |
| text | Base text style | TextStyle |
+| labelOffsetPercentage | Percentage offset for horizonal label positioning relative to the picker | number |
+
+For deeper style customization, you can supply the following custom styles to adjust the component in any way. These are applied on top of the default styling so take a look at those [styles](src/components/TimerPicker/styles.ts) if something isn't adjusting in the way you'd expect.
+
+| Style Prop | Description | Type |
+| :------------------------------------: | :------------------------------------------------------------------- | :--------------------------------------: |
| pickerContainer | Main container for the picker | ViewStyle & { backgroundColor?: string } |
| pickerLabelContainer | Container for the picker's labels | ViewStyle |
| pickerLabel | Style for the picker's labels | TextStyle |
@@ -619,7 +609,7 @@ The following custom styles can be supplied to re-style the component in any way
| durationScrollFlatListContainer | Style for the View that contains the Flatlist in each picker | ViewStyle |
| durationScrollFlatListContentContainer | Style for the Flatlist's `contentContainerStyle` prop in each picker | ViewStyle |
-Note the minor limitations to the allowed styles for `pickerContainer` and `pickerItemContainer`. These are made because these styles are used for internal calculations and all possible `backgroundColor`/`height` types are not supported.
+**Note:** There are minor limitations on `pickerContainer.backgroundColor` and `pickerItemContainer.height`. These properties must be simple values (string and number respectively) as they are used in internal calculations for scroll positioning, gradient overlays, and snap behavior. Complex computed values or union types are not supported for these specific properties.
#### Performance
@@ -680,17 +670,18 @@ The TimerPickerModal component accepts all [TimerPicker props](#timerpicker-️)
#### Custom Styles 👕
-The following custom styles can be supplied to re-style the component in any way. You can also supply all of the styles specified in [CustomTimerPickerStyles](#custom-styles-). Various styles are applied by default - you can take a look at these [here](src/components/TimerPickerModal/styles.ts).
+The following custom styles can be supplied to re-style the component in any way. You can also supply all of the styles specified in [CustomTimerPickerStyles](#custom-styles-). These are applied on top of the default styling so take a look at those [styles](src/components/TimerPickerModal/styles.ts) if something isn't adjusting in the way you'd expect.
| Style Prop | Description | Type |
| :--------------: | :----------------------------------------- | :-------: |
-| container | Main container's style | ViewStyle |
-| contentContainer | Style for the content's container | ViewStyle |
-| buttonContainer | Style for the container around the buttons | ViewStyle |
+| container | Style for the modal container | ViewStyle |
+| contentContainer | Style for the modal content's container | ViewStyle |
+| buttonContainer | Style for the container for the buttons | ViewStyle |
| button | General style for both buttons | TextStyle |
| cancelButton | Style for the cancel button | TextStyle |
| confirmButton | Style for the confirm button | TextStyle |
| modalTitle | Style for the title of the modal | TextStyle |
+| ... | Supply any of [TimerPicker's custom styles]((#custom-styles-)) | - |
diff --git a/examples/example-bare/App.tsx b/examples/example-bare/App.tsx
index 6c08180..3fa18b9 100644
--- a/examples/example-bare/App.tsx
+++ b/examples/example-bare/App.tsx
@@ -238,7 +238,7 @@ export default function App() {
styles.page3Container,
{ width: screenWidth },
]}>
-
+
{alarmStringExample3 !== null
? "Alarm set for"
: "No alarm set"}
@@ -248,7 +248,7 @@ export default function App() {
onPress={() => setShowPickerExample3(true)}>
{alarmStringExample3 !== null ? (
-
+
{alarmStringExample3}
) : null}
@@ -257,7 +257,7 @@ export default function App() {
onPress={() => setShowPickerExample3(true)}>
+ style={[styles.button, styles.buttonLight]}>
{"Set Alarm 🔔"}
@@ -295,11 +295,7 @@ export default function App() {
colors={["#202020", "#220578"]}
end={{ x: 1, y: 1 }}
start={{ x: 0, y: 0 }}
- style={[
- styles.container,
- styles.page4Container,
- { width: screenWidth },
- ]}>
+ style={[styles.container, { width: screenWidth }]}>
@@ -354,18 +344,15 @@ export default function App() {
secondLabel="sec"
styles={{
theme: "light",
+ labelOffsetPercentage: 0,
pickerItem: {
fontSize: 34,
},
pickerLabel: {
fontSize: 26,
- right: -20,
},
- pickerLabelContainer: {
- width: 60,
- },
- pickerItemContainer: {
- width: 150,
+ pickerContainer: {
+ paddingHorizontal: 50,
},
}}
/>
@@ -402,9 +389,6 @@ const styles = StyleSheet.create({
page3Container: {
backgroundColor: "#F1F1F1",
},
- page4Container: {
- flex: 1,
- },
page5Container: {
backgroundColor: "#F1F1F1",
},
@@ -443,4 +427,15 @@ const styles = StyleSheet.create({
buttonContainer: {
marginTop: 30,
},
+ chevronPressable: {
+ justifyContent: "center",
+ alignItems: "center",
+ position: "absolute",
+ top: 0,
+ bottom: 0,
+ padding: 8,
+ },
+ chevronPressable_pressed: {
+ opacity: 0.7,
+ },
});
diff --git a/examples/example-expo/App.tsx b/examples/example-expo/App.tsx
index e3d7eb3..bd7b689 100644
--- a/examples/example-expo/App.tsx
+++ b/examples/example-expo/App.tsx
@@ -12,13 +12,11 @@ import * as Haptics from "expo-haptics";
import { LinearGradient } from "expo-linear-gradient";
import {
LayoutAnimation,
- Platform,
Pressable,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
- UIManager,
View,
useWindowDimensions,
} from "react-native";
@@ -31,10 +29,6 @@ import { CustomButton } from "./components/CustomButton";
import { formatTime } from "./utils/formatTime";
// import { getClickSound } from "./utils/getClickSound";
-if (Platform.OS === "android") {
- UIManager.setLayoutAnimationEnabledExperimental?.(true);
-}
-
export default function App() {
const { width: screenWidth } = useWindowDimensions();
@@ -158,9 +152,7 @@ export default function App() {
setShowPickerExample1(false)}
onConfirm={(pickedDuration) => {
@@ -169,9 +161,7 @@ export default function App() {
}}
pickerFeedback={pickerFeedback}
setIsVisible={setShowPickerExample1}
- styles={{
- theme: "dark",
- }}
+ styles={{ theme: "dark" }}
visible={showPickerExample1}
/>
@@ -223,9 +213,7 @@ export default function App() {
}}
pickerFeedback={pickerFeedback}
setIsVisible={setShowPickerExample2}
- styles={{
- theme: "light",
- }}
+ styles={{ theme: "light" }}
use12HourPicker
visible={showPickerExample2}
/>
@@ -272,9 +260,7 @@ export default function App() {
closeOnOverlayPress
confirmButton={}
LinearGradient={LinearGradient}
- modalProps={{
- overlayOpacity: 0.2,
- }}
+ modalProps={{ overlayOpacity: 0.2 }}
modalTitle="Set Alarm"
onCancel={() => setShowPickerExample3(false)}
onConfirm={(pickedDuration) => {
@@ -283,9 +269,7 @@ export default function App() {
}}
pickerFeedback={pickerFeedback}
setIsVisible={setShowPickerExample3}
- styles={{
- theme: "dark",
- }}
+ styles={{ theme: "dark" }}
visible={showPickerExample3}
/>
@@ -298,11 +282,7 @@ export default function App() {
colors={["#202020", "#220578"]}
end={{ x: 1, y: 1 }}
start={{ x: 0, y: 0 }}
- style={[
- styles.container,
- styles.page4Container,
- { width: screenWidth },
- ]}>
+ style={[styles.container, { width: screenWidth }]}>
@@ -357,18 +331,15 @@ export default function App() {
secondLabel="sec"
styles={{
theme: "light",
+ labelOffsetPercentage: 0,
pickerItem: {
fontSize: 34,
},
pickerLabel: {
fontSize: 26,
- right: -20,
- },
- pickerLabelContainer: {
- width: 60,
},
- pickerItemContainer: {
- width: 150,
+ pickerContainer: {
+ paddingHorizontal: 50,
},
}}
/>
@@ -377,9 +348,16 @@ export default function App() {
}, [pickerFeedback, screenWidth]);
const renderNavigationArrows = useMemo(() => {
+ const pageIndicesWithDarkBackground = [0, 3];
+ const isDarkBackground =
+ pageIndicesWithDarkBackground.includes(currentPageIndex);
+
+ const isFinalPage = currentPageIndex === 4;
+ const isFirstPage = currentPageIndex === 0;
+
return (
<>
- {currentPageIndex !== 4 ? (
+ {!isFinalPage ? (
{
LayoutAnimation.configureNext(
@@ -399,17 +377,13 @@ export default function App() {
pressed && styles.chevronPressable_pressed,
]}>
) : null}
- {currentPageIndex !== 0 ? (
+ {!isFirstPage ? (
{
LayoutAnimation.configureNext(
@@ -429,11 +403,7 @@ export default function App() {
pressed && styles.chevronPressable_pressed,
]}>
@@ -475,9 +445,6 @@ const styles = StyleSheet.create({
page3Container: {
backgroundColor: "#F1F1F1",
},
- page4Container: {
- flex: 1,
- },
page5Container: {
backgroundColor: "#F1F1F1",
},
diff --git a/examples/example-expo/components/CustomButton.tsx b/examples/example-expo/components/CustomButton.tsx
index 21d0187..4eb0279 100644
--- a/examples/example-expo/components/CustomButton.tsx
+++ b/examples/example-expo/components/CustomButton.tsx
@@ -29,7 +29,7 @@ export const CustomButton: React.FC = ({
const styles = StyleSheet.create({
customButtonContainer: {
- marginHorizontal: 5,
+ marginHorizontal: 12,
},
customButtonGradient: {
borderRadius: 15,
diff --git a/examples/example-expo/package.json b/examples/example-expo/package.json
index 06cf3e5..69a06f9 100644
--- a/examples/example-expo/package.json
+++ b/examples/example-expo/package.json
@@ -13,11 +13,11 @@
"dependencies": {
"@expo/vector-icons": "^15.0.3",
"@react-native-masked-view/masked-view": "0.3.2",
- "expo": "54.0.23",
- "expo-asset": "~12.0.9",
- "expo-font": "~14.0.9",
- "expo-haptics": "~15.0.7",
- "expo-linear-gradient": "~15.0.7",
+ "expo": "~54.0.29",
+ "expo-asset": "~12.0.11",
+ "expo-font": "~14.0.10",
+ "expo-haptics": "~15.0.8",
+ "expo-linear-gradient": "~15.0.8",
"react": "19.1.0",
"react-native": "0.81.5",
"react-native-audio-api": "0.9.0"
diff --git a/package.json b/package.json
index d2cda29..583f4ec 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"url": "https://github.com/troberts-28"
},
"license": "MIT",
- "version": "2.3.1",
+ "version": "2.4.0",
"main": "dist/commonjs/index.js",
"module": "dist/module/index.js",
"types": "dist/typescript/index.d.ts",
diff --git a/src/components/DurationScroll/DurationScroll.tsx b/src/components/DurationScroll/DurationScroll.tsx
index 5d770ab..a07b45c 100644
--- a/src/components/DurationScroll/DurationScroll.tsx
+++ b/src/components/DurationScroll/DurationScroll.tsx
@@ -22,6 +22,7 @@ import {
import { getAdjustedLimit } from "../../utils/getAdjustedLimit";
import { getDurationAndIndexFromScrollOffset } from "../../utils/getDurationAndIndexFromScrollOffset";
import { getInitialScrollIndex } from "../../utils/getInitialScrollIndex";
+import PickerItem from "../PickerItem";
import type {
DurationScrollProps,
@@ -215,49 +216,18 @@ const DurationScroll = forwardRef(
const renderItem = useCallback<
NonNullable["renderItem"]>
>(
- ({ item }) => {
- let stringItem = item;
- let intItem: number;
- let isAm: boolean | undefined;
-
- if (!is12HourPicker) {
- intItem = parseInt(item);
- } else {
- isAm = item.includes("AM");
- stringItem = item.replace(/\s[AP]M/g, "");
- intItem = parseInt(stringItem);
- }
-
- return (
-
- adjustedLimited.max ||
- intItem < adjustedLimited.min
- ? styles.disabledPickerItem
- : {},
- ]}>
- {stringItem}
-
- {is12HourPicker ? (
-
-
- {isAm ? amLabel : pmLabel}
-
-
- ) : null}
-
- );
- },
+ ({ item }) => (
+
+ ),
[
adjustedLimited.max,
adjustedLimited.min,
@@ -265,11 +235,7 @@ const DurationScroll = forwardRef(
amLabel,
is12HourPicker,
pmLabel,
- styles.disabledPickerItem,
- styles.pickerAmPmContainer,
- styles.pickerAmPmLabel,
- styles.pickerItem,
- styles.pickerItemContainer,
+ styles,
]
);
@@ -577,6 +543,7 @@ const DurationScroll = forwardRef(
}, [
FlatList,
allowFontScaling,
+ decelerationRate,
flatListRenderKey,
getItemLayout,
initialScrollIndex,
@@ -593,7 +560,6 @@ const DurationScroll = forwardRef(
styles.pickerLabel,
styles.pickerLabelContainer,
viewabilityConfigCallbackPairs,
- decelerationRate,
]);
const renderLinearGradient = useMemo(() => {
diff --git a/src/components/PickerItem/PickerItem.tsx b/src/components/PickerItem/PickerItem.tsx
new file mode 100644
index 0000000..ccef3a8
--- /dev/null
+++ b/src/components/PickerItem/PickerItem.tsx
@@ -0,0 +1,71 @@
+import React from "react";
+
+import { View, Text } from "react-native";
+
+import type { generateStyles } from "../TimerPicker/styles";
+
+interface PickerItemProps {
+ adjustedLimitedMax: number;
+ adjustedLimitedMin: number;
+ allowFontScaling: boolean;
+ amLabel?: string;
+ is12HourPicker?: boolean;
+ item: string;
+ pmLabel?: string;
+ styles: ReturnType;
+}
+
+const PickerItem = React.memo(
+ ({
+ adjustedLimitedMax,
+ adjustedLimitedMin,
+ allowFontScaling,
+ amLabel,
+ is12HourPicker,
+ item,
+ pmLabel,
+ styles,
+ }) => {
+ let stringItem = item;
+ let intItem: number;
+ let isAm: boolean | undefined;
+
+ if (!is12HourPicker) {
+ intItem = parseInt(item);
+ } else {
+ isAm = item.includes("AM");
+ stringItem = item.replace(/\s[AP]M/g, "");
+ intItem = parseInt(stringItem);
+ }
+
+ return (
+
+ adjustedLimitedMax ||
+ intItem < adjustedLimitedMin
+ ? styles.disabledPickerItem
+ : {},
+ ]}>
+ {stringItem}
+
+ {is12HourPicker && (
+
+
+ {isAm ? amLabel : pmLabel}
+
+
+ )}
+
+ );
+ }
+);
+
+export default PickerItem;
diff --git a/src/components/PickerItem/index.ts b/src/components/PickerItem/index.ts
new file mode 100644
index 0000000..7006f50
--- /dev/null
+++ b/src/components/PickerItem/index.ts
@@ -0,0 +1 @@
+export { default } from "./PickerItem";
diff --git a/src/components/TimerPicker/TimerPicker.tsx b/src/components/TimerPicker/TimerPicker.tsx
index f9d5080..652a3f1 100644
--- a/src/components/TimerPicker/TimerPicker.tsx
+++ b/src/components/TimerPicker/TimerPicker.tsx
@@ -69,17 +69,17 @@ const TimerPicker = forwardRef(
useEffect(() => {
if (otherProps.Audio) {
console.warn(
- "The \"Audio\" prop is deprecated and will be removed in a future version. Please use the \"pickerFeedback\" prop instead."
+ 'The "Audio" prop is deprecated and will be removed in a future version. Please use the "pickerFeedback" prop instead.'
);
}
if (otherProps.Haptics) {
console.warn(
- "The \"Haptics\" prop is deprecated and will be removed in a future version. Please use the \"pickerFeedback\" prop instead."
+ 'The "Haptics" prop is deprecated and will be removed in a future version. Please use the "pickerFeedback" prop instead.'
);
}
if (otherProps.clickSoundAsset) {
console.warn(
- "The \"clickSoundAsset\" prop is deprecated and will be removed in a future version. Please use the \"pickerFeedback\" prop instead."
+ 'The "clickSoundAsset" prop is deprecated and will be removed in a future version. Please use the "pickerFeedback" prop instead.'
);
}
}, [otherProps.Audio, otherProps.Haptics, otherProps.clickSoundAsset]);
diff --git a/src/components/TimerPicker/styles.ts b/src/components/TimerPicker/styles.ts
index 4f39bd2..24c9748 100644
--- a/src/components/TimerPicker/styles.ts
+++ b/src/components/TimerPicker/styles.ts
@@ -8,6 +8,7 @@ export interface CustomTimerPickerStyles {
durationScrollFlatList?: ViewStyle;
durationScrollFlatListContainer?: ViewStyle;
durationScrollFlatListContentContainer?: ViewStyle;
+ labelOffsetPercentage?: number;
pickerAmPmContainer?: ViewStyle;
pickerAmPmLabel?: TextStyle;
pickerContainer?: ViewStyle & { backgroundColor?: string };
@@ -27,41 +28,67 @@ const LIGHT_MODE_TEXT_COLOR = "#1B1B1B";
export const generateStyles = (
customStyles: CustomTimerPickerStyles | undefined
-) =>
- StyleSheet.create({
+) => {
+ const backgroundColor =
+ customStyles?.backgroundColor ??
+ (customStyles?.theme === "dark"
+ ? DARK_MODE_BACKGROUND_COLOR
+ : LIGHT_MODE_BACKGROUND_COLOR);
+
+ const textColor =
+ customStyles?.theme === "dark"
+ ? DARK_MODE_TEXT_COLOR
+ : LIGHT_MODE_TEXT_COLOR;
+
+ const pickerLabelFontSize =
+ customStyles?.pickerLabel?.fontSize ??
+ customStyles?.text?.fontSize ??
+ 18;
+ const pickerAmPmFontSize =
+ customStyles?.pickerAmPmLabel?.fontSize ??
+ customStyles?.pickerLabel?.fontSize ??
+ customStyles?.text?.fontSize ??
+ 18;
+ const pickerItemFontSize =
+ customStyles?.pickerItem?.fontSize ??
+ customStyles?.text?.fontSize ??
+ 25;
+
+ // This offset makes the picker label appear to be aligned with the picker item
+ // despite them having different font sizes
+ const pickerLabelVerticalOffset =
+ pickerItemFontSize - pickerLabelFontSize - 1;
+ const pickerAmPmVerticalOffset =
+ pickerItemFontSize - pickerAmPmFontSize - 1;
+
+ // The label is absolutely positioned, so we need to offset it for it to appear
+ // in the correct position. We offset it to the left of the container so that
+ // the width of the label doesn't impact its position.
+ const extraLabelOffsetPercentage = customStyles?.labelOffsetPercentage ?? 8;
+ const baseLeftOffsetPercentage = 70;
+ const labelOffsetPercentage =
+ baseLeftOffsetPercentage + extraLabelOffsetPercentage;
+
+ return StyleSheet.create({
pickerContainer: {
flexDirection: "row",
- marginRight: "8%",
- backgroundColor:
- customStyles?.backgroundColor ??
- (customStyles?.theme === "dark"
- ? DARK_MODE_BACKGROUND_COLOR
- : LIGHT_MODE_BACKGROUND_COLOR),
+ backgroundColor,
+ width: "100%",
...customStyles?.pickerContainer,
},
pickerLabelContainer: {
position: "absolute",
- right: 4,
top: 0,
bottom: 0,
+ left: `${labelOffsetPercentage}%`,
justifyContent: "center",
- minWidth:
- (customStyles?.pickerLabel?.fontSize ??
- customStyles?.text?.fontSize ??
- 25) * 0.65,
+ marginTop: pickerLabelVerticalOffset,
...customStyles?.pickerLabelContainer,
},
pickerLabel: {
fontSize: 18,
fontWeight: "bold",
- marginTop:
- (customStyles?.pickerItem?.fontSize ??
- customStyles?.text?.fontSize ??
- 25) / 6,
- color:
- customStyles?.theme === "dark"
- ? DARK_MODE_TEXT_COLOR
- : LIGHT_MODE_TEXT_COLOR,
+ color: textColor,
...customStyles?.text,
...customStyles?.pickerLabel,
},
@@ -70,36 +97,30 @@ export const generateStyles = (
height: 50,
justifyContent: "center",
alignItems: "center",
- width: (customStyles?.pickerItem?.fontSize ?? 25) * 3.6,
...customStyles?.pickerItemContainer,
},
pickerItem: {
textAlignVertical: "center",
fontSize: 25,
- color:
- customStyles?.theme === "dark"
- ? DARK_MODE_TEXT_COLOR
- : LIGHT_MODE_TEXT_COLOR,
+ overflow: "visible",
+ color: textColor,
...customStyles?.text,
...customStyles?.pickerItem,
},
pickerAmPmContainer: {
position: "absolute",
- right: 0,
top: 0,
bottom: 0,
+ left: `${labelOffsetPercentage}%`,
justifyContent: "center",
+ marginTop: pickerAmPmVerticalOffset,
...customStyles?.pickerLabelContainer,
...customStyles?.pickerAmPmContainer,
},
pickerAmPmLabel: {
fontSize: 18,
fontWeight: "bold",
- marginTop: (customStyles?.pickerItem?.fontSize ?? 25) / 6,
- color:
- customStyles?.theme === "dark"
- ? DARK_MODE_TEXT_COLOR
- : LIGHT_MODE_TEXT_COLOR,
+ color: textColor,
...customStyles?.text,
...customStyles?.pickerLabel,
...customStyles?.pickerAmPmLabel,
@@ -121,16 +142,19 @@ export const generateStyles = (
height: "100%",
...customStyles?.pickerGradientOverlay,
},
- durationScrollFlatList: {
- minWidth: 1,
- width: "300%",
- ...customStyles?.durationScrollFlatList,
- },
durationScrollFlatListContainer: {
- overflow: "visible",
+ flex: 1,
...customStyles?.durationScrollFlatListContainer,
},
+ durationScrollFlatList: {
+ // These paddings allow the inner am/pm label to
+ // spill out of the flatlist
+ paddingRight: "25%",
+ marginRight: "-25%",
+ ...customStyles?.durationScrollFlatList,
+ },
durationScrollFlatListContentContainer: {
...customStyles?.durationScrollFlatListContentContainer,
},
});
+};
diff --git a/src/components/TimerPickerModal/styles.ts b/src/components/TimerPickerModal/styles.ts
index 1f1147a..7fb4790 100644
--- a/src/components/TimerPickerModal/styles.ts
+++ b/src/components/TimerPickerModal/styles.ts
@@ -1,5 +1,5 @@
import { StyleSheet } from "react-native";
-import type { TextStyle, ViewStyle } from "react-native";
+import type { DimensionValue, TextStyle, ViewStyle } from "react-native";
import type { CustomTimerPickerStyles } from "../TimerPicker/styles";
@@ -40,10 +40,6 @@ export const generateStyles = (
justifyContent: "center",
overflow: "hidden",
...customContainerStyle,
- // disable setting alignItems here because it can affect
- // the FlatList's ability to calculate its layout, which can
- // stop snapToOffsets working properly
- alignItems: undefined,
},
contentContainer: {
backgroundColor:
@@ -55,12 +51,8 @@ export const generateStyles = (
alignItems: "center",
borderRadius: 20,
overflow: "hidden",
+ paddingHorizontal: 20,
...customContentContainerStyle,
- // disable setting padding here because it can affect
- // the FlatList's ability to calculate its layout, which can
- // stop snapToOffsets working properly
- paddingHorizontal: 0,
- paddingVertical: 0,
},
buttonContainer: {
flexDirection: "row",
@@ -116,10 +108,7 @@ export const generateStyles = (
timerPickerStyles: {
...customTimerPickerStyles,
pickerContainer: {
- // set padding here instead of on modal content container because it can affect
- // the FlatList's ability to calculate its layout, which can
- // stop snapToOffsets working properly
- paddingHorizontal: 20,
+ marginRight: "8%" as DimensionValue,
paddingTop: !variables?.hasModalTitle ? 20 : 0,
...(customTimerPickerStyles?.pickerContainer ?? {}),
},
diff --git a/src/tests/generateNumbers.test.ts b/src/tests/generateNumbers.test.ts
index 5ded2a4..79afc13 100644
--- a/src/tests/generateNumbers.test.ts
+++ b/src/tests/generateNumbers.test.ts
@@ -22,7 +22,7 @@ describe("generateNumbers", () => {
repeatNTimes: 1,
disableInfiniteScroll: true,
});
- expect(result).toEqual([" 0", " 2", " 4", " 6", " 8"]);
+ expect(result).toEqual(["\u20070", "\u20072", "\u20074", "\u20076", "\u20078"]);
});
it("generates numbers with interval of 5", () => {
@@ -32,7 +32,7 @@ describe("generateNumbers", () => {
repeatNTimes: 1,
disableInfiniteScroll: true,
});
- expect(result).toEqual([" 0", " 5", "10", "15"]);
+ expect(result).toEqual(["\u20070", "\u20075", "10", "15"]);
});
it("returns empty array when numberOfItems is 0", () => {
@@ -88,7 +88,7 @@ describe("generateNumbers", () => {
padNumbersWithZero: false,
disableInfiniteScroll: true,
});
- expect(result).toEqual([" 0", " 1", " 2", " 3", " 4"]);
+ expect(result).toEqual(["\u20070", "\u20071", "\u20072", "\u20073", "\u20074"]);
});
});
@@ -100,7 +100,7 @@ describe("generateNumbers", () => {
repeatNTimes: 1,
disableInfiniteScroll: true,
});
- expect(result).toEqual(["", "", " 0", " 1", " 2", "", ""]);
+ expect(result).toEqual(["", "", "\u20070", "\u20071", "\u20072", "", ""]);
expect(result).toHaveLength(7);
});
@@ -111,7 +111,7 @@ describe("generateNumbers", () => {
repeatNTimes: 1,
disableInfiniteScroll: true,
});
- expect(result).toEqual(["", " 0", " 1", " 2", ""]);
+ expect(result).toEqual(["", "\u20070", "\u20071", "\u20072", ""]);
});
it("adds padding with 3 items", () => {
@@ -121,7 +121,7 @@ describe("generateNumbers", () => {
repeatNTimes: 1,
disableInfiniteScroll: true,
});
- expect(result).toEqual(["", "", "", " 0", " 1", "", "", ""]);
+ expect(result).toEqual(["", "", "", "\u20070", "\u20071", "", "", ""]);
});
});
@@ -133,7 +133,7 @@ describe("generateNumbers", () => {
repeatNTimes: 2,
disableInfiniteScroll: false,
});
- expect(result).toEqual([" 0", " 1", " 2", " 0", " 1", " 2"]);
+ expect(result).toEqual(["\u20070", "\u20071", "\u20072", "\u20070", "\u20071", "\u20072"]);
});
it("repeats numbers when repeatNTimes is 3", () => {
@@ -143,7 +143,7 @@ describe("generateNumbers", () => {
repeatNTimes: 3,
disableInfiniteScroll: false,
});
- expect(result).toEqual([" 0", " 1", " 0", " 1", " 0", " 1"]);
+ expect(result).toEqual(["\u20070", "\u20071", "\u20070", "\u20071", "\u20070", "\u20071"]);
});
});
@@ -192,7 +192,7 @@ describe("generate12HourNumbers", () => {
disableInfiniteScroll: false,
});
expect(result).toHaveLength(24);
- expect(result[0]).toBe(" 0 AM");
+ expect(result[0]).toBe("12 AM");
expect(result[11]).toBe("11 AM");
expect(result[12]).toBe("12 PM");
expect(result[23]).toBe("11 PM");
@@ -205,7 +205,7 @@ describe("generate12HourNumbers", () => {
disableInfiniteScroll: false,
});
expect(result).toHaveLength(12);
- expect(result[0]).toBe(" 0 AM");
+ expect(result[0]).toBe("12 AM");
expect(result[5]).toBe("10 AM");
expect(result[6]).toBe("12 PM");
expect(result[11]).toBe("10 PM");
@@ -218,10 +218,10 @@ describe("generate12HourNumbers", () => {
disableInfiniteScroll: false,
});
expect(result).toHaveLength(8);
- expect(result[0]).toBe(" 0 AM");
- expect(result[3]).toBe(" 9 AM");
+ expect(result[0]).toBe("12 AM");
+ expect(result[3]).toBe("\u20079 AM");
expect(result[4]).toBe("12 PM");
- expect(result[7]).toBe(" 9 PM");
+ expect(result[7]).toBe("\u20079 PM");
});
it("generates hours with 4-hour interval", () => {
@@ -231,10 +231,10 @@ describe("generate12HourNumbers", () => {
disableInfiniteScroll: false,
});
expect(result).toHaveLength(6);
- expect(result[0]).toBe(" 0 AM");
- expect(result[2]).toBe(" 8 AM");
+ expect(result[0]).toBe("12 AM");
+ expect(result[2]).toBe("\u20078 AM");
expect(result[3]).toBe("12 PM");
- expect(result[5]).toBe(" 8 PM");
+ expect(result[5]).toBe("\u20078 PM");
});
it("generates hours with 6-hour interval", () => {
@@ -244,10 +244,10 @@ describe("generate12HourNumbers", () => {
disableInfiniteScroll: false,
});
expect(result).toHaveLength(4);
- expect(result[0]).toBe(" 0 AM");
- expect(result[1]).toBe(" 6 AM");
+ expect(result[0]).toBe("12 AM");
+ expect(result[1]).toBe("\u20076 AM");
expect(result[2]).toBe("12 PM");
- expect(result[3]).toBe(" 6 PM");
+ expect(result[3]).toBe("\u20076 PM");
});
});
@@ -259,7 +259,7 @@ describe("generate12HourNumbers", () => {
padNumbersWithZero: true,
disableInfiniteScroll: false,
});
- expect(result[0]).toBe("00 AM");
+ expect(result[0]).toBe("12 AM");
expect(result[1]).toBe("01 AM");
expect(result[9]).toBe("09 AM");
expect(result[10]).toBe("10 AM");
@@ -287,10 +287,10 @@ describe("generate12HourNumbers", () => {
});
expect(result[0]).toBe("");
expect(result[1]).toBe("");
- expect(result[2]).toBe(" 0 AM");
- expect(result[3]).toBe(" 6 AM");
+ expect(result[2]).toBe("12 AM");
+ expect(result[3]).toBe("\u20076 AM");
expect(result[4]).toBe("12 PM");
- expect(result[5]).toBe(" 6 PM");
+ expect(result[5]).toBe("\u20076 PM");
expect(result[6]).toBe("");
expect(result[7]).toBe("");
expect(result).toHaveLength(8);
@@ -302,8 +302,8 @@ describe("generate12HourNumbers", () => {
padWithNItems: 2,
disableInfiniteScroll: false,
});
- expect(result[0]).toBe(" 0 AM");
- expect(result[3]).toBe(" 6 PM");
+ expect(result[0]).toBe("12 AM");
+ expect(result[3]).toBe("\u20076 PM");
expect(result).toHaveLength(4);
});
});
@@ -317,10 +317,10 @@ describe("generate12HourNumbers", () => {
disableInfiniteScroll: false,
});
expect(result).toHaveLength(8);
- expect(result[0]).toBe(" 0 AM");
- expect(result[3]).toBe(" 6 PM");
- expect(result[4]).toBe(" 0 AM");
- expect(result[7]).toBe(" 6 PM");
+ expect(result[0]).toBe("12 AM");
+ expect(result[3]).toBe("\u20076 PM");
+ expect(result[4]).toBe("12 AM");
+ expect(result[7]).toBe("\u20076 PM");
});
it("repeats hours when repeatNTimes is 3", () => {
@@ -331,11 +331,11 @@ describe("generate12HourNumbers", () => {
disableInfiniteScroll: false,
});
expect(result).toHaveLength(6);
- expect(result[0]).toBe(" 0 AM");
+ expect(result[0]).toBe("12 AM");
expect(result[1]).toBe("12 PM");
- expect(result[2]).toBe(" 0 AM");
+ expect(result[2]).toBe("12 AM");
expect(result[3]).toBe("12 PM");
- expect(result[4]).toBe(" 0 AM");
+ expect(result[4]).toBe("12 AM");
expect(result[5]).toBe("12 PM");
});
@@ -357,7 +357,7 @@ describe("generate12HourNumbers", () => {
padNumbersWithZero: true,
disableInfiniteScroll: true,
});
- expect(result).toEqual(["", "00 AM", "12 PM", ""]);
+ expect(result).toEqual(["", "12 AM", "12 PM", ""]);
});
it("combines all options", () => {
@@ -369,11 +369,11 @@ describe("generate12HourNumbers", () => {
disableInfiniteScroll: false,
});
expect(result).toHaveLength(8);
- expect(result[0]).toBe("00 AM");
+ expect(result[0]).toBe("12 AM");
expect(result[1]).toBe("06 AM");
expect(result[2]).toBe("12 PM");
expect(result[3]).toBe("06 PM");
- expect(result[4]).toBe("00 AM");
+ expect(result[4]).toBe("12 AM");
expect(result[7]).toBe("06 PM");
});
});
diff --git a/src/tests/padNumber.test.ts b/src/tests/padNumber.test.ts
index 30df52c..a57c8b5 100644
--- a/src/tests/padNumber.test.ts
+++ b/src/tests/padNumber.test.ts
@@ -29,10 +29,10 @@ describe("padNumber", () => {
describe("padding with space", () => {
it("pads single digit with space", () => {
- expect(padNumber(0, { padWithZero: false })).toBe(" 0");
- expect(padNumber(1, { padWithZero: false })).toBe(" 1");
- expect(padNumber(5, { padWithZero: false })).toBe(" 5");
- expect(padNumber(9, { padWithZero: false })).toBe(" 9");
+ expect(padNumber(0, { padWithZero: false })).toBe("\u20070");
+ expect(padNumber(1, { padWithZero: false })).toBe("\u20071");
+ expect(padNumber(5, { padWithZero: false })).toBe("\u20075");
+ expect(padNumber(9, { padWithZero: false })).toBe("\u20079");
});
it("does not pad double digits", () => {
@@ -55,10 +55,10 @@ describe("padNumber", () => {
describe("no options provided", () => {
it("defaults to space padding for single digits", () => {
- expect(padNumber(0)).toBe(" 0");
- expect(padNumber(1)).toBe(" 1");
- expect(padNumber(5)).toBe(" 5");
- expect(padNumber(9)).toBe(" 9");
+ expect(padNumber(0)).toBe("\u20070");
+ expect(padNumber(1)).toBe("\u20071");
+ expect(padNumber(5)).toBe("\u20075");
+ expect(padNumber(9)).toBe("\u20079");
});
it("does not pad double digits", () => {
@@ -76,9 +76,9 @@ describe("padNumber", () => {
describe("undefined padWithZero option", () => {
it("defaults to space padding", () => {
- expect(padNumber(0, {})).toBe(" 0");
- expect(padNumber(5, {})).toBe(" 5");
- expect(padNumber(9, {})).toBe(" 9");
+ expect(padNumber(0, {})).toBe("\u20070");
+ expect(padNumber(5, {})).toBe("\u20075");
+ expect(padNumber(9, {})).toBe("\u20079");
});
it("does not pad double digits", () => {
@@ -90,8 +90,8 @@ describe("padNumber", () => {
describe("edge cases at boundary", () => {
it("handles value exactly 9 (last single digit)", () => {
expect(padNumber(9, { padWithZero: true })).toBe("09");
- expect(padNumber(9, { padWithZero: false })).toBe(" 9");
- expect(padNumber(9)).toBe(" 9");
+ expect(padNumber(9, { padWithZero: false })).toBe("\u20079");
+ expect(padNumber(9)).toBe("\u20079");
});
it("handles value exactly 10 (first double digit)", () => {
@@ -102,8 +102,8 @@ describe("padNumber", () => {
it("handles value exactly 0", () => {
expect(padNumber(0, { padWithZero: true })).toBe("00");
- expect(padNumber(0, { padWithZero: false })).toBe(" 0");
- expect(padNumber(0)).toBe(" 0");
+ expect(padNumber(0, { padWithZero: false })).toBe("\u20070");
+ expect(padNumber(0)).toBe("\u20070");
});
});
@@ -134,8 +134,8 @@ describe("padNumber", () => {
});
it("formats days without padding preference", () => {
- expect(padNumber(1, { padWithZero: false })).toBe(" 1");
- expect(padNumber(7, { padWithZero: false })).toBe(" 7");
+ expect(padNumber(1, { padWithZero: false })).toBe("\u20071");
+ expect(padNumber(7, { padWithZero: false })).toBe("\u20077");
expect(padNumber(30, { padWithZero: false })).toBe("30");
expect(padNumber(365, { padWithZero: false })).toBe("365");
});
@@ -153,7 +153,7 @@ describe("padNumber", () => {
it("correctly pads all single digits 0-9 with space", () => {
for (let i = 0; i < 10; i++) {
const result = padNumber(i, { padWithZero: false });
- expect(result).toBe(` ${i}`);
+ expect(result).toBe(`\u2007${i}`);
expect(result).toHaveLength(2);
}
});
diff --git a/src/utils/generateNumbers.ts b/src/utils/generateNumbers.ts
index 3e87cf3..17a6e89 100644
--- a/src/utils/generateNumbers.ts
+++ b/src/utils/generateNumbers.ts
@@ -107,14 +107,15 @@ export const generate12HourNumbers = (options: {
}) => {
let numbers: string[] = [];
- // Generate numbers from 0 to 11 for AM
+ // Generate numbers from 12 AM to 11 AM
for (let i = 0; i < 12; i += options.interval) {
+ const hour = i === 0 ? 12 : i;
numbers.push(
- `${padNumber(i, { padWithZero: options.padNumbersWithZero })} AM`
+ `${padNumber(hour, { padWithZero: options.padNumbersWithZero })} AM`
);
}
- // Generate numbers from 12 to 11 for PM
+ // Generate numbers from 12 PM to 11 PM
for (let i = 12; i < 24; i += options.interval) {
const hour = i > 12 ? i - 12 : i;
numbers.push(
diff --git a/src/utils/padNumber.ts b/src/utils/padNumber.ts
index f754787..bab1814 100644
--- a/src/utils/padNumber.ts
+++ b/src/utils/padNumber.ts
@@ -1,23 +1,23 @@
/**
* Formats a number by optionally padding it with a leading zero or space.
* Numbers less than 10 are padded based on the options provided.
- *
+ *
* @param {number} value - The number to format
* @param {Object} [options] - Optional formatting options
* @param {boolean} [options.padWithZero] - Whether to pad with zero (true) or space (false)
- *
+ *
* @returns {string} The formatted number string
- *
+ *
* @example
* // Pad with zero
* padNumber(5, { padWithZero: true })
* // Returns: '05'
- *
+ *
* @example
- * // Pad with space
+ * // Pad with figure space (same width as zero)
* padNumber(5, { padWithZero: false })
* // Returns: ' 5'
- *
+ *
* @example
* // No padding needed
* padNumber(15)
@@ -28,7 +28,7 @@ export const padNumber = (
options?: { padWithZero?: boolean }
): string => {
if (value < 10) {
- return (options?.padWithZero ? "0" : " ") + value;
+ return (options?.padWithZero ? "0" : "\u2007") + value;
} else {
return String(value);
}
diff --git a/yarn.lock b/yarn.lock
index 0132c0a..385b6f7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1831,26 +1831,25 @@ __metadata:
languageName: node
linkType: hard
-"@expo/cli@npm:54.0.16":
- version: 54.0.16
- resolution: "@expo/cli@npm:54.0.16"
+"@expo/cli@npm:54.0.19":
+ version: 54.0.19
+ resolution: "@expo/cli@npm:54.0.19"
dependencies:
"@0no-co/graphql.web": "npm:^1.0.8"
"@expo/code-signing-certificates": "npm:^0.0.5"
- "@expo/config": "npm:~12.0.10"
- "@expo/config-plugins": "npm:~54.0.2"
- "@expo/devcert": "npm:^1.1.2"
- "@expo/env": "npm:~2.0.7"
- "@expo/image-utils": "npm:^0.8.7"
- "@expo/json-file": "npm:^10.0.7"
- "@expo/mcp-tunnel": "npm:~0.1.0"
+ "@expo/config": "npm:~12.0.12"
+ "@expo/config-plugins": "npm:~54.0.3"
+ "@expo/devcert": "npm:^1.2.1"
+ "@expo/env": "npm:~2.0.8"
+ "@expo/image-utils": "npm:^0.8.8"
+ "@expo/json-file": "npm:^10.0.8"
"@expo/metro": "npm:~54.1.0"
- "@expo/metro-config": "npm:~54.0.9"
- "@expo/osascript": "npm:^2.3.7"
- "@expo/package-manager": "npm:^1.9.8"
- "@expo/plist": "npm:^0.4.7"
- "@expo/prebuild-config": "npm:^54.0.6"
- "@expo/schema-utils": "npm:^0.1.7"
+ "@expo/metro-config": "npm:~54.0.11"
+ "@expo/osascript": "npm:^2.3.8"
+ "@expo/package-manager": "npm:^1.9.9"
+ "@expo/plist": "npm:^0.4.8"
+ "@expo/prebuild-config": "npm:^54.0.7"
+ "@expo/schema-utils": "npm:^0.1.8"
"@expo/spawn-async": "npm:^1.7.2"
"@expo/ws-tunnel": "npm:^1.0.1"
"@expo/xcpretty": "npm:^4.3.0"
@@ -1868,10 +1867,10 @@ __metadata:
connect: "npm:^3.7.0"
debug: "npm:^4.3.4"
env-editor: "npm:^0.4.1"
- expo-server: "npm:^1.0.4"
+ expo-server: "npm:^1.0.5"
freeport-async: "npm:^2.0.0"
getenv: "npm:^2.0.0"
- glob: "npm:^10.4.2"
+ glob: "npm:^13.0.0"
lan-network: "npm:^0.1.6"
minimatch: "npm:^9.0.0"
node-forge: "npm:^1.3.1"
@@ -1894,7 +1893,7 @@ __metadata:
source-map-support: "npm:~0.5.21"
stacktrace-parser: "npm:^0.1.10"
structured-headers: "npm:^0.4.1"
- tar: "npm:^7.4.3"
+ tar: "npm:^7.5.2"
terminal-link: "npm:^2.1.1"
undici: "npm:^6.18.2"
wrap-ansi: "npm:^7.0.0"
@@ -1910,7 +1909,7 @@ __metadata:
optional: true
bin:
expo-internal: build/bin/cli
- checksum: 10c0/7921ecf138409dd145e0f906b320b9b2ef569426918bd3b6eadf42af2bd856013ff7ebb050212d4ccb98fa7f13272ca435318929007ceae7386874f294dc5f9b
+ checksum: 10c0/a5db332daf83060dee3ec70bdc8a19022de9fa9ada5c01fd768df09ff2383f9738e14cd84b7e0c7777dfb379c955217e402bae37cc3cb181e1e45f2bc352fff9
languageName: node
linkType: hard
@@ -1924,70 +1923,69 @@ __metadata:
languageName: node
linkType: hard
-"@expo/config-plugins@npm:~54.0.2":
- version: 54.0.2
- resolution: "@expo/config-plugins@npm:54.0.2"
+"@expo/config-plugins@npm:~54.0.3, @expo/config-plugins@npm:~54.0.4":
+ version: 54.0.4
+ resolution: "@expo/config-plugins@npm:54.0.4"
dependencies:
- "@expo/config-types": "npm:^54.0.8"
- "@expo/json-file": "npm:~10.0.7"
- "@expo/plist": "npm:^0.4.7"
+ "@expo/config-types": "npm:^54.0.10"
+ "@expo/json-file": "npm:~10.0.8"
+ "@expo/plist": "npm:^0.4.8"
"@expo/sdk-runtime-versions": "npm:^1.0.0"
chalk: "npm:^4.1.2"
debug: "npm:^4.3.5"
getenv: "npm:^2.0.0"
- glob: "npm:^10.4.2"
+ glob: "npm:^13.0.0"
resolve-from: "npm:^5.0.0"
semver: "npm:^7.5.4"
slash: "npm:^3.0.0"
slugify: "npm:^1.6.6"
xcode: "npm:^3.0.1"
xml2js: "npm:0.6.0"
- checksum: 10c0/99f303c82a80b248ddddd2b5d2e638a83a7865f82b673cf1ff4788cdce8b835f4528e4ebca06612a7fd3aa962b3d748f63de370c9f95f78cb711eee1c6e4c331
+ checksum: 10c0/c7537485a0e883d8a98f1fb93335a1f56d4be2c2a4b5676ba09a8e9253190996241022f841c437e64578fa63b20b6ecf843d88b52930b890fa199d7aa188253f
languageName: node
linkType: hard
-"@expo/config-types@npm:^54.0.8":
- version: 54.0.8
- resolution: "@expo/config-types@npm:54.0.8"
- checksum: 10c0/8ea03fe4b18277b76d40bcd4d64a247013a2a24669e021f489f5b5a4abc06b753a9545d072c3eb12b8946cc51ad99f1c92734b94fef2c151a493a1ca78bdbf84
+"@expo/config-types@npm:^54.0.10, @expo/config-types@npm:^54.0.9":
+ version: 54.0.10
+ resolution: "@expo/config-types@npm:54.0.10"
+ checksum: 10c0/a304e18314937cbe3a146fe7daf23d5b78049676dabc14b1e181330f9e74ab2f4ada288f23999f254b59ee7c59380f895ffcb536f537e9039cd10336b1c1d7bc
languageName: node
linkType: hard
-"@expo/config@npm:~12.0.10, @expo/config@npm:~12.0.9":
- version: 12.0.10
- resolution: "@expo/config@npm:12.0.10"
+"@expo/config@npm:~12.0.11, @expo/config@npm:~12.0.12":
+ version: 12.0.12
+ resolution: "@expo/config@npm:12.0.12"
dependencies:
"@babel/code-frame": "npm:~7.10.4"
- "@expo/config-plugins": "npm:~54.0.2"
- "@expo/config-types": "npm:^54.0.8"
- "@expo/json-file": "npm:^10.0.7"
+ "@expo/config-plugins": "npm:~54.0.3"
+ "@expo/config-types": "npm:^54.0.10"
+ "@expo/json-file": "npm:^10.0.8"
deepmerge: "npm:^4.3.1"
getenv: "npm:^2.0.0"
- glob: "npm:^10.4.2"
+ glob: "npm:^13.0.0"
require-from-string: "npm:^2.0.2"
resolve-from: "npm:^5.0.0"
resolve-workspace-root: "npm:^2.0.0"
semver: "npm:^7.6.0"
slugify: "npm:^1.3.4"
- sucrase: "npm:3.35.0"
- checksum: 10c0/e438cbab74b12e0b0edb4c3434aef2e8b26f57e5cc1573998533cd102f502ab63836decabd93929756e9220795ecd9daf907ac6f7ec221fc7933d20b27825283
+ sucrase: "npm:~3.35.1"
+ checksum: 10c0/4094af9815a1c594a80fd4663db12768840350b03136e5500a7d0103c348cfe6ebe90b89bfe7ca3913293c49f9c6fa85a4b8f87a2154492e415c46e7a8cbdbb4
languageName: node
linkType: hard
-"@expo/devcert@npm:^1.1.2":
- version: 1.2.0
- resolution: "@expo/devcert@npm:1.2.0"
+"@expo/devcert@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "@expo/devcert@npm:1.2.1"
dependencies:
"@expo/sudo-prompt": "npm:^9.3.1"
debug: "npm:^3.1.0"
- glob: "npm:^10.4.2"
- checksum: 10c0/3d6a1ce44918c2e5be3bb89d25cfc80551623e4fe5004d4eb29d1edc8edd676258345e64d2aefe56188bc5d4b33e2b7e733a108b2be225af1f90ca86d7170069
+ checksum: 10c0/7c5cb4fa74a14702a44b4772a56f27fd191b6cd08988f3da01323f6d592623c80247171b7d66b2c0a32408f48a0814162dbb2764042444887f27e38b89ad1051
languageName: node
linkType: hard
-"@expo/devtools@npm:0.1.7":
- version: 0.1.7
- resolution: "@expo/devtools@npm:0.1.7"
+"@expo/devtools@npm:0.1.8":
+ version: 0.1.8
+ resolution: "@expo/devtools@npm:0.1.8"
dependencies:
chalk: "npm:^4.1.2"
peerDependencies:
@@ -1998,33 +1996,33 @@ __metadata:
optional: true
react-native:
optional: true
- checksum: 10c0/4525a007db0b3c89d7e0400f8ec9ede679d0ee110e572c9ba12e8430d564b7c9967031b0f316f0379bb5310b9b1b78adccd659cfca904effaa27706d15325fe8
+ checksum: 10c0/dc4e095e5f4508370ae2258f23370a295b9400c87f29aee2338caa3ca3733d789ba3ff1bfafbf5fa285ac6974aec89b3cbf363fca5885eb9be3973ac1a7d7fa8
languageName: node
linkType: hard
-"@expo/env@npm:~2.0.7":
- version: 2.0.7
- resolution: "@expo/env@npm:2.0.7"
+"@expo/env@npm:~2.0.8":
+ version: 2.0.8
+ resolution: "@expo/env@npm:2.0.8"
dependencies:
chalk: "npm:^4.0.0"
debug: "npm:^4.3.4"
dotenv: "npm:~16.4.5"
dotenv-expand: "npm:~11.0.6"
getenv: "npm:^2.0.0"
- checksum: 10c0/029914cfca2f85dd2c159b7331492d26255db7cf1615d02108041f561f3e7286d77f473943dd1d6ede68ee3cea8b63271c8352fa9b728c90e020f50d6d8c5582
+ checksum: 10c0/e6e4cd1be45a6873f5ad4a6a2176957897159b08104f04ea8f28a9d9f38abe0d109ded76ac197c0edba1ac606c14a034be19cfda75b44111be85b78a2d209375
languageName: node
linkType: hard
-"@expo/fingerprint@npm:0.15.3":
- version: 0.15.3
- resolution: "@expo/fingerprint@npm:0.15.3"
+"@expo/fingerprint@npm:0.15.4":
+ version: 0.15.4
+ resolution: "@expo/fingerprint@npm:0.15.4"
dependencies:
"@expo/spawn-async": "npm:^1.7.2"
arg: "npm:^5.0.2"
chalk: "npm:^4.1.2"
debug: "npm:^4.3.4"
getenv: "npm:^2.0.0"
- glob: "npm:^10.4.2"
+ glob: "npm:^13.0.0"
ignore: "npm:^5.3.1"
minimatch: "npm:^9.0.0"
p-limit: "npm:^3.1.0"
@@ -2032,13 +2030,13 @@ __metadata:
semver: "npm:^7.6.0"
bin:
fingerprint: bin/cli.js
- checksum: 10c0/bbb3a568987f976c44053f83f29ed86f0d18d4e5e9ac649525bae4657014e86b3f184e80c6dc3baa95b017d8e37c50eafae0f926fe14f2e371243a3edc741a45
+ checksum: 10c0/fe5aa9eff4f649cc58aa0b67cd6b93845ddc81b49a61f03c50632405bf2b99fc83ecbb15c527bfddc0156f8fad297f066dd46edf4cfa17580025fb192d7a98ee
languageName: node
linkType: hard
-"@expo/image-utils@npm:^0.8.7":
- version: 0.8.7
- resolution: "@expo/image-utils@npm:0.8.7"
+"@expo/image-utils@npm:^0.8.8":
+ version: 0.8.8
+ resolution: "@expo/image-utils@npm:0.8.8"
dependencies:
"@expo/spawn-async": "npm:^1.7.2"
chalk: "npm:^4.0.0"
@@ -2050,46 +2048,30 @@ __metadata:
semver: "npm:^7.6.0"
temp-dir: "npm:~2.0.0"
unique-string: "npm:~2.0.0"
- checksum: 10c0/763fbe6d5e34c6e40b74f1088dd5a3bf8cf54a57b073ec55230a8c2f87deb9204a79ce3750d40745c330cb438e50d854d0177a7f7d19c2055770687ef243660e
+ checksum: 10c0/d08a93036d865b52d1a4848597bd872192c7023d415f62ed744e9ff20fd9e68308ade06b39c25b0eabbc04745ffa68c4b5a8d79883adb0c32738e1a414d7d62e
languageName: node
linkType: hard
-"@expo/json-file@npm:^10.0.7, @expo/json-file@npm:~10.0.7":
- version: 10.0.7
- resolution: "@expo/json-file@npm:10.0.7"
+"@expo/json-file@npm:^10.0.8, @expo/json-file@npm:~10.0.8":
+ version: 10.0.8
+ resolution: "@expo/json-file@npm:10.0.8"
dependencies:
"@babel/code-frame": "npm:~7.10.4"
json5: "npm:^2.2.3"
- checksum: 10c0/3dfff7fe435d286f6c2f55569a8667f6d52133fc96a263e7421fa49cbf2ad7a4e2952da1fa7a3cdb15c52f11e891335ec784d358c3be554f966fdf5c836cc944
- languageName: node
- linkType: hard
-
-"@expo/mcp-tunnel@npm:~0.1.0":
- version: 0.1.0
- resolution: "@expo/mcp-tunnel@npm:0.1.0"
- dependencies:
- ws: "npm:^8.18.3"
- zod: "npm:^3.25.76"
- zod-to-json-schema: "npm:^3.24.6"
- peerDependencies:
- "@modelcontextprotocol/sdk": ^1.13.2
- peerDependenciesMeta:
- "@modelcontextprotocol/sdk":
- optional: true
- checksum: 10c0/db1241d159875c7e8bcc72c121e6b3a287794809c1bbf7781b61bd15673b3a2dd36e9fa6886893ff20d1aea399440f3abafcdf10a955ad9f410750d757ee8158
+ checksum: 10c0/dddd7ef7966fe0d29d1cad5a1d517d01c4e6a7b55cd15e901b947e7832d613aa1b982de5336d1305a3714bb4b5e3d78110c0ff799ca33fd54a8cd887f8ba533d
languageName: node
linkType: hard
-"@expo/metro-config@npm:54.0.9, @expo/metro-config@npm:~54.0.9":
- version: 54.0.9
- resolution: "@expo/metro-config@npm:54.0.9"
+"@expo/metro-config@npm:54.0.11, @expo/metro-config@npm:~54.0.11":
+ version: 54.0.11
+ resolution: "@expo/metro-config@npm:54.0.11"
dependencies:
"@babel/code-frame": "npm:^7.20.0"
"@babel/core": "npm:^7.20.0"
"@babel/generator": "npm:^7.20.5"
- "@expo/config": "npm:~12.0.10"
- "@expo/env": "npm:~2.0.7"
- "@expo/json-file": "npm:~10.0.7"
+ "@expo/config": "npm:~12.0.12"
+ "@expo/env": "npm:~2.0.8"
+ "@expo/json-file": "npm:~10.0.8"
"@expo/metro": "npm:~54.1.0"
"@expo/spawn-async": "npm:^1.7.2"
browserslist: "npm:^4.25.0"
@@ -2098,7 +2080,7 @@ __metadata:
dotenv: "npm:~16.4.5"
dotenv-expand: "npm:~11.0.6"
getenv: "npm:^2.0.0"
- glob: "npm:^10.4.2"
+ glob: "npm:^13.0.0"
hermes-parser: "npm:^0.29.1"
jsc-safe-url: "npm:^0.2.4"
lightningcss: "npm:^1.30.1"
@@ -2110,7 +2092,7 @@ __metadata:
peerDependenciesMeta:
expo:
optional: true
- checksum: 10c0/6833c594082a347ba6df0ad6d107c6b8f21363a06b4f5e4ffbac91bbfc14cf1d62b2fbb335bb146dddcad8bd53d7a09920fe928cc7312f9e50bd9138b2d4aacc
+ checksum: 10c0/be2774a33366607a28d9dc5a19721fc4eb50f1d84fe68d9a33ab41611cc9186e60e340c24c8b4646403995a86e4dc90b4d21653b3388181f146ff1a22b641d70
languageName: node
linkType: hard
@@ -2134,50 +2116,50 @@ __metadata:
languageName: node
linkType: hard
-"@expo/osascript@npm:^2.3.7":
- version: 2.3.7
- resolution: "@expo/osascript@npm:2.3.7"
+"@expo/osascript@npm:^2.3.8":
+ version: 2.3.8
+ resolution: "@expo/osascript@npm:2.3.8"
dependencies:
"@expo/spawn-async": "npm:^1.7.2"
exec-async: "npm:^2.2.0"
- checksum: 10c0/7778120019f3969e68e2473d8a75e35b03e1b8f573a6d306603b9007953595b28ef042eaf16580f00c48b063fdc808f7a8a6cfd302fedcbe149bd1a3e44c84c9
+ checksum: 10c0/5991c363fb33fb1f740eb8bfdb7ccafd1944a6d89a644ec20dd76b546ffa995a3963727150155391287536046f5f47c7efae003a27a86299224d55191e2f65cb
languageName: node
linkType: hard
-"@expo/package-manager@npm:^1.9.8":
- version: 1.9.8
- resolution: "@expo/package-manager@npm:1.9.8"
+"@expo/package-manager@npm:^1.9.9":
+ version: 1.9.9
+ resolution: "@expo/package-manager@npm:1.9.9"
dependencies:
- "@expo/json-file": "npm:^10.0.7"
+ "@expo/json-file": "npm:^10.0.8"
"@expo/spawn-async": "npm:^1.7.2"
chalk: "npm:^4.0.0"
npm-package-arg: "npm:^11.0.0"
ora: "npm:^3.4.0"
resolve-workspace-root: "npm:^2.0.0"
- checksum: 10c0/d9f727a9b02a13d7fac8afccc5608f46690ca3e27f834042e74bc271607a5a085ad4600a19eeda55556251b8f1f0960cf71609680df7fedf76750141cb0d2a9e
+ checksum: 10c0/f822b49f4b6c6b8e4d95b7d136a515131f85b145fe6bc15eef42ef2c2890474b5bba913d03c098c614373be2e5e85afa24ea3ca237dfd0ec077bdd4b6c5248cc
languageName: node
linkType: hard
-"@expo/plist@npm:^0.4.7":
- version: 0.4.7
- resolution: "@expo/plist@npm:0.4.7"
+"@expo/plist@npm:^0.4.8":
+ version: 0.4.8
+ resolution: "@expo/plist@npm:0.4.8"
dependencies:
"@xmldom/xmldom": "npm:^0.8.8"
base64-js: "npm:^1.2.3"
xmlbuilder: "npm:^15.1.1"
- checksum: 10c0/697b3845e7898516de4d25ac28ae9fcbf1e58612bd543b41e11b3d41b9a52b754f2775dc2891cd3068a88f0375a77c2805073c12c5d54f3cd7ef6d315d0a3b92
+ checksum: 10c0/5bacdb6f8c5e0e56da07f4504290036e3a5433164a29bea7857e72234137d8eaa04adb319221fcc1ec7f931d40d7f9f6fc9528fa601ed18c308a4cf8179f7783
languageName: node
linkType: hard
-"@expo/prebuild-config@npm:^54.0.6":
- version: 54.0.6
- resolution: "@expo/prebuild-config@npm:54.0.6"
+"@expo/prebuild-config@npm:^54.0.7":
+ version: 54.0.7
+ resolution: "@expo/prebuild-config@npm:54.0.7"
dependencies:
- "@expo/config": "npm:~12.0.10"
- "@expo/config-plugins": "npm:~54.0.2"
- "@expo/config-types": "npm:^54.0.8"
- "@expo/image-utils": "npm:^0.8.7"
- "@expo/json-file": "npm:^10.0.7"
+ "@expo/config": "npm:~12.0.11"
+ "@expo/config-plugins": "npm:~54.0.3"
+ "@expo/config-types": "npm:^54.0.9"
+ "@expo/image-utils": "npm:^0.8.8"
+ "@expo/json-file": "npm:^10.0.8"
"@react-native/normalize-colors": "npm:0.81.5"
debug: "npm:^4.3.1"
resolve-from: "npm:^5.0.0"
@@ -2185,14 +2167,14 @@ __metadata:
xml2js: "npm:0.6.0"
peerDependencies:
expo: "*"
- checksum: 10c0/d27cf8c6387115e293f25c102f80124230e425c3326f85350bc758bf0c5019c6ea6ca0f4718f56dc6e7916b42fa65535100147da84a71f12472d2606d50578f8
+ checksum: 10c0/8ab94732c51c74823e8377c2f6fd5095615f8f82a4dd1696586bbdd5faed617806ffb52b9ab9fd88dff8244fc6361828eb376143c956a7b6ea30d6e9479e4e9c
languageName: node
linkType: hard
-"@expo/schema-utils@npm:^0.1.7":
- version: 0.1.7
- resolution: "@expo/schema-utils@npm:0.1.7"
- checksum: 10c0/1099bd8801ff941584bc6d2bb44613f9fb87af663843d629d9ede8315f44f7332c881b70f1681e8f8fc82b27472b4a025341963f0f347e16a0ae90fcb65138cd
+"@expo/schema-utils@npm:^0.1.8":
+ version: 0.1.8
+ resolution: "@expo/schema-utils@npm:0.1.8"
+ checksum: 10c0/9a600ac858bcd1bd24ccac3e86cbef996c2c58cb20ce61fb1fc753f36dce4a000510e61b803ad5cb221a16caa38b54b243f08ac08e0de69e4aa556798d877f02
languageName: node
linkType: hard
@@ -2292,6 +2274,22 @@ __metadata:
languageName: node
linkType: hard
+"@isaacs/balanced-match@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "@isaacs/balanced-match@npm:4.0.1"
+ checksum: 10c0/7da011805b259ec5c955f01cee903da72ad97c5e6f01ca96197267d3f33103d5b2f8a1af192140f3aa64526c593c8d098ae366c2b11f7f17645d12387c2fd420
+ languageName: node
+ linkType: hard
+
+"@isaacs/brace-expansion@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "@isaacs/brace-expansion@npm:5.0.0"
+ dependencies:
+ "@isaacs/balanced-match": "npm:^4.0.1"
+ checksum: 10c0/b4d4812f4be53afc2c5b6c545001ff7a4659af68d4484804e9d514e183d20269bb81def8682c01a22b17c4d6aed14292c8494f7d2ac664e547101c1a905aa977
+ languageName: node
+ linkType: hard
+
"@isaacs/cliui@npm:^8.0.2":
version: 8.0.2
resolution: "@isaacs/cliui@npm:8.0.2"
@@ -4699,9 +4697,9 @@ __metadata:
languageName: node
linkType: hard
-"babel-preset-expo@npm:~54.0.7":
- version: 54.0.7
- resolution: "babel-preset-expo@npm:54.0.7"
+"babel-preset-expo@npm:~54.0.8":
+ version: 54.0.8
+ resolution: "babel-preset-expo@npm:54.0.8"
dependencies:
"@babel/helper-module-imports": "npm:^7.25.9"
"@babel/plugin-proposal-decorators": "npm:^7.12.9"
@@ -4734,7 +4732,7 @@ __metadata:
optional: true
expo:
optional: true
- checksum: 10c0/a4c2de6b1c2a56199e663b99ddc42b75ece556d862e15d1240441a5d06f6f09c93f725e230baf3fab29afb11ee2026569f497e037d1596432cb66a5c1c6cefdc
+ checksum: 10c0/474b0799f3027d35f72d27f212551e92ac1b1119bac5a3f98c5d4e78be1a1cfcbcd24f52680236bf1400a037e07f7ab69ca4a8311947f0cf6f75c2d44aabde7d
languageName: node
linkType: hard
@@ -6486,11 +6484,11 @@ __metadata:
dependencies:
"@expo/vector-icons": "npm:^15.0.3"
"@react-native-masked-view/masked-view": "npm:0.3.2"
- expo: "npm:54.0.23"
- expo-asset: "npm:~12.0.9"
- expo-font: "npm:~14.0.9"
- expo-haptics: "npm:~15.0.7"
- expo-linear-gradient: "npm:~15.0.7"
+ expo: "npm:~54.0.29"
+ expo-asset: "npm:~12.0.11"
+ expo-font: "npm:~14.0.10"
+ expo-haptics: "npm:~15.0.8"
+ expo-linear-gradient: "npm:~15.0.8"
react: "npm:19.1.0"
react-native: "npm:0.81.5"
react-native-audio-api: "npm:0.9.0"
@@ -6558,102 +6556,89 @@ __metadata:
languageName: node
linkType: hard
-"expo-asset@npm:~12.0.9":
- version: 12.0.9
- resolution: "expo-asset@npm:12.0.9"
+"expo-asset@npm:~12.0.11":
+ version: 12.0.11
+ resolution: "expo-asset@npm:12.0.11"
dependencies:
- "@expo/image-utils": "npm:^0.8.7"
- expo-constants: "npm:~18.0.9"
+ "@expo/image-utils": "npm:^0.8.8"
+ expo-constants: "npm:~18.0.11"
peerDependencies:
expo: "*"
react: "*"
react-native: "*"
- checksum: 10c0/7a66523e26e9868ad7961c9d6436f188e2832a7b3168a47be10ae8468616250803d31ded11b61bcc920e2aa0f0443c69fcb220be16b0b120aa255a840a355032
+ checksum: 10c0/d2b452efeb5fbe014e6a17f344b53d57539c79786d26ef32841c89e06ca6eb6f35949c72c6b8c506dc385dda394a344b0810d368090c1d42277b18f37d5b2b08
languageName: node
linkType: hard
-"expo-constants@npm:~18.0.10":
- version: 18.0.10
- resolution: "expo-constants@npm:18.0.10"
+"expo-constants@npm:~18.0.11, expo-constants@npm:~18.0.12":
+ version: 18.0.12
+ resolution: "expo-constants@npm:18.0.12"
dependencies:
- "@expo/config": "npm:~12.0.10"
- "@expo/env": "npm:~2.0.7"
+ "@expo/config": "npm:~12.0.12"
+ "@expo/env": "npm:~2.0.8"
peerDependencies:
expo: "*"
react-native: "*"
- checksum: 10c0/c3878d7a4c438e1bab25bc5267553c06e4c002237f0cf35eb434de70734e31ef1d07c151d9a7771b75be1baa1c794a4c1c731167cbdfa5bd4fe41a499b8dda4b
+ checksum: 10c0/9dab3f1d685b17c25ae4179823162b763a7edeea8b976f96f25e37fabbfbc190f05cd774431664e5145196f3982e34303ebf5a1f5a82a1409218ae93187f710f
languageName: node
linkType: hard
-"expo-constants@npm:~18.0.9":
- version: 18.0.9
- resolution: "expo-constants@npm:18.0.9"
- dependencies:
- "@expo/config": "npm:~12.0.9"
- "@expo/env": "npm:~2.0.7"
- peerDependencies:
- expo: "*"
- react-native: "*"
- checksum: 10c0/5e7f2fd366d4c0351d2d30b8f31afc0001e1d0c19f113b9083bae7ee495cb55aeae402497d0a13f856157730d5821c5143acccfc3d8d25b74aa064c6d33ec017
- languageName: node
- linkType: hard
-
-"expo-file-system@npm:~19.0.17":
- version: 19.0.17
- resolution: "expo-file-system@npm:19.0.17"
+"expo-file-system@npm:~19.0.21":
+ version: 19.0.21
+ resolution: "expo-file-system@npm:19.0.21"
peerDependencies:
expo: "*"
react-native: "*"
- checksum: 10c0/c0c4017429f0f43790d5a5587e56deca77015e959a8667c4ee3890a42d47a4389775ebfeb4951d0f7942ef7d416eb487928f6447f64a86cad58326181917e3c8
+ checksum: 10c0/0ece34f86beda2048f8bf1f3218e57f6c7c14a875fe8be0f0dd2704d968ee61f979ddf0561b8769f4d46cfeb77ac759da0a030c5a77128cf2a06ce0bb9e3959b
languageName: node
linkType: hard
-"expo-font@npm:~14.0.9":
- version: 14.0.9
- resolution: "expo-font@npm:14.0.9"
+"expo-font@npm:~14.0.10":
+ version: 14.0.10
+ resolution: "expo-font@npm:14.0.10"
dependencies:
fontfaceobserver: "npm:^2.1.0"
peerDependencies:
expo: "*"
react: "*"
react-native: "*"
- checksum: 10c0/7336a6094705c46379d4bb93f34a3b6c8d5fca871b34d62db94739b204639f3eeb6b1f5db4b4209e28a34348360075ccf557fe28ca996182469685427e570a9d
+ checksum: 10c0/67b5ea924319235426c27a4b69a8409438314bed635ad9c57bfbb4b5dcc873a575d2f44129683ec145785d3cdf591349078cc2e96d750ba2dea3aebf89e19e9f
languageName: node
linkType: hard
-"expo-haptics@npm:~15.0.7":
- version: 15.0.7
- resolution: "expo-haptics@npm:15.0.7"
+"expo-haptics@npm:~15.0.8":
+ version: 15.0.8
+ resolution: "expo-haptics@npm:15.0.8"
peerDependencies:
expo: "*"
- checksum: 10c0/72daaf272b6ab3f650d76d901b3f744d497c9120b77d274560cccff6da985c867256212108c2057843996fad5ea8905614aae4747a217d6502f0c0156eca6d5d
+ checksum: 10c0/25f58bbbb5faa0d05701ada7f1247adead98a7e30dcbac136aa3e458773584ac758318a02d906de7ba85d63cbd45e7edde3dc35e61825f0dc1e8ed20668ed594
languageName: node
linkType: hard
-"expo-keep-awake@npm:~15.0.7":
- version: 15.0.7
- resolution: "expo-keep-awake@npm:15.0.7"
+"expo-keep-awake@npm:~15.0.8":
+ version: 15.0.8
+ resolution: "expo-keep-awake@npm:15.0.8"
peerDependencies:
expo: "*"
react: "*"
- checksum: 10c0/6ca4cb430a97627b5657a220720808e4bd6dd89f4e9f86d52db71b9f91a72af8e63a83005d49af86924fc8f7bd210c312dfcb07212a1fe54334e0b4058943ec9
+ checksum: 10c0/23064b18285498e70be0aa525dc875cc809fc723b9a101d51e4721a09b1460eb041c73ebeb6d51e9175bb4c9b7a668bc08a48b99ebddac4cfaadb5a47194d329
languageName: node
linkType: hard
-"expo-linear-gradient@npm:~15.0.7":
- version: 15.0.7
- resolution: "expo-linear-gradient@npm:15.0.7"
+"expo-linear-gradient@npm:~15.0.8":
+ version: 15.0.8
+ resolution: "expo-linear-gradient@npm:15.0.8"
peerDependencies:
expo: "*"
react: "*"
react-native: "*"
- checksum: 10c0/ee9984f4bc8985b3ad32f8a59138fd7336e16e782c1d2d10110f70b2e05b9c563382d2c16cfbe21e6463fa896f573dcc3d70d0afd32f8d435bccd9afadf8b006
+ checksum: 10c0/2ac3bff62143083e3d5b894fccc4c76de058277f65ed123232636cf26c88da6d566fa3cd46be4101f86e66b89ede7c058e12c93493b752df562da2fa971dcd66
languageName: node
linkType: hard
-"expo-modules-autolinking@npm:3.0.21":
- version: 3.0.21
- resolution: "expo-modules-autolinking@npm:3.0.21"
+"expo-modules-autolinking@npm:3.0.23":
+ version: 3.0.23
+ resolution: "expo-modules-autolinking@npm:3.0.23"
dependencies:
"@expo/spawn-async": "npm:^1.7.2"
chalk: "npm:^4.1.0"
@@ -6662,51 +6647,51 @@ __metadata:
resolve-from: "npm:^5.0.0"
bin:
expo-modules-autolinking: bin/expo-modules-autolinking.js
- checksum: 10c0/f1a7abb57f9ea0ceb3f530257705c7fd8775547c60618d9f954ac4e8ce8ff4b2928b47da69c1003535febc04f82fb415755b1226cdb9e5f7bbb82b4110a1f37f
+ checksum: 10c0/c10e5a4b9cbc3cad1ab34745f2903041b5042123663f94cbd724602dbdfc0bfe75dd94f581660a41ffd2baa9c407a5d71a13d415a6214ac6bd9f9d00ba499e8a
languageName: node
linkType: hard
-"expo-modules-core@npm:3.0.25":
- version: 3.0.25
- resolution: "expo-modules-core@npm:3.0.25"
+"expo-modules-core@npm:3.0.29":
+ version: 3.0.29
+ resolution: "expo-modules-core@npm:3.0.29"
dependencies:
invariant: "npm:^2.2.4"
peerDependencies:
react: "*"
react-native: "*"
- checksum: 10c0/45cc72d2c8c7fdf149be19009f99be1e600aa4619a849accd24b6f20cf64cd461014767e46cace300e096520d4e3c239c3a44a96f4275488bd1b47320ac03ee0
+ checksum: 10c0/e32a87b06aa772f523afa5a995523848c61c06370085ae9e724ad24432cac38925ff69976f58b2c562828c2cefba6df00cfef2dbb206111413890ce1c2baee19
languageName: node
linkType: hard
-"expo-server@npm:^1.0.4":
- version: 1.0.4
- resolution: "expo-server@npm:1.0.4"
- checksum: 10c0/56330a10e222475126ce4a61676b170cf34951deae4a8b0965dcf8e317b03e99f71d92f908e57bb6196d2bdb0b36d5efb17fb48fd7c3b1d65f690bf2578f7975
+"expo-server@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "expo-server@npm:1.0.5"
+ checksum: 10c0/0da974f733235d457f7ce51e5452f48f203378687f821bdab7159617a491c0192251423a17a7a3a118486e1cbfffff5d5ad31aeeedcf2cfad6412a1bd7e86877
languageName: node
linkType: hard
-"expo@npm:54.0.23":
- version: 54.0.23
- resolution: "expo@npm:54.0.23"
+"expo@npm:~54.0.29":
+ version: 54.0.29
+ resolution: "expo@npm:54.0.29"
dependencies:
"@babel/runtime": "npm:^7.20.0"
- "@expo/cli": "npm:54.0.16"
- "@expo/config": "npm:~12.0.10"
- "@expo/config-plugins": "npm:~54.0.2"
- "@expo/devtools": "npm:0.1.7"
- "@expo/fingerprint": "npm:0.15.3"
+ "@expo/cli": "npm:54.0.19"
+ "@expo/config": "npm:~12.0.12"
+ "@expo/config-plugins": "npm:~54.0.4"
+ "@expo/devtools": "npm:0.1.8"
+ "@expo/fingerprint": "npm:0.15.4"
"@expo/metro": "npm:~54.1.0"
- "@expo/metro-config": "npm:54.0.9"
+ "@expo/metro-config": "npm:54.0.11"
"@expo/vector-icons": "npm:^15.0.3"
"@ungap/structured-clone": "npm:^1.3.0"
- babel-preset-expo: "npm:~54.0.7"
- expo-asset: "npm:~12.0.9"
- expo-constants: "npm:~18.0.10"
- expo-file-system: "npm:~19.0.17"
- expo-font: "npm:~14.0.9"
- expo-keep-awake: "npm:~15.0.7"
- expo-modules-autolinking: "npm:3.0.21"
- expo-modules-core: "npm:3.0.25"
+ babel-preset-expo: "npm:~54.0.8"
+ expo-asset: "npm:~12.0.11"
+ expo-constants: "npm:~18.0.12"
+ expo-file-system: "npm:~19.0.21"
+ expo-font: "npm:~14.0.10"
+ expo-keep-awake: "npm:~15.0.8"
+ expo-modules-autolinking: "npm:3.0.23"
+ expo-modules-core: "npm:3.0.29"
pretty-format: "npm:^29.7.0"
react-refresh: "npm:^0.14.2"
whatwg-url-without-unicode: "npm:8.0.0-3"
@@ -6727,7 +6712,7 @@ __metadata:
expo: bin/cli
expo-modules-autolinking: bin/autolinking
fingerprint: bin/fingerprint
- checksum: 10c0/4dd715a2a73387ebb40a5d2427ad643dc03b365ced10705203ebe4c0bac8f26ad76c65758d55b6c43971d6843d328c99212a1af0de926cb83cffdb699194626b
+ checksum: 10c0/4e550143de61e8cb68d03ba78e34f3f008bc670f8dd042711f38da04c59e8289b97f88c20fc6e5529f838390cd2efc95e06bab36ea49c324af46253df628f929
languageName: node
linkType: hard
@@ -6813,6 +6798,18 @@ __metadata:
languageName: node
linkType: hard
+"fdir@npm:^6.5.0":
+ version: 6.5.0
+ resolution: "fdir@npm:6.5.0"
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+ checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f
+ languageName: node
+ linkType: hard
+
"file-entry-cache@npm:^6.0.1":
version: 6.0.1
resolution: "file-entry-cache@npm:6.0.1"
@@ -7158,7 +7155,7 @@ __metadata:
languageName: node
linkType: hard
-"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.2":
+"glob@npm:^10.2.2":
version: 10.4.5
resolution: "glob@npm:10.4.5"
dependencies:
@@ -7174,6 +7171,17 @@ __metadata:
languageName: node
linkType: hard
+"glob@npm:^13.0.0":
+ version: 13.0.0
+ resolution: "glob@npm:13.0.0"
+ dependencies:
+ minimatch: "npm:^10.1.1"
+ minipass: "npm:^7.1.2"
+ path-scurry: "npm:^2.0.0"
+ checksum: 10c0/8e2f5821f3f7c312dd102e23a15b80c79e0837a9872784293ba2e15ec73b3f3749a49a42a31bfcb4e52c84820a474e92331c2eebf18819d20308f5c33876630a
+ languageName: node
+ linkType: hard
+
"glob@npm:^7.1.1, glob@npm:^7.1.3, glob@npm:^7.1.4":
version: 7.2.3
resolution: "glob@npm:7.2.3"
@@ -9165,6 +9173,13 @@ __metadata:
languageName: node
linkType: hard
+"lru-cache@npm:^11.0.0":
+ version: 11.2.4
+ resolution: "lru-cache@npm:11.2.4"
+ checksum: 10c0/4a24f9b17537619f9144d7b8e42cd5a225efdfd7076ebe7b5e7dc02b860a818455201e67fbf000765233fe7e339d3c8229fc815e9b58ee6ede511e07608c19b2
+ languageName: node
+ linkType: hard
+
"lru-cache@npm:^5.1.1":
version: 5.1.1
resolution: "lru-cache@npm:5.1.1"
@@ -10375,6 +10390,15 @@ __metadata:
languageName: node
linkType: hard
+"minimatch@npm:^10.1.1":
+ version: 10.1.1
+ resolution: "minimatch@npm:10.1.1"
+ dependencies:
+ "@isaacs/brace-expansion": "npm:^5.0.0"
+ checksum: 10c0/c85d44821c71973d636091fddbfbffe62370f5ee3caf0241c5b60c18cd289e916200acb2361b7e987558cd06896d153e25d505db9fc1e43e6b4b6752e2702902
+ languageName: node
+ linkType: hard
+
"minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
@@ -10485,6 +10509,15 @@ __metadata:
languageName: node
linkType: hard
+"minizlib@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "minizlib@npm:3.1.0"
+ dependencies:
+ minipass: "npm:^7.1.2"
+ checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec
+ languageName: node
+ linkType: hard
+
"mkdirp@npm:^0.5.1":
version: 0.5.6
resolution: "mkdirp@npm:0.5.6"
@@ -11156,6 +11189,16 @@ __metadata:
languageName: node
linkType: hard
+"path-scurry@npm:^2.0.0":
+ version: 2.0.1
+ resolution: "path-scurry@npm:2.0.1"
+ dependencies:
+ lru-cache: "npm:^11.0.0"
+ minipass: "npm:^7.1.2"
+ checksum: 10c0/2a16ed0e81fbc43513e245aa5763354e25e787dab0d539581a6c3f0f967461a159ed6236b2559de23aa5b88e7dc32b469b6c47568833dd142a4b24b4f5cd2620
+ languageName: node
+ linkType: hard
+
"path-type@npm:^4.0.0":
version: 4.0.0
resolution: "path-type@npm:4.0.0"
@@ -11191,6 +11234,13 @@ __metadata:
languageName: node
linkType: hard
+"picomatch@npm:^4.0.3":
+ version: 4.0.3
+ resolution: "picomatch@npm:4.0.3"
+ checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2
+ languageName: node
+ linkType: hard
+
"pify@npm:^4.0.1":
version: 4.0.1
resolution: "pify@npm:4.0.1"
@@ -12946,21 +12996,21 @@ __metadata:
languageName: node
linkType: hard
-"sucrase@npm:3.35.0":
- version: 3.35.0
- resolution: "sucrase@npm:3.35.0"
+"sucrase@npm:~3.35.1":
+ version: 3.35.1
+ resolution: "sucrase@npm:3.35.1"
dependencies:
"@jridgewell/gen-mapping": "npm:^0.3.2"
commander: "npm:^4.0.0"
- glob: "npm:^10.3.10"
lines-and-columns: "npm:^1.1.6"
mz: "npm:^2.7.0"
pirates: "npm:^4.0.1"
+ tinyglobby: "npm:^0.2.11"
ts-interface-checker: "npm:^0.1.9"
bin:
sucrase: bin/sucrase
sucrase-node: bin/sucrase-node
- checksum: 10c0/ac85f3359d2c2ecbf5febca6a24ae9bf96c931f05fde533c22a94f59c6a74895e5d5f0e871878dfd59c2697a75ebb04e4b2224ef0bfc24ca1210735c2ec191ef
+ checksum: 10c0/6fa22329c261371feb9560630d961ad0d0b9c87dce21ea74557c5f3ffbe5c1ee970ea8bcce9962ae9c90c3c47165ffa7dd41865c7414f5d8ea7a40755d612c5c
languageName: node
linkType: hard
@@ -13029,6 +13079,19 @@ __metadata:
languageName: node
linkType: hard
+"tar@npm:^7.5.2":
+ version: 7.5.2
+ resolution: "tar@npm:7.5.2"
+ dependencies:
+ "@isaacs/fs-minipass": "npm:^4.0.0"
+ chownr: "npm:^3.0.0"
+ minipass: "npm:^7.1.2"
+ minizlib: "npm:^3.1.0"
+ yallist: "npm:^5.0.0"
+ checksum: 10c0/a7d8b801139b52f93a7e34830db0de54c5aa45487c7cb551f6f3d44a112c67f1cb8ffdae856b05fd4f17b1749911f1c26f1e3a23bbe0279e17fd96077f13f467
+ languageName: node
+ linkType: hard
+
"temp-dir@npm:~2.0.0":
version: 2.0.0
resolution: "temp-dir@npm:2.0.0"
@@ -13122,6 +13185,16 @@ __metadata:
languageName: node
linkType: hard
+"tinyglobby@npm:^0.2.11":
+ version: 0.2.15
+ resolution: "tinyglobby@npm:0.2.15"
+ dependencies:
+ fdir: "npm:^6.5.0"
+ picomatch: "npm:^4.0.3"
+ checksum: 10c0/869c31490d0d88eedb8305d178d4c75e7463e820df5a9b9d388291daf93e8b1eb5de1dad1c1e139767e4269fe75f3b10d5009b2cc14db96ff98986920a186844
+ languageName: node
+ linkType: hard
+
"tinyglobby@npm:^0.2.12":
version: 0.2.13
resolution: "tinyglobby@npm:0.2.13"
@@ -13817,21 +13890,6 @@ __metadata:
languageName: node
linkType: hard
-"ws@npm:^8.18.3":
- version: 8.18.3
- resolution: "ws@npm:8.18.3"
- peerDependencies:
- bufferutil: ^4.0.1
- utf-8-validate: ">=5.0.2"
- peerDependenciesMeta:
- bufferutil:
- optional: true
- utf-8-validate:
- optional: true
- checksum: 10c0/eac918213de265ef7cb3d4ca348b891a51a520d839aa51cdb8ca93d4fa7ff9f6ccb339ccee89e4075324097f0a55157c89fa3f7147bde9d8d7e90335dc087b53
- languageName: node
- linkType: hard
-
"xcode@npm:^3.0.1":
version: 3.0.1
resolution: "xcode@npm:3.0.1"
@@ -13990,19 +14048,3 @@ __metadata:
checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f
languageName: node
linkType: hard
-
-"zod-to-json-schema@npm:^3.24.6":
- version: 3.24.6
- resolution: "zod-to-json-schema@npm:3.24.6"
- peerDependencies:
- zod: ^3.24.1
- checksum: 10c0/b907ab6d057100bd25a37e5545bf5f0efa5902cd84d3c3ec05c2e51541431a47bd9bf1e5e151a244273409b45f5986d55b26e5d207f98abc5200702f733eb368
- languageName: node
- linkType: hard
-
-"zod@npm:^3.25.76":
- version: 3.25.76
- resolution: "zod@npm:3.25.76"
- checksum: 10c0/5718ec35e3c40b600316c5b4c5e4976f7fee68151bc8f8d90ec18a469be9571f072e1bbaace10f1e85cf8892ea12d90821b200e980ab46916a6166a4260a983c
- languageName: node
- linkType: hard