react-native-timer-picker 1.3.0 → 1.4.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.
Files changed (53) hide show
  1. package/README.md +6 -0
  2. package/dist/commonjs/components/Modal/index.js +13 -14
  3. package/dist/commonjs/components/Modal/index.js.map +1 -1
  4. package/dist/commonjs/components/TimerPicker/DurationScroll.js +51 -32
  5. package/dist/commonjs/components/TimerPicker/DurationScroll.js.map +1 -1
  6. package/dist/commonjs/components/TimerPicker/TimerPicker.styles.js +23 -3
  7. package/dist/commonjs/components/TimerPicker/TimerPicker.styles.js.map +1 -1
  8. package/dist/commonjs/components/TimerPicker/index.js +33 -28
  9. package/dist/commonjs/components/TimerPicker/index.js.map +1 -1
  10. package/dist/commonjs/components/index.js +44 -39
  11. package/dist/commonjs/components/index.js.map +1 -1
  12. package/dist/commonjs/tests/Modal.test.js +3 -1
  13. package/dist/commonjs/tests/Modal.test.js.map +1 -1
  14. package/dist/commonjs/utils/generateNumbers.js +33 -10
  15. package/dist/commonjs/utils/generateNumbers.js.map +1 -1
  16. package/dist/commonjs/utils/padNumber.js +15 -0
  17. package/dist/commonjs/utils/padNumber.js.map +1 -0
  18. package/dist/module/components/Modal/index.js +13 -14
  19. package/dist/module/components/Modal/index.js.map +1 -1
  20. package/dist/module/components/TimerPicker/DurationScroll.js +52 -33
  21. package/dist/module/components/TimerPicker/DurationScroll.js.map +1 -1
  22. package/dist/module/components/TimerPicker/TimerPicker.styles.js +23 -3
  23. package/dist/module/components/TimerPicker/TimerPicker.styles.js.map +1 -1
  24. package/dist/module/components/TimerPicker/index.js +33 -28
  25. package/dist/module/components/TimerPicker/index.js.map +1 -1
  26. package/dist/module/components/index.js +44 -39
  27. package/dist/module/components/index.js.map +1 -1
  28. package/dist/module/tests/Modal.test.js +3 -1
  29. package/dist/module/tests/Modal.test.js.map +1 -1
  30. package/dist/module/utils/generateNumbers.js +31 -9
  31. package/dist/module/utils/generateNumbers.js.map +1 -1
  32. package/dist/module/utils/padNumber.js +8 -0
  33. package/dist/module/utils/padNumber.js.map +1 -0
  34. package/dist/typescript/components/TimerPicker/DurationScroll.d.ts +3 -0
  35. package/dist/typescript/components/TimerPicker/TimerPicker.styles.d.ts +4 -0
  36. package/dist/typescript/components/TimerPicker/index.d.ts +3 -0
  37. package/dist/typescript/utils/generateNumbers.d.ts +7 -2
  38. package/dist/typescript/utils/padNumber.d.ts +3 -0
  39. package/package.json +1 -1
  40. package/src/components/Modal/index.tsx +2 -2
  41. package/src/components/TimerPicker/DurationScroll.tsx +52 -10
  42. package/src/components/TimerPicker/TimerPicker.styles.ts +32 -1
  43. package/src/components/TimerPicker/index.tsx +26 -9
  44. package/src/components/index.tsx +9 -3
  45. package/src/tests/Modal.test.tsx +1 -1
  46. package/src/utils/generateNumbers.ts +40 -10
  47. package/src/utils/padNumber.ts +10 -0
  48. package/dist/commonjs/utils/padWithZero.js +0 -15
  49. package/dist/commonjs/utils/padWithZero.js.map +0 -1
  50. package/dist/module/utils/padWithZero.js +0 -8
  51. package/dist/module/utils/padWithZero.js.map +0 -1
  52. package/dist/typescript/utils/padWithZero.d.ts +0 -1
  53. package/src/utils/padWithZero.ts +0 -7
@@ -1 +1 @@
1
- {"version":3,"names":["React","forwardRef","useCallback","useImperativeHandle","useRef","useState","View","Text","TouchableOpacity","TimerPicker","Modal","generateStyles","TimerPickerModal","_ref","ref","visible","setIsVisible","onConfirm","onCancel","onDurationChange","closeOnOverlayPress","initialHours","initialMinutes","initialSeconds","hideHours","hideMinutes","hideSeconds","hourLimit","minuteLimit","secondLimit","hourLabel","minuteLabel","secondLabel","padWithNItems","disableInfiniteScroll","hideCancelButton","confirmButtonText","cancelButtonText","modalTitle","LinearGradient","modalProps","containerProps","contentContainerProps","pickerContainerProps","buttonContainerProps","buttonTouchableOpacityProps","modalTitleProps","pickerGradientOverlayProps","topPickerGradientOverlayProps","bottomPickerGradientOverlayProps","styles","customStyles","timerPickerRef","selectedDuration","setSelectedDuration","hours","minutes","seconds","confirmedDuration","setConfirmedDuration","hideModalHandler","confirmHandler","_timerPickerRef$curre","_latestDuration$hours","_latestDuration$minut","_latestDuration$secon","latestDuration","current","newDuration","cancelHandler","durationChangeHandler","duration","_timerPickerRef$curre4","_timerPickerRef$curre5","_timerPickerRef$curre6","reset","options","_timerPickerRef$curre2","initialDuration","setValue","value","_timerPickerRef$curre3","createElement","_extends","isVisible","onOverlayPress","undefined","testID","style","container","contentContainer","aggressivelyGetLatestDuration","buttonContainer","onPress","button","cancelButton","confirmButton","memo"],"sources":["index.tsx"],"sourcesContent":["import React, {\n MutableRefObject,\n forwardRef,\n useCallback,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { View, Text, TouchableOpacity } from \"react-native\";\n\nimport TimerPicker, { TimerPickerProps, TimerPickerRef } from \"./TimerPicker\";\nimport Modal from \"./Modal\";\n\nimport {\n generateStyles,\n CustomTimerPickerModalStyles,\n} from \"./TimerPickerModal.styles\";\n\nexport interface TimerPickerModalRef {\n reset: (options?: { animated?: boolean }) => void;\n setValue: (\n value: {\n hours: number;\n minutes: number;\n seconds: number;\n },\n options?: { animated?: boolean }\n ) => void;\n latestDuration: {\n hours: MutableRefObject<number> | undefined;\n minutes: MutableRefObject<number> | undefined;\n seconds: MutableRefObject<number> | undefined;\n };\n}\n\nexport interface TimerPickerModalProps extends TimerPickerProps {\n visible: boolean;\n setIsVisible: (isVisible: boolean) => void;\n onConfirm: ({\n hours,\n minutes,\n seconds,\n }: {\n hours: number;\n minutes: number;\n seconds: number;\n }) => void;\n onCancel?: () => void;\n closeOnOverlayPress?: boolean;\n hideCancelButton?: boolean;\n confirmButtonText?: string;\n cancelButtonText?: string;\n modalTitle?: string;\n modalProps?: React.ComponentProps<typeof Modal>;\n containerProps?: React.ComponentProps<typeof View>;\n contentContainerProps?: React.ComponentProps<typeof View>;\n buttonContainerProps?: React.ComponentProps<typeof View>;\n buttonTouchableOpacityProps?: React.ComponentProps<typeof TouchableOpacity>;\n modalTitleProps?: React.ComponentProps<typeof Text>;\n styles?: CustomTimerPickerModalStyles;\n}\n\nconst TimerPickerModal = forwardRef<TimerPickerModalRef, TimerPickerModalProps>(\n (\n {\n visible,\n setIsVisible,\n onConfirm,\n onCancel,\n onDurationChange,\n closeOnOverlayPress,\n initialHours = 0,\n initialMinutes = 0,\n initialSeconds = 0,\n hideHours = false,\n hideMinutes = false,\n hideSeconds = false,\n hourLimit,\n minuteLimit,\n secondLimit,\n hourLabel = \"h\",\n minuteLabel = \"m\",\n secondLabel = \"s\",\n padWithNItems = 1,\n disableInfiniteScroll = false,\n hideCancelButton = false,\n confirmButtonText = \"Confirm\",\n cancelButtonText = \"Cancel\",\n modalTitle,\n LinearGradient,\n modalProps,\n containerProps,\n contentContainerProps,\n pickerContainerProps,\n buttonContainerProps,\n buttonTouchableOpacityProps,\n modalTitleProps,\n pickerGradientOverlayProps,\n topPickerGradientOverlayProps,\n bottomPickerGradientOverlayProps,\n styles: customStyles,\n },\n ref\n ): React.ReactElement => {\n const styles = generateStyles(customStyles);\n\n const timerPickerRef = useRef<TimerPickerRef>(null);\n\n const [selectedDuration, setSelectedDuration] = useState({\n hours: initialHours,\n minutes: initialMinutes,\n seconds: initialSeconds,\n });\n const [confirmedDuration, setConfirmedDuration] = useState({\n hours: initialHours,\n minutes: initialMinutes,\n seconds: initialSeconds,\n });\n\n const hideModalHandler = () => {\n setSelectedDuration({\n hours: confirmedDuration.hours,\n minutes: confirmedDuration.minutes,\n seconds: confirmedDuration.seconds,\n });\n setIsVisible(false);\n };\n\n const confirmHandler = () => {\n const latestDuration = timerPickerRef.current?.latestDuration;\n const newDuration = {\n hours: latestDuration?.hours?.current ?? selectedDuration.hours,\n minutes:\n latestDuration?.minutes?.current ??\n selectedDuration.minutes,\n seconds:\n latestDuration?.seconds?.current ??\n selectedDuration.seconds,\n };\n setConfirmedDuration(newDuration);\n onConfirm(newDuration);\n };\n\n const cancelHandler = () => {\n setIsVisible(false);\n setSelectedDuration(confirmedDuration);\n onCancel?.();\n };\n\n // wrapped in useCallback to avoid unnecessary re-renders of TimerPicker\n const durationChangeHandler = useCallback(\n (duration: { hours: number; minutes: number; seconds: number }) => {\n setSelectedDuration(duration);\n onDurationChange?.(duration);\n },\n [onDurationChange]\n );\n\n useImperativeHandle(ref, () => ({\n reset: (options) => {\n const initialDuration = {\n hours: initialHours,\n minutes: initialMinutes,\n seconds: initialSeconds,\n };\n setSelectedDuration(initialDuration);\n setConfirmedDuration(initialDuration);\n timerPickerRef.current?.reset(options);\n },\n setValue: (value, options) => {\n setSelectedDuration(value);\n setConfirmedDuration(value);\n timerPickerRef.current?.setValue(value, options);\n },\n latestDuration: {\n hours: timerPickerRef.current?.latestDuration?.hours,\n minutes: timerPickerRef.current?.latestDuration?.minutes,\n seconds: timerPickerRef.current?.latestDuration?.seconds,\n },\n }));\n\n return (\n <Modal\n isVisible={visible}\n onOverlayPress={\n closeOnOverlayPress ? hideModalHandler : undefined\n }\n {...modalProps}\n testID=\"timer-picker-modal\">\n <View {...containerProps} style={styles.container}>\n <View\n {...contentContainerProps}\n style={styles.contentContainer}>\n {modalTitle ? (\n <Text\n {...modalTitleProps}\n style={styles.modalTitle}>\n {modalTitle}\n </Text>\n ) : null}\n <TimerPicker\n ref={timerPickerRef}\n onDurationChange={durationChangeHandler}\n initialHours={confirmedDuration.hours}\n initialMinutes={confirmedDuration.minutes}\n initialSeconds={confirmedDuration.seconds}\n aggressivelyGetLatestDuration={true}\n hideHours={hideHours}\n hideMinutes={hideMinutes}\n hideSeconds={hideSeconds}\n hourLimit={hourLimit}\n minuteLimit={minuteLimit}\n secondLimit={secondLimit}\n hourLabel={hourLabel}\n minuteLabel={minuteLabel}\n secondLabel={secondLabel}\n padWithNItems={padWithNItems}\n disableInfiniteScroll={disableInfiniteScroll}\n LinearGradient={LinearGradient}\n pickerContainerProps={pickerContainerProps}\n pickerGradientOverlayProps={\n pickerGradientOverlayProps\n }\n topPickerGradientOverlayProps={\n topPickerGradientOverlayProps\n }\n bottomPickerGradientOverlayProps={\n bottomPickerGradientOverlayProps\n }\n styles={customStyles}\n />\n <View\n {...buttonContainerProps}\n style={styles.buttonContainer}>\n {!hideCancelButton ? (\n <TouchableOpacity\n onPress={cancelHandler}\n {...buttonTouchableOpacityProps}>\n <Text\n style={[\n styles.button,\n styles.cancelButton,\n ]}>\n {cancelButtonText}\n </Text>\n </TouchableOpacity>\n ) : null}\n <TouchableOpacity\n onPress={confirmHandler}\n {...buttonTouchableOpacityProps}>\n <Text\n style={[\n styles.button,\n styles.confirmButton,\n ]}>\n {confirmButtonText}\n </Text>\n </TouchableOpacity>\n </View>\n </View>\n </View>\n </Modal>\n );\n }\n);\n\nexport default React.memo(TimerPickerModal);\n"],"mappings":";AAAA,OAAOA,KAAK,IAERC,UAAU,EACVC,WAAW,EACXC,mBAAmB,EACnBC,MAAM,EACNC,QAAQ,QACL,OAAO;AACd,SAASC,IAAI,EAAEC,IAAI,EAAEC,gBAAgB,QAAQ,cAAc;AAE3D,OAAOC,WAAW,MAA4C,eAAe;AAC7E,OAAOC,KAAK,MAAM,SAAS;AAE3B,SACIC,cAAc,QAEX,2BAA2B;AA8ClC,MAAMC,gBAAgB,gBAAGX,UAAU,CAC/B,CAAAY,IAAA,EAuCIC,GAAG,KACkB;EAAA,IAvCrB;IACIC,OAAO;IACPC,YAAY;IACZC,SAAS;IACTC,QAAQ;IACRC,gBAAgB;IAChBC,mBAAmB;IACnBC,YAAY,GAAG,CAAC;IAChBC,cAAc,GAAG,CAAC;IAClBC,cAAc,GAAG,CAAC;IAClBC,SAAS,GAAG,KAAK;IACjBC,WAAW,GAAG,KAAK;IACnBC,WAAW,GAAG,KAAK;IACnBC,SAAS;IACTC,WAAW;IACXC,WAAW;IACXC,SAAS,GAAG,GAAG;IACfC,WAAW,GAAG,GAAG;IACjBC,WAAW,GAAG,GAAG;IACjBC,aAAa,GAAG,CAAC;IACjBC,qBAAqB,GAAG,KAAK;IAC7BC,gBAAgB,GAAG,KAAK;IACxBC,iBAAiB,GAAG,SAAS;IAC7BC,gBAAgB,GAAG,QAAQ;IAC3BC,UAAU;IACVC,cAAc;IACdC,UAAU;IACVC,cAAc;IACdC,qBAAqB;IACrBC,oBAAoB;IACpBC,oBAAoB;IACpBC,2BAA2B;IAC3BC,eAAe;IACfC,0BAA0B;IAC1BC,6BAA6B;IAC7BC,gCAAgC;IAChCC,MAAM,EAAEC;EACZ,CAAC,GAAAtC,IAAA;EAGD,MAAMqC,MAAM,GAAGvC,cAAc,CAACwC,YAAY,CAAC;EAE3C,MAAMC,cAAc,GAAGhD,MAAM,CAAiB,IAAI,CAAC;EAEnD,MAAM,CAACiD,gBAAgB,EAAEC,mBAAmB,CAAC,GAAGjD,QAAQ,CAAC;IACrDkD,KAAK,EAAElC,YAAY;IACnBmC,OAAO,EAAElC,cAAc;IACvBmC,OAAO,EAAElC;EACb,CAAC,CAAC;EACF,MAAM,CAACmC,iBAAiB,EAAEC,oBAAoB,CAAC,GAAGtD,QAAQ,CAAC;IACvDkD,KAAK,EAAElC,YAAY;IACnBmC,OAAO,EAAElC,cAAc;IACvBmC,OAAO,EAAElC;EACb,CAAC,CAAC;EAEF,MAAMqC,gBAAgB,GAAGA,CAAA,KAAM;IAC3BN,mBAAmB,CAAC;MAChBC,KAAK,EAAEG,iBAAiB,CAACH,KAAK;MAC9BC,OAAO,EAAEE,iBAAiB,CAACF,OAAO;MAClCC,OAAO,EAAEC,iBAAiB,CAACD;IAC/B,CAAC,CAAC;IACFzC,YAAY,CAAC,KAAK,CAAC;EACvB,CAAC;EAED,MAAM6C,cAAc,GAAGA,CAAA,KAAM;IAAA,IAAAC,qBAAA,EAAAC,qBAAA,EAAAC,qBAAA,EAAAC,qBAAA;IACzB,MAAMC,cAAc,IAAAJ,qBAAA,GAAGV,cAAc,CAACe,OAAO,cAAAL,qBAAA,uBAAtBA,qBAAA,CAAwBI,cAAc;IAC7D,MAAME,WAAW,GAAG;MAChBb,KAAK,EAAE,CAAAW,cAAc,aAAdA,cAAc,gBAAAH,qBAAA,GAAdG,cAAc,CAAEX,KAAK,cAAAQ,qBAAA,uBAArBA,qBAAA,CAAuBI,OAAO,KAAId,gBAAgB,CAACE,KAAK;MAC/DC,OAAO,EACH,CAAAU,cAAc,aAAdA,cAAc,gBAAAF,qBAAA,GAAdE,cAAc,CAAEV,OAAO,cAAAQ,qBAAA,uBAAvBA,qBAAA,CAAyBG,OAAO,KAChCd,gBAAgB,CAACG,OAAO;MAC5BC,OAAO,EACH,CAAAS,cAAc,aAAdA,cAAc,gBAAAD,qBAAA,GAAdC,cAAc,CAAET,OAAO,cAAAQ,qBAAA,uBAAvBA,qBAAA,CAAyBE,OAAO,KAChCd,gBAAgB,CAACI;IACzB,CAAC;IACDE,oBAAoB,CAACS,WAAW,CAAC;IACjCnD,SAAS,CAACmD,WAAW,CAAC;EAC1B,CAAC;EAED,MAAMC,aAAa,GAAGA,CAAA,KAAM;IACxBrD,YAAY,CAAC,KAAK,CAAC;IACnBsC,mBAAmB,CAACI,iBAAiB,CAAC;IACtCxC,QAAQ,aAARA,QAAQ,eAARA,QAAQ,CAAG,CAAC;EAChB,CAAC;;EAED;EACA,MAAMoD,qBAAqB,GAAGpE,WAAW,CACpCqE,QAA6D,IAAK;IAC/DjB,mBAAmB,CAACiB,QAAQ,CAAC;IAC7BpD,gBAAgB,aAAhBA,gBAAgB,eAAhBA,gBAAgB,CAAGoD,QAAQ,CAAC;EAChC,CAAC,EACD,CAACpD,gBAAgB,CACrB,CAAC;EAEDhB,mBAAmB,CAACW,GAAG,EAAE;IAAA,IAAA0D,sBAAA,EAAAC,sBAAA,EAAAC,sBAAA;IAAA,OAAO;MAC5BC,KAAK,EAAGC,OAAO,IAAK;QAAA,IAAAC,sBAAA;QAChB,MAAMC,eAAe,GAAG;UACpBvB,KAAK,EAAElC,YAAY;UACnBmC,OAAO,EAAElC,cAAc;UACvBmC,OAAO,EAAElC;QACb,CAAC;QACD+B,mBAAmB,CAACwB,eAAe,CAAC;QACpCnB,oBAAoB,CAACmB,eAAe,CAAC;QACrC,CAAAD,sBAAA,GAAAzB,cAAc,CAACe,OAAO,cAAAU,sBAAA,eAAtBA,sBAAA,CAAwBF,KAAK,CAACC,OAAO,CAAC;MAC1C,CAAC;MACDG,QAAQ,EAAEA,CAACC,KAAK,EAAEJ,OAAO,KAAK;QAAA,IAAAK,sBAAA;QAC1B3B,mBAAmB,CAAC0B,KAAK,CAAC;QAC1BrB,oBAAoB,CAACqB,KAAK,CAAC;QAC3B,CAAAC,sBAAA,GAAA7B,cAAc,CAACe,OAAO,cAAAc,sBAAA,eAAtBA,sBAAA,CAAwBF,QAAQ,CAACC,KAAK,EAAEJ,OAAO,CAAC;MACpD,CAAC;MACDV,cAAc,EAAE;QACZX,KAAK,GAAAiB,sBAAA,GAAEpB,cAAc,CAACe,OAAO,cAAAK,sBAAA,gBAAAA,sBAAA,GAAtBA,sBAAA,CAAwBN,cAAc,cAAAM,sBAAA,uBAAtCA,sBAAA,CAAwCjB,KAAK;QACpDC,OAAO,GAAAiB,sBAAA,GAAErB,cAAc,CAACe,OAAO,cAAAM,sBAAA,gBAAAA,sBAAA,GAAtBA,sBAAA,CAAwBP,cAAc,cAAAO,sBAAA,uBAAtCA,sBAAA,CAAwCjB,OAAO;QACxDC,OAAO,GAAAiB,sBAAA,GAAEtB,cAAc,CAACe,OAAO,cAAAO,sBAAA,gBAAAA,sBAAA,GAAtBA,sBAAA,CAAwBR,cAAc,cAAAQ,sBAAA,uBAAtCA,sBAAA,CAAwCjB;MACrD;IACJ,CAAC;EAAA,CAAC,CAAC;EAEH,oBACIzD,KAAA,CAAAkF,aAAA,CAACxE,KAAK,EAAAyE,QAAA;IACFC,SAAS,EAAErE,OAAQ;IACnBsE,cAAc,EACVjE,mBAAmB,GAAGwC,gBAAgB,GAAG0B;EAC5C,GACG9C,UAAU;IACd+C,MAAM,EAAC;EAAoB,iBAC3BvF,KAAA,CAAAkF,aAAA,CAAC5E,IAAI,EAAA6E,QAAA,KAAK1C,cAAc;IAAE+C,KAAK,EAAEtC,MAAM,CAACuC;EAAU,iBAC9CzF,KAAA,CAAAkF,aAAA,CAAC5E,IAAI,EAAA6E,QAAA,KACGzC,qBAAqB;IACzB8C,KAAK,EAAEtC,MAAM,CAACwC;EAAiB,IAC9BpD,UAAU,gBACPtC,KAAA,CAAAkF,aAAA,CAAC3E,IAAI,EAAA4E,QAAA,KACGrC,eAAe;IACnB0C,KAAK,EAAEtC,MAAM,CAACZ;EAAW,IACxBA,UACC,CAAC,GACP,IAAI,eACRtC,KAAA,CAAAkF,aAAA,CAACzE,WAAW;IACRK,GAAG,EAAEsC,cAAe;IACpBjC,gBAAgB,EAAEmD,qBAAsB;IACxCjD,YAAY,EAAEqC,iBAAiB,CAACH,KAAM;IACtCjC,cAAc,EAAEoC,iBAAiB,CAACF,OAAQ;IAC1CjC,cAAc,EAAEmC,iBAAiB,CAACD,OAAQ;IAC1CkC,6BAA6B,EAAE,IAAK;IACpCnE,SAAS,EAAEA,SAAU;IACrBC,WAAW,EAAEA,WAAY;IACzBC,WAAW,EAAEA,WAAY;IACzBC,SAAS,EAAEA,SAAU;IACrBC,WAAW,EAAEA,WAAY;IACzBC,WAAW,EAAEA,WAAY;IACzBC,SAAS,EAAEA,SAAU;IACrBC,WAAW,EAAEA,WAAY;IACzBC,WAAW,EAAEA,WAAY;IACzBC,aAAa,EAAEA,aAAc;IAC7BC,qBAAqB,EAAEA,qBAAsB;IAC7CK,cAAc,EAAEA,cAAe;IAC/BI,oBAAoB,EAAEA,oBAAqB;IAC3CI,0BAA0B,EACtBA,0BACH;IACDC,6BAA6B,EACzBA,6BACH;IACDC,gCAAgC,EAC5BA,gCACH;IACDC,MAAM,EAAEC;EAAa,CACxB,CAAC,eACFnD,KAAA,CAAAkF,aAAA,CAAC5E,IAAI,EAAA6E,QAAA,KACGvC,oBAAoB;IACxB4C,KAAK,EAAEtC,MAAM,CAAC0C;EAAgB,IAC7B,CAACzD,gBAAgB,gBACdnC,KAAA,CAAAkF,aAAA,CAAC1E,gBAAgB,EAAA2E,QAAA;IACbU,OAAO,EAAExB;EAAc,GACnBxB,2BAA2B,gBAC/B7C,KAAA,CAAAkF,aAAA,CAAC3E,IAAI;IACDiF,KAAK,EAAE,CACHtC,MAAM,CAAC4C,MAAM,EACb5C,MAAM,CAAC6C,YAAY;EACrB,GACD1D,gBACC,CACQ,CAAC,GACnB,IAAI,eACRrC,KAAA,CAAAkF,aAAA,CAAC1E,gBAAgB,EAAA2E,QAAA;IACbU,OAAO,EAAEhC;EAAe,GACpBhB,2BAA2B,gBAC/B7C,KAAA,CAAAkF,aAAA,CAAC3E,IAAI;IACDiF,KAAK,EAAE,CACHtC,MAAM,CAAC4C,MAAM,EACb5C,MAAM,CAAC8C,aAAa;EACtB,GACD5D,iBACC,CACQ,CAChB,CACJ,CACJ,CACH,CAAC;AAEhB,CACJ,CAAC;AAED,4BAAepC,KAAK,CAACiG,IAAI,CAACrF,gBAAgB,CAAC"}
1
+ {"version":3,"names":["React","forwardRef","useCallback","useImperativeHandle","useRef","useState","View","Text","TouchableOpacity","TimerPicker","Modal","generateStyles","TimerPickerModal","visible","setIsVisible","onConfirm","onCancel","onDurationChange","closeOnOverlayPress","initialHours","initialMinutes","initialSeconds","hideHours","hideMinutes","hideSeconds","hourLimit","minuteLimit","secondLimit","hourLabel","minuteLabel","secondLabel","padWithNItems","disableInfiniteScroll","use12HourPicker","amLabel","pmLabel","hideCancelButton","confirmButtonText","cancelButtonText","modalTitle","LinearGradient","modalProps","containerProps","contentContainerProps","pickerContainerProps","buttonContainerProps","buttonTouchableOpacityProps","modalTitleProps","pickerGradientOverlayProps","topPickerGradientOverlayProps","bottomPickerGradientOverlayProps","styles","customStyles","ref","timerPickerRef","selectedDuration","setSelectedDuration","hours","minutes","seconds","confirmedDuration","setConfirmedDuration","hideModalHandler","confirmHandler","_timerPickerRef$curre","_latestDuration$hours","_latestDuration$minut","_latestDuration$secon","latestDuration","current","newDuration","cancelHandler","durationChangeHandler","duration","_timerPickerRef$curre4","_timerPickerRef$curre5","_timerPickerRef$curre6","reset","options","_timerPickerRef$curre2","initialDuration","setValue","value","_timerPickerRef$curre3","createElement","_extends","isVisible","onOverlayPress","undefined","testID","style","container","contentContainer","aggressivelyGetLatestDuration","buttonContainer","onPress","button","cancelButton","confirmButton","memo"],"sources":["index.tsx"],"sourcesContent":["import React, {\n MutableRefObject,\n forwardRef,\n useCallback,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { View, Text, TouchableOpacity } from \"react-native\";\n\nimport TimerPicker, { TimerPickerProps, TimerPickerRef } from \"./TimerPicker\";\nimport Modal from \"./Modal\";\n\nimport {\n generateStyles,\n CustomTimerPickerModalStyles,\n} from \"./TimerPickerModal.styles\";\n\nexport interface TimerPickerModalRef {\n reset: (options?: { animated?: boolean }) => void;\n setValue: (\n value: {\n hours: number;\n minutes: number;\n seconds: number;\n },\n options?: { animated?: boolean }\n ) => void;\n latestDuration: {\n hours: MutableRefObject<number> | undefined;\n minutes: MutableRefObject<number> | undefined;\n seconds: MutableRefObject<number> | undefined;\n };\n}\n\nexport interface TimerPickerModalProps extends TimerPickerProps {\n visible: boolean;\n setIsVisible: (isVisible: boolean) => void;\n onConfirm: ({\n hours,\n minutes,\n seconds,\n }: {\n hours: number;\n minutes: number;\n seconds: number;\n }) => void;\n onCancel?: () => void;\n closeOnOverlayPress?: boolean;\n hideCancelButton?: boolean;\n confirmButtonText?: string;\n cancelButtonText?: string;\n modalTitle?: string;\n modalProps?: React.ComponentProps<typeof Modal>;\n containerProps?: React.ComponentProps<typeof View>;\n contentContainerProps?: React.ComponentProps<typeof View>;\n buttonContainerProps?: React.ComponentProps<typeof View>;\n buttonTouchableOpacityProps?: React.ComponentProps<typeof TouchableOpacity>;\n modalTitleProps?: React.ComponentProps<typeof Text>;\n styles?: CustomTimerPickerModalStyles;\n}\n\nconst TimerPickerModal = forwardRef<TimerPickerModalRef, TimerPickerModalProps>(\n (\n {\n visible,\n setIsVisible,\n onConfirm,\n onCancel,\n onDurationChange,\n closeOnOverlayPress,\n initialHours = 0,\n initialMinutes = 0,\n initialSeconds = 0,\n hideHours = false,\n hideMinutes = false,\n hideSeconds = false,\n hourLimit,\n minuteLimit,\n secondLimit,\n hourLabel,\n minuteLabel,\n secondLabel,\n padWithNItems = 1,\n disableInfiniteScroll = false,\n use12HourPicker,\n amLabel,\n pmLabel,\n hideCancelButton = false,\n confirmButtonText = \"Confirm\",\n cancelButtonText = \"Cancel\",\n modalTitle,\n LinearGradient,\n modalProps,\n containerProps,\n contentContainerProps,\n pickerContainerProps,\n buttonContainerProps,\n buttonTouchableOpacityProps,\n modalTitleProps,\n pickerGradientOverlayProps,\n topPickerGradientOverlayProps,\n bottomPickerGradientOverlayProps,\n styles: customStyles,\n },\n ref\n ): React.ReactElement => {\n const styles = generateStyles(customStyles);\n\n const timerPickerRef = useRef<TimerPickerRef>(null);\n\n const [selectedDuration, setSelectedDuration] = useState({\n hours: initialHours,\n minutes: initialMinutes,\n seconds: initialSeconds,\n });\n const [confirmedDuration, setConfirmedDuration] = useState({\n hours: initialHours,\n minutes: initialMinutes,\n seconds: initialSeconds,\n });\n\n const hideModalHandler = () => {\n setSelectedDuration({\n hours: confirmedDuration.hours,\n minutes: confirmedDuration.minutes,\n seconds: confirmedDuration.seconds,\n });\n setIsVisible(false);\n };\n\n const confirmHandler = () => {\n const latestDuration = timerPickerRef.current?.latestDuration;\n const newDuration = {\n hours: latestDuration?.hours?.current ?? selectedDuration.hours,\n minutes:\n latestDuration?.minutes?.current ??\n selectedDuration.minutes,\n seconds:\n latestDuration?.seconds?.current ??\n selectedDuration.seconds,\n };\n setConfirmedDuration(newDuration);\n onConfirm(newDuration);\n };\n\n const cancelHandler = () => {\n setIsVisible(false);\n setSelectedDuration(confirmedDuration);\n onCancel?.();\n };\n\n // wrapped in useCallback to avoid unnecessary re-renders of TimerPicker\n const durationChangeHandler = useCallback(\n (duration: { hours: number; minutes: number; seconds: number }) => {\n setSelectedDuration(duration);\n onDurationChange?.(duration);\n },\n [onDurationChange]\n );\n\n useImperativeHandle(ref, () => ({\n reset: (options) => {\n const initialDuration = {\n hours: initialHours,\n minutes: initialMinutes,\n seconds: initialSeconds,\n };\n setSelectedDuration(initialDuration);\n setConfirmedDuration(initialDuration);\n timerPickerRef.current?.reset(options);\n },\n setValue: (value, options) => {\n setSelectedDuration(value);\n setConfirmedDuration(value);\n timerPickerRef.current?.setValue(value, options);\n },\n latestDuration: {\n hours: timerPickerRef.current?.latestDuration?.hours,\n minutes: timerPickerRef.current?.latestDuration?.minutes,\n seconds: timerPickerRef.current?.latestDuration?.seconds,\n },\n }));\n\n return (\n <Modal\n isVisible={visible}\n onOverlayPress={\n closeOnOverlayPress ? hideModalHandler : undefined\n }\n {...modalProps}\n testID=\"timer-picker-modal\">\n <View {...containerProps} style={styles.container}>\n <View\n {...contentContainerProps}\n style={styles.contentContainer}>\n {modalTitle ? (\n <Text\n {...modalTitleProps}\n style={styles.modalTitle}>\n {modalTitle}\n </Text>\n ) : null}\n <TimerPicker\n ref={timerPickerRef}\n onDurationChange={durationChangeHandler}\n initialHours={confirmedDuration.hours}\n initialMinutes={confirmedDuration.minutes}\n initialSeconds={confirmedDuration.seconds}\n aggressivelyGetLatestDuration={true}\n hideHours={hideHours}\n hideMinutes={hideMinutes}\n hideSeconds={hideSeconds}\n hourLimit={hourLimit}\n minuteLimit={minuteLimit}\n secondLimit={secondLimit}\n hourLabel={hourLabel}\n minuteLabel={minuteLabel}\n secondLabel={secondLabel}\n padWithNItems={padWithNItems}\n disableInfiniteScroll={disableInfiniteScroll}\n use12HourPicker={use12HourPicker}\n amLabel={amLabel}\n pmLabel={pmLabel}\n LinearGradient={LinearGradient}\n pickerContainerProps={pickerContainerProps}\n pickerGradientOverlayProps={\n pickerGradientOverlayProps\n }\n topPickerGradientOverlayProps={\n topPickerGradientOverlayProps\n }\n bottomPickerGradientOverlayProps={\n bottomPickerGradientOverlayProps\n }\n styles={customStyles}\n />\n <View\n {...buttonContainerProps}\n style={styles.buttonContainer}>\n {!hideCancelButton ? (\n <TouchableOpacity\n onPress={cancelHandler}\n {...buttonTouchableOpacityProps}>\n <Text\n style={[\n styles.button,\n styles.cancelButton,\n ]}>\n {cancelButtonText}\n </Text>\n </TouchableOpacity>\n ) : null}\n <TouchableOpacity\n onPress={confirmHandler}\n {...buttonTouchableOpacityProps}>\n <Text\n style={[\n styles.button,\n styles.confirmButton,\n ]}>\n {confirmButtonText}\n </Text>\n </TouchableOpacity>\n </View>\n </View>\n </View>\n </Modal>\n );\n }\n);\n\nexport default React.memo(TimerPickerModal);\n"],"mappings":"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"}
@@ -6,7 +6,9 @@ describe("Modal", () => {
6
6
  it("renders without crashing", () => {
7
7
  const {
8
8
  getByTestId
9
- } = render( /*#__PURE__*/React.createElement(Modal, null));
9
+ } = render( /*#__PURE__*/React.createElement(Modal, {
10
+ isVisible: true
11
+ }));
10
12
  const component = getByTestId("modal");
11
13
  expect(component).toBeDefined();
12
14
  });
@@ -1 +1 @@
1
- {"version":3,"names":["React","Text","render","fireEvent","Modal","describe","it","getByTestId","createElement","component","expect","toBeDefined","getByText","isVisible","content","onOverlayPressMock","jest","fn","onOverlayPress","overlay","press","toHaveBeenCalled"],"sources":["Modal.test.tsx"],"sourcesContent":["import React from \"react\";\nimport { Text } from \"react-native\";\nimport { render, fireEvent } from \"@testing-library/react-native\";\nimport Modal from \"../components/Modal\";\n\ndescribe(\"Modal\", () => {\n it(\"renders without crashing\", () => {\n const { getByTestId } = render(<Modal />);\n const component = getByTestId(\"modal\");\n expect(component).toBeDefined();\n });\n\n it(\"renders children when visible\", () => {\n const { getByText } = render(\n <Modal isVisible>\n <Text>{\"Modal Content\"}</Text>\n </Modal>\n );\n const content = getByText(\"Modal Content\");\n expect(content).toBeDefined();\n });\n\n it(\"calls onOverlayPress when overlay is pressed\", () => {\n const onOverlayPressMock = jest.fn();\n const { getByTestId } = render(\n <Modal isVisible onOverlayPress={onOverlayPressMock} />\n );\n const overlay = getByTestId(\"modal-backdrop\");\n fireEvent.press(overlay);\n expect(onOverlayPressMock).toHaveBeenCalled();\n });\n\n // Add more test cases to cover different interactions, scenarios, and edge cases\n});\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,EAAEC,SAAS,QAAQ,+BAA+B;AACjE,OAAOC,KAAK,MAAM,qBAAqB;AAEvCC,QAAQ,CAAC,OAAO,EAAE,MAAM;EACpBC,EAAE,CAAC,0BAA0B,EAAE,MAAM;IACjC,MAAM;MAAEC;IAAY,CAAC,GAAGL,MAAM,eAACF,KAAA,CAAAQ,aAAA,CAACJ,KAAK,MAAE,CAAC,CAAC;IACzC,MAAMK,SAAS,GAAGF,WAAW,CAAC,OAAO,CAAC;IACtCG,MAAM,CAACD,SAAS,CAAC,CAACE,WAAW,CAAC,CAAC;EACnC,CAAC,CAAC;EAEFL,EAAE,CAAC,+BAA+B,EAAE,MAAM;IACtC,MAAM;MAAEM;IAAU,CAAC,GAAGV,MAAM,eACxBF,KAAA,CAAAQ,aAAA,CAACJ,KAAK;MAACS,SAAS;IAAA,gBACZb,KAAA,CAAAQ,aAAA,CAACP,IAAI,QAAE,eAAsB,CAC1B,CACX,CAAC;IACD,MAAMa,OAAO,GAAGF,SAAS,CAAC,eAAe,CAAC;IAC1CF,MAAM,CAACI,OAAO,CAAC,CAACH,WAAW,CAAC,CAAC;EACjC,CAAC,CAAC;EAEFL,EAAE,CAAC,8CAA8C,EAAE,MAAM;IACrD,MAAMS,kBAAkB,GAAGC,IAAI,CAACC,EAAE,CAAC,CAAC;IACpC,MAAM;MAAEV;IAAY,CAAC,GAAGL,MAAM,eAC1BF,KAAA,CAAAQ,aAAA,CAACJ,KAAK;MAACS,SAAS;MAACK,cAAc,EAAEH;IAAmB,CAAE,CAC1D,CAAC;IACD,MAAMI,OAAO,GAAGZ,WAAW,CAAC,gBAAgB,CAAC;IAC7CJ,SAAS,CAACiB,KAAK,CAACD,OAAO,CAAC;IACxBT,MAAM,CAACK,kBAAkB,CAAC,CAACM,gBAAgB,CAAC,CAAC;EACjD,CAAC,CAAC;;EAEF;AACJ,CAAC,CAAC"}
1
+ {"version":3,"names":["React","Text","render","fireEvent","Modal","describe","it","getByTestId","createElement","isVisible","component","expect","toBeDefined","getByText","content","onOverlayPressMock","jest","fn","onOverlayPress","overlay","press","toHaveBeenCalled"],"sources":["Modal.test.tsx"],"sourcesContent":["import React from \"react\";\nimport { Text } from \"react-native\";\nimport { render, fireEvent } from \"@testing-library/react-native\";\nimport Modal from \"../components/Modal\";\n\ndescribe(\"Modal\", () => {\n it(\"renders without crashing\", () => {\n const { getByTestId } = render(<Modal isVisible/>);\n const component = getByTestId(\"modal\");\n expect(component).toBeDefined();\n });\n\n it(\"renders children when visible\", () => {\n const { getByText } = render(\n <Modal isVisible>\n <Text>{\"Modal Content\"}</Text>\n </Modal>\n );\n const content = getByText(\"Modal Content\");\n expect(content).toBeDefined();\n });\n\n it(\"calls onOverlayPress when overlay is pressed\", () => {\n const onOverlayPressMock = jest.fn();\n const { getByTestId } = render(\n <Modal isVisible onOverlayPress={onOverlayPressMock} />\n );\n const overlay = getByTestId(\"modal-backdrop\");\n fireEvent.press(overlay);\n expect(onOverlayPressMock).toHaveBeenCalled();\n });\n\n // Add more test cases to cover different interactions, scenarios, and edge cases\n});\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,MAAM,EAAEC,SAAS,QAAQ,+BAA+B;AACjE,OAAOC,KAAK,MAAM,qBAAqB;AAEvCC,QAAQ,CAAC,OAAO,EAAE,MAAM;EACpBC,EAAE,CAAC,0BAA0B,EAAE,MAAM;IACjC,MAAM;MAAEC;IAAY,CAAC,GAAGL,MAAM,eAACF,KAAA,CAAAQ,aAAA,CAACJ,KAAK;MAACK,SAAS;IAAA,CAAC,CAAC,CAAC;IAClD,MAAMC,SAAS,GAAGH,WAAW,CAAC,OAAO,CAAC;IACtCI,MAAM,CAACD,SAAS,CAAC,CAACE,WAAW,CAAC,CAAC;EACnC,CAAC,CAAC;EAEFN,EAAE,CAAC,+BAA+B,EAAE,MAAM;IACtC,MAAM;MAAEO;IAAU,CAAC,GAAGX,MAAM,eACxBF,KAAA,CAAAQ,aAAA,CAACJ,KAAK;MAACK,SAAS;IAAA,gBACZT,KAAA,CAAAQ,aAAA,CAACP,IAAI,QAAE,eAAsB,CAC1B,CACX,CAAC;IACD,MAAMa,OAAO,GAAGD,SAAS,CAAC,eAAe,CAAC;IAC1CF,MAAM,CAACG,OAAO,CAAC,CAACF,WAAW,CAAC,CAAC;EACjC,CAAC,CAAC;EAEFN,EAAE,CAAC,8CAA8C,EAAE,MAAM;IACrD,MAAMS,kBAAkB,GAAGC,IAAI,CAACC,EAAE,CAAC,CAAC;IACpC,MAAM;MAAEV;IAAY,CAAC,GAAGL,MAAM,eAC1BF,KAAA,CAAAQ,aAAA,CAACJ,KAAK;MAACK,SAAS;MAACS,cAAc,EAAEH;IAAmB,CAAE,CAC1D,CAAC;IACD,MAAMI,OAAO,GAAGZ,WAAW,CAAC,gBAAgB,CAAC;IAC7CJ,SAAS,CAACiB,KAAK,CAACD,OAAO,CAAC;IACxBR,MAAM,CAACI,kBAAkB,CAAC,CAACM,gBAAgB,CAAC,CAAC;EACjD,CAAC,CAAC;;EAEF;AACJ,CAAC,CAAC"}
@@ -1,17 +1,39 @@
1
- import { padWithZero } from "./padWithZero";
1
+ import { padNumber } from "./padNumber";
2
2
  export const generateNumbers = (numberOfItems, options) => {
3
3
  if (numberOfItems <= 0) {
4
4
  return [];
5
5
  }
6
6
  let numbers = [];
7
- if (options.padWithZero) {
8
- for (let i = 0; i <= numberOfItems; i++) {
9
- numbers.push(padWithZero(i));
10
- }
11
- } else {
12
- for (let i = 0; i <= numberOfItems; i++) {
13
- numbers.push(String(i));
14
- }
7
+ for (let i = 0; i <= numberOfItems; i++) {
8
+ numbers.push(padNumber(i, {
9
+ padWithZero: options.padNumbersWithZero
10
+ }));
11
+ }
12
+ if ((options.repeatNTimes ?? 1) > 1) {
13
+ numbers = Array(options.repeatNTimes).fill(numbers).flat();
14
+ }
15
+ if (options.disableInfiniteScroll) {
16
+ numbers.push(...Array(options.padWithNItems).fill(""));
17
+ numbers.unshift(...Array(options.padWithNItems).fill(""));
18
+ }
19
+ return numbers;
20
+ };
21
+ export const generate12HourNumbers = options => {
22
+ let numbers = [];
23
+
24
+ // Generate numbers from 0 to 11 for AM
25
+ for (let i = 0; i <= 11; i++) {
26
+ numbers.push(`${padNumber(i, {
27
+ padWithZero: options.padNumbersWithZero
28
+ })} AM`);
29
+ }
30
+
31
+ // Generate numbers from 12 to 11 for PM
32
+ for (let i = 12; i <= 23; i++) {
33
+ const hour = i > 12 ? i - 12 : i;
34
+ numbers.push(`${padNumber(hour, {
35
+ padWithZero: options.padNumbersWithZero
36
+ })} PM`);
15
37
  }
16
38
  if ((options.repeatNTimes ?? 1) > 1) {
17
39
  numbers = Array(options.repeatNTimes).fill(numbers).flat();
@@ -1 +1 @@
1
- {"version":3,"names":["padWithZero","generateNumbers","numberOfItems","options","numbers","i","push","String","repeatNTimes","Array","fill","flat","disableInfiniteScroll","padWithNItems","unshift"],"sources":["generateNumbers.ts"],"sourcesContent":["import { padWithZero } from \"./padWithZero\";\n\nexport const generateNumbers = (\n numberOfItems: number,\n options: {\n repeatNTimes?: number;\n padWithZero?: boolean;\n disableInfiniteScroll?: boolean;\n padWithNItems: number;\n }\n) => {\n if (numberOfItems <= 0) {\n return [];\n }\n\n let numbers: string[] = [];\n if (options.padWithZero) {\n for (let i = 0; i <= numberOfItems; i++) {\n numbers.push(padWithZero(i));\n }\n } else {\n for (let i = 0; i <= numberOfItems; i++) {\n numbers.push(String(i));\n }\n }\n if ((options.repeatNTimes ?? 1) > 1) {\n numbers = Array(options.repeatNTimes).fill(numbers).flat();\n }\n if (options.disableInfiniteScroll) {\n numbers.push(...Array(options.padWithNItems).fill(\"\"));\n numbers.unshift(...Array(options.padWithNItems).fill(\"\"));\n }\n return numbers;\n};\n"],"mappings":"AAAA,SAASA,WAAW,QAAQ,eAAe;AAE3C,OAAO,MAAMC,eAAe,GAAGA,CAC3BC,aAAqB,EACrBC,OAKC,KACA;EACD,IAAID,aAAa,IAAI,CAAC,EAAE;IACpB,OAAO,EAAE;EACb;EAEA,IAAIE,OAAiB,GAAG,EAAE;EAC1B,IAAID,OAAO,CAACH,WAAW,EAAE;IACrB,KAAK,IAAIK,CAAC,GAAG,CAAC,EAAEA,CAAC,IAAIH,aAAa,EAAEG,CAAC,EAAE,EAAE;MACrCD,OAAO,CAACE,IAAI,CAACN,WAAW,CAACK,CAAC,CAAC,CAAC;IAChC;EACJ,CAAC,MAAM;IACH,KAAK,IAAIA,CAAC,GAAG,CAAC,EAAEA,CAAC,IAAIH,aAAa,EAAEG,CAAC,EAAE,EAAE;MACrCD,OAAO,CAACE,IAAI,CAACC,MAAM,CAACF,CAAC,CAAC,CAAC;IAC3B;EACJ;EACA,IAAI,CAACF,OAAO,CAACK,YAAY,IAAI,CAAC,IAAI,CAAC,EAAE;IACjCJ,OAAO,GAAGK,KAAK,CAACN,OAAO,CAACK,YAAY,CAAC,CAACE,IAAI,CAACN,OAAO,CAAC,CAACO,IAAI,CAAC,CAAC;EAC9D;EACA,IAAIR,OAAO,CAACS,qBAAqB,EAAE;IAC/BR,OAAO,CAACE,IAAI,CAAC,GAAGG,KAAK,CAACN,OAAO,CAACU,aAAa,CAAC,CAACH,IAAI,CAAC,EAAE,CAAC,CAAC;IACtDN,OAAO,CAACU,OAAO,CAAC,GAAGL,KAAK,CAACN,OAAO,CAACU,aAAa,CAAC,CAACH,IAAI,CAAC,EAAE,CAAC,CAAC;EAC7D;EACA,OAAON,OAAO;AAClB,CAAC"}
1
+ {"version":3,"names":["padNumber","generateNumbers","numberOfItems","options","numbers","i","push","padWithZero","padNumbersWithZero","repeatNTimes","Array","fill","flat","disableInfiniteScroll","padWithNItems","unshift","generate12HourNumbers","hour"],"sources":["generateNumbers.ts"],"sourcesContent":["import { padNumber } from \"./padNumber\";\n\nexport const generateNumbers = (\n numberOfItems: number,\n options: {\n repeatNTimes?: number;\n padNumbersWithZero?: boolean;\n disableInfiniteScroll?: boolean;\n padWithNItems: number;\n }\n) => {\n if (numberOfItems <= 0) {\n return [];\n }\n\n let numbers: string[] = [];\n for (let i = 0; i <= numberOfItems; i++) {\n numbers.push(padNumber(i, { padWithZero: options.padNumbersWithZero }));\n }\n\n if ((options.repeatNTimes ?? 1) > 1) {\n numbers = Array(options.repeatNTimes).fill(numbers).flat();\n }\n if (options.disableInfiniteScroll) {\n numbers.push(...Array(options.padWithNItems).fill(\"\"));\n numbers.unshift(...Array(options.padWithNItems).fill(\"\"));\n }\n return numbers;\n};\n\nexport const generate12HourNumbers = (options: {\n repeatNTimes?: number;\n padNumbersWithZero?: boolean;\n disableInfiniteScroll?: boolean;\n padWithNItems: number;\n}) => {\n let numbers: string[] = [];\n\n // Generate numbers from 0 to 11 for AM\n for (let i = 0; i <= 11; i++) {\n numbers.push(\n `${padNumber(i, { padWithZero: options.padNumbersWithZero })} AM`\n );\n }\n\n // Generate numbers from 12 to 11 for PM\n for (let i = 12; i <= 23; i++) {\n const hour = i > 12 ? i - 12 : i;\n numbers.push(\n `${padNumber(hour, { padWithZero: options.padNumbersWithZero })} PM`\n );\n }\n\n if ((options.repeatNTimes ?? 1) > 1) {\n numbers = Array(options.repeatNTimes).fill(numbers).flat();\n }\n\n if (options.disableInfiniteScroll) {\n numbers.push(...Array(options.padWithNItems).fill(\"\"));\n numbers.unshift(...Array(options.padWithNItems).fill(\"\"));\n }\n\n return numbers;\n};\n"],"mappings":"AAAA,SAASA,SAAS,QAAQ,aAAa;AAEvC,OAAO,MAAMC,eAAe,GAAGA,CAC3BC,aAAqB,EACrBC,OAKC,KACA;EACD,IAAID,aAAa,IAAI,CAAC,EAAE;IACpB,OAAO,EAAE;EACb;EAEA,IAAIE,OAAiB,GAAG,EAAE;EAC1B,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,IAAIH,aAAa,EAAEG,CAAC,EAAE,EAAE;IACrCD,OAAO,CAACE,IAAI,CAACN,SAAS,CAACK,CAAC,EAAE;MAAEE,WAAW,EAAEJ,OAAO,CAACK;IAAmB,CAAC,CAAC,CAAC;EAC3E;EAEA,IAAI,CAACL,OAAO,CAACM,YAAY,IAAI,CAAC,IAAI,CAAC,EAAE;IACjCL,OAAO,GAAGM,KAAK,CAACP,OAAO,CAACM,YAAY,CAAC,CAACE,IAAI,CAACP,OAAO,CAAC,CAACQ,IAAI,CAAC,CAAC;EAC9D;EACA,IAAIT,OAAO,CAACU,qBAAqB,EAAE;IAC/BT,OAAO,CAACE,IAAI,CAAC,GAAGI,KAAK,CAACP,OAAO,CAACW,aAAa,CAAC,CAACH,IAAI,CAAC,EAAE,CAAC,CAAC;IACtDP,OAAO,CAACW,OAAO,CAAC,GAAGL,KAAK,CAACP,OAAO,CAACW,aAAa,CAAC,CAACH,IAAI,CAAC,EAAE,CAAC,CAAC;EAC7D;EACA,OAAOP,OAAO;AAClB,CAAC;AAED,OAAO,MAAMY,qBAAqB,GAAIb,OAKrC,IAAK;EACF,IAAIC,OAAiB,GAAG,EAAE;;EAE1B;EACA,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,IAAI,EAAE,EAAEA,CAAC,EAAE,EAAE;IAC1BD,OAAO,CAACE,IAAI,CACP,GAAEN,SAAS,CAACK,CAAC,EAAE;MAAEE,WAAW,EAAEJ,OAAO,CAACK;IAAmB,CAAC,CAAE,KACjE,CAAC;EACL;;EAEA;EACA,KAAK,IAAIH,CAAC,GAAG,EAAE,EAAEA,CAAC,IAAI,EAAE,EAAEA,CAAC,EAAE,EAAE;IAC3B,MAAMY,IAAI,GAAGZ,CAAC,GAAG,EAAE,GAAGA,CAAC,GAAG,EAAE,GAAGA,CAAC;IAChCD,OAAO,CAACE,IAAI,CACP,GAAEN,SAAS,CAACiB,IAAI,EAAE;MAAEV,WAAW,EAAEJ,OAAO,CAACK;IAAmB,CAAC,CAAE,KACpE,CAAC;EACL;EAEA,IAAI,CAACL,OAAO,CAACM,YAAY,IAAI,CAAC,IAAI,CAAC,EAAE;IACjCL,OAAO,GAAGM,KAAK,CAACP,OAAO,CAACM,YAAY,CAAC,CAACE,IAAI,CAACP,OAAO,CAAC,CAACQ,IAAI,CAAC,CAAC;EAC9D;EAEA,IAAIT,OAAO,CAACU,qBAAqB,EAAE;IAC/BT,OAAO,CAACE,IAAI,CAAC,GAAGI,KAAK,CAACP,OAAO,CAACW,aAAa,CAAC,CAACH,IAAI,CAAC,EAAE,CAAC,CAAC;IACtDP,OAAO,CAACW,OAAO,CAAC,GAAGL,KAAK,CAACP,OAAO,CAACW,aAAa,CAAC,CAACH,IAAI,CAAC,EAAE,CAAC,CAAC;EAC7D;EAEA,OAAOP,OAAO;AAClB,CAAC"}
@@ -0,0 +1,8 @@
1
+ export const padNumber = (value, options) => {
2
+ if (value < 10) {
3
+ return (options !== null && options !== void 0 && options.padWithZero ? "0" : " ") + value;
4
+ } else {
5
+ return String(value);
6
+ }
7
+ };
8
+ //# sourceMappingURL=padNumber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["padNumber","value","options","padWithZero","String"],"sources":["padNumber.ts"],"sourcesContent":["export const padNumber = (\n value: number,\n options?: { padWithZero?: boolean }\n): string => {\n if (value < 10) {\n return (options?.padWithZero ? \"0\" : \" \") + value;\n } else {\n return String(value);\n }\n};\n"],"mappings":"AAAA,OAAO,MAAMA,SAAS,GAAGA,CACrBC,KAAa,EACbC,OAAmC,KAC1B;EACT,IAAID,KAAK,GAAG,EAAE,EAAE;IACZ,OAAO,CAACC,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEC,WAAW,GAAG,GAAG,GAAG,GAAG,IAAIF,KAAK;EACrD,CAAC,MAAM;IACH,OAAOG,MAAM,CAACH,KAAK,CAAC;EACxB;AACJ,CAAC"}
@@ -33,6 +33,9 @@ interface DurationScrollProps {
33
33
  disableInfiniteScroll?: boolean;
34
34
  limit?: LimitType;
35
35
  aggressivelyGetLatestDuration: boolean;
36
+ is12HourPicker?: boolean;
37
+ amLabel?: string;
38
+ pmLabel?: string;
36
39
  padWithNItems: number;
37
40
  pickerGradientOverlayProps?: Partial<LinearGradientProps>;
38
41
  topPickerGradientOverlayProps?: Partial<LinearGradientProps>;
@@ -5,6 +5,8 @@ export interface CustomTimerPickerStyles {
5
5
  pickerContainer?: any;
6
6
  pickerLabelContainer?: any;
7
7
  pickerLabel?: any;
8
+ pickerAmPmContainer?: any;
9
+ pickerAmPmLabel?: any;
8
10
  pickerItemContainer?: any;
9
11
  pickerItem?: any;
10
12
  disabledPickerItem?: any;
@@ -18,6 +20,8 @@ export declare const generateStyles: (customStyles: CustomTimerPickerStyles | un
18
20
  pickerLabel: any;
19
21
  pickerItemContainer: any;
20
22
  pickerItem: any;
23
+ pickerAmPmContainer: any;
24
+ pickerAmPmLabel: any;
21
25
  disabledPickerItem: any;
22
26
  pickerGradientOverlay: any;
23
27
  };
@@ -30,6 +30,9 @@ export interface TimerPickerProps {
30
30
  initialMinutes?: number;
31
31
  initialSeconds?: number;
32
32
  aggressivelyGetLatestDuration?: boolean;
33
+ use12HourPicker?: boolean;
34
+ amLabel?: string;
35
+ pmLabel?: string;
33
36
  hideHours?: boolean;
34
37
  hideMinutes?: boolean;
35
38
  hideSeconds?: boolean;
@@ -1,7 +1,12 @@
1
- import { padWithZero } from "./padWithZero";
2
1
  export declare const generateNumbers: (numberOfItems: number, options: {
3
2
  repeatNTimes?: number;
4
- padWithZero?: boolean;
3
+ padNumbersWithZero?: boolean;
4
+ disableInfiniteScroll?: boolean;
5
+ padWithNItems: number;
6
+ }) => string[];
7
+ export declare const generate12HourNumbers: (options: {
8
+ repeatNTimes?: number;
9
+ padNumbersWithZero?: boolean;
5
10
  disableInfiniteScroll?: boolean;
6
11
  padWithNItems: number;
7
12
  }) => string[];
@@ -0,0 +1,3 @@
1
+ export declare const padNumber: (value: number, options?: {
2
+ padWithZero?: boolean;
3
+ }) => string;
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/troberts-28"
7
7
  },
8
8
  "license": "MIT",
9
- "version": "1.3.0",
9
+ "version": "1.4.0",
10
10
  "main": "dist/commonjs/index.js",
11
11
  "types": "dist/typescript/src/index.d.ts",
12
12
  "scripts": {
@@ -33,7 +33,7 @@ export const Modal = ({
33
33
  modalProps,
34
34
  contentStyle,
35
35
  overlayStyle,
36
- testID,
36
+ testID = "modal",
37
37
  }: ModalProps): React.ReactElement => {
38
38
  const { width: screenWidth, height: screenHeight } = useWindowDimensions();
39
39
 
@@ -109,7 +109,7 @@ export const Modal = ({
109
109
  animationType="fade"
110
110
  visible={isVisible}
111
111
  {...modalProps}
112
- testID={testID ?? "modal"}>
112
+ testID={testID}>
113
113
  <TouchableWithoutFeedback
114
114
  onPress={onOverlayPress}
115
115
  testID="modal-backdrop">
@@ -15,7 +15,10 @@ import {
15
15
  NativeScrollEvent,
16
16
  } from "react-native";
17
17
 
18
- import { generateNumbers } from "../../utils/generateNumbers";
18
+ import {
19
+ generate12HourNumbers,
20
+ generateNumbers,
21
+ } from "../../utils/generateNumbers";
19
22
  import { colorToRgba } from "../../utils/colorToRgba";
20
23
  import { generateStyles } from "./TimerPicker.styles";
21
24
  import { getAdjustedLimit } from "../../utils/getAdjustedLimit";
@@ -53,6 +56,9 @@ interface DurationScrollProps {
53
56
  disableInfiniteScroll?: boolean;
54
57
  limit?: LimitType;
55
58
  aggressivelyGetLatestDuration: boolean;
59
+ is12HourPicker?: boolean;
60
+ amLabel?: string;
61
+ pmLabel?: string;
56
62
  padWithNItems: number;
57
63
  pickerGradientOverlayProps?: Partial<LinearGradientProps>;
58
64
  topPickerGradientOverlayProps?: Partial<LinearGradientProps>;
@@ -77,6 +83,9 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
77
83
  disableInfiniteScroll = false,
78
84
  limit,
79
85
  aggressivelyGetLatestDuration,
86
+ is12HourPicker,
87
+ amLabel,
88
+ pmLabel,
80
89
  padWithNItems,
81
90
  pickerGradientOverlayProps,
82
91
  topPickerGradientOverlayProps,
@@ -87,12 +96,19 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
87
96
  },
88
97
  ref
89
98
  ): React.ReactElement => {
90
- const data = generateNumbers(numberOfItems, {
91
- padWithZero: padNumbersWithZero,
92
- repeatNTimes: 3,
93
- disableInfiniteScroll,
94
- padWithNItems: padWithNItems,
95
- });
99
+ const data = !is12HourPicker
100
+ ? generateNumbers(numberOfItems, {
101
+ padNumbersWithZero,
102
+ repeatNTimes: 3,
103
+ disableInfiniteScroll,
104
+ padWithNItems,
105
+ })
106
+ : generate12HourNumbers({
107
+ padNumbersWithZero,
108
+ repeatNTimes: 3,
109
+ disableInfiniteScroll,
110
+ padWithNItems,
111
+ });
96
112
 
97
113
  const numberOfItemsToShow = 1 + padWithNItems * 2;
98
114
 
@@ -132,7 +148,17 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
132
148
 
133
149
  const renderItem = useCallback(
134
150
  ({ item }: { item: string }) => {
135
- const intItem = parseInt(item);
151
+ let stringItem = item;
152
+ let intItem: number;
153
+ let isAm: boolean | undefined;
154
+
155
+ if (!is12HourPicker) {
156
+ intItem = parseInt(item);
157
+ } else {
158
+ isAm = item.includes("AM");
159
+ stringItem = item.replace(/\s[AP]M/g, "");
160
+ intItem = parseInt(stringItem);
161
+ }
136
162
 
137
163
  return (
138
164
  <View
@@ -147,15 +173,29 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
147
173
  ? styles.disabledPickerItem
148
174
  : {},
149
175
  ]}>
150
- {item}
176
+ {stringItem}
151
177
  </Text>
178
+ {is12HourPicker ? (
179
+ <View
180
+ style={styles.pickerAmPmContainer}
181
+ pointerEvents="none">
182
+ <Text style={[styles.pickerAmPmLabel]}>
183
+ {isAm ? amLabel : pmLabel}
184
+ </Text>
185
+ </View>
186
+ ) : null}
152
187
  </View>
153
188
  );
154
189
  },
155
190
  [
156
191
  adjustedLimited.max,
157
192
  adjustedLimited.min,
193
+ amLabel,
194
+ is12HourPicker,
195
+ pmLabel,
158
196
  styles.disabledPickerItem,
197
+ styles.pickerAmPmContainer,
198
+ styles.pickerAmPmLabel,
159
199
  styles.pickerItem,
160
200
  styles.pickerItemContainer,
161
201
  ]
@@ -317,7 +357,9 @@ const DurationScroll = forwardRef<DurationScrollRef, DurationScrollProps>(
317
357
  : undefined
318
358
  }
319
359
  onMomentumScrollEnd={onMomentumScrollEnd}
320
- onScroll={aggressivelyGetLatestDuration ? onScroll : undefined}
360
+ onScroll={
361
+ aggressivelyGetLatestDuration ? onScroll : undefined
362
+ }
321
363
  testID="duration-scroll-flatlist"
322
364
  />
323
365
  <View style={styles.pickerLabelContainer} pointerEvents="none">
@@ -8,6 +8,8 @@ export interface CustomTimerPickerStyles {
8
8
  pickerContainer?: any;
9
9
  pickerLabelContainer?: any;
10
10
  pickerLabel?: any;
11
+ pickerAmPmContainer?: any;
12
+ pickerAmPmLabel?: any;
11
13
  pickerItemContainer?: any;
12
14
  pickerItem?: any;
13
15
  disabledPickerItem?: any;
@@ -40,12 +42,19 @@ export const generateStyles = (
40
42
  top: 0,
41
43
  bottom: 0,
42
44
  justifyContent: "center",
45
+ minWidth:
46
+ (customStyles?.pickerLabel?.fontSize ??
47
+ customStyles?.text?.fontSize ??
48
+ 25) * 0.65,
43
49
  ...customStyles?.pickerLabelContainer,
44
50
  },
45
51
  pickerLabel: {
46
52
  fontSize: 18,
47
53
  fontWeight: "bold",
48
- marginTop: (customStyles?.pickerItem?.fontSize ?? 25) / 6,
54
+ marginTop:
55
+ (customStyles?.pickerItem?.fontSize ??
56
+ customStyles?.text?.fontSize ??
57
+ 25) / 6,
49
58
  color:
50
59
  customStyles?.theme === "dark"
51
60
  ? DARK_MODE_TEXT_COLOR
@@ -54,6 +63,7 @@ export const generateStyles = (
54
63
  ...customStyles?.pickerLabel,
55
64
  },
56
65
  pickerItemContainer: {
66
+ flexDirection: "row",
57
67
  height: 50,
58
68
  justifyContent: "center",
59
69
  alignItems: "center",
@@ -70,6 +80,27 @@ export const generateStyles = (
70
80
  ...customStyles?.text,
71
81
  ...customStyles?.pickerItem,
72
82
  },
83
+ pickerAmPmContainer: {
84
+ position: "absolute",
85
+ right: 0,
86
+ top: 0,
87
+ bottom: 0,
88
+ justifyContent: "center",
89
+ ...customStyles?.pickerLabelContainer,
90
+ ...customStyles?.pickerAmPmContainer,
91
+ },
92
+ pickerAmPmLabel: {
93
+ fontSize: 18,
94
+ fontWeight: "bold",
95
+ marginTop: (customStyles?.pickerItem?.fontSize ?? 25) / 6,
96
+ color:
97
+ customStyles?.theme === "dark"
98
+ ? DARK_MODE_TEXT_COLOR
99
+ : LIGHT_MODE_TEXT_COLOR,
100
+ ...customStyles?.text,
101
+ ...customStyles?.pickerLabel,
102
+ ...customStyles?.pickerAmPmLabel,
103
+ },
73
104
  disabledPickerItem: {
74
105
  opacity: 0.2,
75
106
  ...customStyles?.disabledPickerItem,
@@ -41,6 +41,9 @@ export interface TimerPickerProps {
41
41
  initialMinutes?: number;
42
42
  initialSeconds?: number;
43
43
  aggressivelyGetLatestDuration?: boolean;
44
+ use12HourPicker?: boolean;
45
+ amLabel?: string;
46
+ pmLabel?: string;
44
47
  hideHours?: boolean;
45
48
  hideMinutes?: boolean;
46
49
  hideSeconds?: boolean;
@@ -74,12 +77,15 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
74
77
  hourLimit,
75
78
  minuteLimit,
76
79
  secondLimit,
77
- hourLabel = "h",
78
- minuteLabel = "m",
79
- secondLabel = "s",
80
+ hourLabel,
81
+ minuteLabel,
82
+ secondLabel,
80
83
  padWithNItems = 1,
81
84
  disableInfiniteScroll = false,
82
85
  aggressivelyGetLatestDuration = false,
86
+ use12HourPicker = false,
87
+ amLabel = "am",
88
+ pmLabel = "pm",
83
89
  LinearGradient,
84
90
  pickerContainerProps,
85
91
  pickerGradientOverlayProps,
@@ -157,9 +163,13 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
157
163
  <DurationScroll
158
164
  ref={hoursDurationScrollRef}
159
165
  numberOfItems={23}
160
- label={hourLabel}
166
+ label={
167
+ hourLabel ?? (!use12HourPicker ? "h" : undefined)
168
+ }
161
169
  initialValue={initialHours}
162
- aggressivelyGetLatestDuration={aggressivelyGetLatestDuration}
170
+ aggressivelyGetLatestDuration={
171
+ aggressivelyGetLatestDuration
172
+ }
163
173
  onDurationChange={setSelectedHours}
164
174
  pickerGradientOverlayProps={pickerGradientOverlayProps}
165
175
  topPickerGradientOverlayProps={
@@ -172,6 +182,9 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
172
182
  padWithNItems={checkedPadWithNItems}
173
183
  limit={hourLimit}
174
184
  LinearGradient={LinearGradient}
185
+ is12HourPicker={use12HourPicker}
186
+ amLabel={amLabel}
187
+ pmLabel={pmLabel}
175
188
  styles={styles}
176
189
  testID="duration-scroll-hour"
177
190
  />
@@ -180,9 +193,11 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
180
193
  <DurationScroll
181
194
  ref={minutesDurationScrollRef}
182
195
  numberOfItems={59}
183
- label={minuteLabel}
196
+ label={minuteLabel ?? "m"}
184
197
  initialValue={initialMinutes}
185
- aggressivelyGetLatestDuration={aggressivelyGetLatestDuration}
198
+ aggressivelyGetLatestDuration={
199
+ aggressivelyGetLatestDuration
200
+ }
186
201
  onDurationChange={setSelectedMinutes}
187
202
  padNumbersWithZero
188
203
  pickerGradientOverlayProps={pickerGradientOverlayProps}
@@ -204,9 +219,11 @@ const TimerPicker = forwardRef<TimerPickerRef, TimerPickerProps>(
204
219
  <DurationScroll
205
220
  ref={secondsDurationScrollRef}
206
221
  numberOfItems={59}
207
- label={secondLabel}
222
+ label={secondLabel ?? "s"}
208
223
  initialValue={initialSeconds}
209
- aggressivelyGetLatestDuration={aggressivelyGetLatestDuration}
224
+ aggressivelyGetLatestDuration={
225
+ aggressivelyGetLatestDuration
226
+ }
210
227
  onDurationChange={setSelectedSeconds}
211
228
  padNumbersWithZero
212
229
  pickerGradientOverlayProps={pickerGradientOverlayProps}
@@ -78,11 +78,14 @@ const TimerPickerModal = forwardRef<TimerPickerModalRef, TimerPickerModalProps>(
78
78
  hourLimit,
79
79
  minuteLimit,
80
80
  secondLimit,
81
- hourLabel = "h",
82
- minuteLabel = "m",
83
- secondLabel = "s",
81
+ hourLabel,
82
+ minuteLabel,
83
+ secondLabel,
84
84
  padWithNItems = 1,
85
85
  disableInfiniteScroll = false,
86
+ use12HourPicker,
87
+ amLabel,
88
+ pmLabel,
86
89
  hideCancelButton = false,
87
90
  confirmButtonText = "Confirm",
88
91
  cancelButtonText = "Cancel",
@@ -216,6 +219,9 @@ const TimerPickerModal = forwardRef<TimerPickerModalRef, TimerPickerModalProps>(
216
219
  secondLabel={secondLabel}
217
220
  padWithNItems={padWithNItems}
218
221
  disableInfiniteScroll={disableInfiniteScroll}
222
+ use12HourPicker={use12HourPicker}
223
+ amLabel={amLabel}
224
+ pmLabel={pmLabel}
219
225
  LinearGradient={LinearGradient}
220
226
  pickerContainerProps={pickerContainerProps}
221
227
  pickerGradientOverlayProps={
@@ -5,7 +5,7 @@ import Modal from "../components/Modal";
5
5
 
6
6
  describe("Modal", () => {
7
7
  it("renders without crashing", () => {
8
- const { getByTestId } = render(<Modal />);
8
+ const { getByTestId } = render(<Modal isVisible/>);
9
9
  const component = getByTestId("modal");
10
10
  expect(component).toBeDefined();
11
11
  });