@forthtilliath/react-native-kit 0.15.0 → 0.16.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.
- package/README.md +102 -0
- package/dist/components/feedback/ErrorFallback.d.ts +63 -0
- package/dist/components/feedback/ErrorFallback.d.ts.map +1 -0
- package/dist/components/feedback/ErrorFallback.js +86 -0
- package/dist/components/feedback/index.d.ts +2 -0
- package/dist/components/feedback/index.d.ts.map +1 -0
- package/dist/components/feedback/index.js +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -0
- package/dist/components/list/AddButton.d.ts +27 -0
- package/dist/components/list/AddButton.d.ts.map +1 -0
- package/dist/components/list/AddButton.js +29 -0
- package/dist/components/list/DragHandle.d.ts +35 -0
- package/dist/components/list/DragHandle.d.ts.map +1 -0
- package/dist/components/list/DragHandle.js +31 -0
- package/dist/components/list/SwipeableRow.d.ts +18 -4
- package/dist/components/list/SwipeableRow.d.ts.map +1 -1
- package/dist/components/list/SwipeableRow.js +40 -13
- package/dist/components/list/index.d.ts +2 -0
- package/dist/components/list/index.d.ts.map +1 -1
- package/dist/components/list/index.js +2 -0
- package/dist/components/overlay/BottomSheet.d.ts +45 -0
- package/dist/components/overlay/BottomSheet.d.ts.map +1 -0
- package/dist/components/overlay/BottomSheet.js +48 -0
- package/dist/components/overlay/index.d.ts +2 -0
- package/dist/components/overlay/index.d.ts.map +1 -0
- package/dist/components/overlay/index.js +1 -0
- package/dist/components/picker/CheckboxGroup.d.ts +47 -0
- package/dist/components/picker/CheckboxGroup.d.ts.map +1 -0
- package/dist/components/picker/CheckboxGroup.js +50 -0
- package/dist/components/picker/MonthDayGrid.d.ts +58 -0
- package/dist/components/picker/MonthDayGrid.d.ts.map +1 -0
- package/dist/components/picker/MonthDayGrid.js +73 -0
- package/dist/components/picker/OptionsModal.d.ts +45 -0
- package/dist/components/picker/OptionsModal.d.ts.map +1 -0
- package/dist/components/picker/OptionsModal.js +45 -0
- package/dist/components/picker/PhotoPicker.d.ts +5 -0
- package/dist/components/picker/PhotoPicker.d.ts.map +1 -1
- package/dist/components/picker/PhotoPicker.js +3 -9
- package/dist/components/picker/QuantityStepper.d.ts +63 -0
- package/dist/components/picker/QuantityStepper.d.ts.map +1 -0
- package/dist/components/picker/QuantityStepper.js +101 -0
- package/dist/components/picker/SegmentedToggle.d.ts +52 -0
- package/dist/components/picker/SegmentedToggle.d.ts.map +1 -0
- package/dist/components/picker/SegmentedToggle.js +48 -0
- package/dist/components/picker/SelectField.d.ts +45 -0
- package/dist/components/picker/SelectField.d.ts.map +1 -0
- package/dist/components/picker/SelectField.js +54 -0
- package/dist/components/picker/index.d.ts +6 -0
- package/dist/components/picker/index.d.ts.map +1 -1
- package/dist/components/picker/index.js +6 -0
- package/dist/components/settings/SettingsCard.d.ts +63 -0
- package/dist/components/settings/SettingsCard.d.ts.map +1 -0
- package/dist/components/settings/SettingsCard.js +68 -0
- package/dist/components/settings/SwitchRow.d.ts +48 -0
- package/dist/components/settings/SwitchRow.d.ts.map +1 -0
- package/dist/components/settings/SwitchRow.js +44 -0
- package/dist/components/settings/index.d.ts +2 -0
- package/dist/components/settings/index.d.ts.map +1 -1
- package/dist/components/settings/index.js +2 -0
- package/dist/components/theme/ThemePreferenceProvider.d.ts +39 -0
- package/dist/components/theme/ThemePreferenceProvider.d.ts.map +1 -0
- package/dist/components/theme/ThemePreferenceProvider.js +53 -0
- package/dist/components/theme/index.d.ts +2 -0
- package/dist/components/theme/index.d.ts.map +1 -1
- package/dist/components/theme/index.js +2 -0
- package/dist/components/theme/themePreferenceContext.d.ts +20 -0
- package/dist/components/theme/themePreferenceContext.d.ts.map +1 -0
- package/dist/components/theme/themePreferenceContext.js +21 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/utils/calendar/index.d.ts +3 -0
- package/dist/utils/calendar/index.d.ts.map +1 -0
- package/dist/utils/calendar/index.js +2 -0
- package/dist/utils/calendar/syncDedicatedCalendar.d.ts +37 -0
- package/dist/utils/calendar/syncDedicatedCalendar.d.ts.map +1 -0
- package/dist/utils/calendar/syncDedicatedCalendar.js +42 -0
- package/dist/utils/calendar/toCalendarEventDetails.d.ts +32 -0
- package/dist/utils/calendar/toCalendarEventDetails.d.ts.map +1 -0
- package/dist/utils/calendar/toCalendarEventDetails.js +47 -0
- package/dist/utils/files/appFiles.d.ts +61 -0
- package/dist/utils/files/appFiles.d.ts.map +1 -0
- package/dist/utils/files/appFiles.js +126 -0
- package/dist/utils/files/imageThumbnail.d.ts +22 -0
- package/dist/utils/files/imageThumbnail.d.ts.map +1 -0
- package/dist/utils/files/imageThumbnail.js +28 -0
- package/dist/utils/files/index.d.ts +3 -0
- package/dist/utils/files/index.d.ts.map +1 -0
- package/dist/utils/files/index.js +2 -0
- package/dist/utils/helpers/haptics.d.ts +9 -0
- package/dist/utils/helpers/haptics.d.ts.map +1 -0
- package/dist/utils/helpers/haptics.js +28 -0
- package/dist/utils/helpers/index.d.ts +5 -0
- package/dist/utils/helpers/index.d.ts.map +1 -1
- package/dist/utils/helpers/index.js +5 -0
- package/dist/utils/helpers/isNativeModuleAvailable.d.ts +12 -0
- package/dist/utils/helpers/isNativeModuleAvailable.d.ts.map +1 -0
- package/dist/utils/helpers/isNativeModuleAvailable.js +15 -0
- package/dist/utils/helpers/shareFile.d.ts +23 -0
- package/dist/utils/helpers/shareFile.d.ts.map +1 -0
- package/dist/utils/helpers/shareFile.js +26 -0
- package/dist/utils/helpers/shareTextFile.d.ts +16 -0
- package/dist/utils/helpers/shareTextFile.d.ts.map +1 -0
- package/dist/utils/helpers/shareTextFile.js +23 -0
- package/dist/utils/helpers/shareViewAsImage.d.ts +21 -0
- package/dist/utils/helpers/shareViewAsImage.d.ts.map +1 -0
- package/dist/utils/helpers/shareViewAsImage.js +32 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/package.json +38 -6
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { StyleProp, ViewStyle } from "react-native";
|
|
3
|
+
/** Per-slot style overrides for {@link BottomSheet}, each merged after its default. */
|
|
4
|
+
export interface BottomSheetStyles {
|
|
5
|
+
/** The dimmed full-screen backdrop; tapping it closes the sheet. */
|
|
6
|
+
overlay?: StyleProp<ViewStyle>;
|
|
7
|
+
/** The sheet itself: background, rounded top corners, `maxHeight`. */
|
|
8
|
+
sheet?: StyleProp<ViewStyle>;
|
|
9
|
+
/** The `ScrollView` holding the children. */
|
|
10
|
+
scroll?: StyleProp<ViewStyle>;
|
|
11
|
+
}
|
|
12
|
+
export interface BottomSheetProps {
|
|
13
|
+
visible: boolean;
|
|
14
|
+
/** Called on a backdrop tap and on Android's back button. */
|
|
15
|
+
onClose: () => void;
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Extra space below the content, typically the bottom safe-area inset
|
|
19
|
+
* (`useSafeAreaInsets().bottom`): with Android edge-to-edge, the modal
|
|
20
|
+
* otherwise slides under the system navigation bar.
|
|
21
|
+
*
|
|
22
|
+
* @defaultValue 0
|
|
23
|
+
*/
|
|
24
|
+
bottomInset?: number;
|
|
25
|
+
/** Per-slot style overrides — see {@link BottomSheetStyles}. */
|
|
26
|
+
styles?: BottomSheetStyles;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A modal panel sliding up from the bottom of the screen, its content
|
|
30
|
+
* scrollable past `maxHeight` — instead of inline content that shifts the
|
|
31
|
+
* layout. Tapping the backdrop or pressing back closes it.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* import { BottomSheet } from "@forthtilliath/react-native-kit/components/overlay/BottomSheet";
|
|
36
|
+
*
|
|
37
|
+
* const { bottom } = useSafeAreaInsets();
|
|
38
|
+
*
|
|
39
|
+
* <BottomSheet visible={open} onClose={() => setOpen(false)} bottomInset={bottom}>
|
|
40
|
+
* <DayDetails day={day} />
|
|
41
|
+
* </BottomSheet>
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function BottomSheet({ visible, onClose, children, bottomInset, styles, }: BottomSheetProps): import("react").JSX.Element;
|
|
45
|
+
//# sourceMappingURL=BottomSheet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../../src/components/overlay/BottomSheet.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKzD,uFAAuF;AACvF,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,sEAAsE;IACtE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AA6BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,OAAO,EACP,QAAQ,EACR,WAAe,EACf,MAAM,GACP,EAAE,gBAAgB,+BAqBlB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Modal, Pressable, ScrollView, View } from "react-native";
|
|
3
|
+
import { mergeSlotStyles } from "../../utils/helpers/mergeSlotStyles.js";
|
|
4
|
+
const defaultStyles = {
|
|
5
|
+
overlay: {
|
|
6
|
+
flex: 1,
|
|
7
|
+
backgroundColor: "rgba(0,0,0,0.5)",
|
|
8
|
+
justifyContent: "flex-end",
|
|
9
|
+
},
|
|
10
|
+
sheet: {
|
|
11
|
+
backgroundColor: "#ffffff",
|
|
12
|
+
borderTopLeftRadius: 16,
|
|
13
|
+
borderTopRightRadius: 16,
|
|
14
|
+
paddingTop: 8,
|
|
15
|
+
paddingBottom: 24,
|
|
16
|
+
maxHeight: "85%",
|
|
17
|
+
},
|
|
18
|
+
// Without flexShrink the ScrollView takes its content's height, ignores the
|
|
19
|
+
// sheet's maxHeight, and the overflow is clipped instead of scrollable.
|
|
20
|
+
scroll: { flexShrink: 1 },
|
|
21
|
+
};
|
|
22
|
+
const backdropFill = {
|
|
23
|
+
position: "absolute",
|
|
24
|
+
top: 0,
|
|
25
|
+
right: 0,
|
|
26
|
+
bottom: 0,
|
|
27
|
+
left: 0,
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* A modal panel sliding up from the bottom of the screen, its content
|
|
31
|
+
* scrollable past `maxHeight` — instead of inline content that shifts the
|
|
32
|
+
* layout. Tapping the backdrop or pressing back closes it.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* import { BottomSheet } from "@forthtilliath/react-native-kit/components/overlay/BottomSheet";
|
|
37
|
+
*
|
|
38
|
+
* const { bottom } = useSafeAreaInsets();
|
|
39
|
+
*
|
|
40
|
+
* <BottomSheet visible={open} onClose={() => setOpen(false)} bottomInset={bottom}>
|
|
41
|
+
* <DayDetails day={day} />
|
|
42
|
+
* </BottomSheet>
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function BottomSheet({ visible, onClose, children, bottomInset = 0, styles, }) {
|
|
46
|
+
const merged = mergeSlotStyles(defaultStyles, styles);
|
|
47
|
+
return (_jsx(Modal, { visible: visible, transparent: true, animationType: "slide", onRequestClose: onClose, children: _jsxs(View, { style: merged.overlay, children: [_jsx(Pressable, { style: backdropFill, onPress: onClose }), _jsxs(View, { style: merged.sheet, children: [_jsx(ScrollView, { style: merged.scroll, children: children }), bottomInset > 0 && _jsx(View, { style: { height: bottomInset } })] })] }) }));
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/overlay/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./BottomSheet.js";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { StyleProp, TextStyle, ViewStyle } from "react-native";
|
|
2
|
+
/** Per-slot style overrides for {@link CheckboxGroup}, each merged after its default. */
|
|
3
|
+
export interface CheckboxGroupStyles {
|
|
4
|
+
/** The wrapping row holding the chips. */
|
|
5
|
+
row?: StyleProp<ViewStyle>;
|
|
6
|
+
/** Every chip. */
|
|
7
|
+
chip?: StyleProp<ViewStyle>;
|
|
8
|
+
/** Added on top of `chip` for the checked ones. */
|
|
9
|
+
chipChecked?: StyleProp<ViewStyle>;
|
|
10
|
+
/** Every chip's label. */
|
|
11
|
+
text?: StyleProp<TextStyle>;
|
|
12
|
+
/** Added on top of `text` for the checked ones. */
|
|
13
|
+
textChecked?: StyleProp<TextStyle>;
|
|
14
|
+
}
|
|
15
|
+
export interface CheckboxGroupOption<T extends string> {
|
|
16
|
+
value: T;
|
|
17
|
+
label: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CheckboxGroupProps<T extends string> {
|
|
20
|
+
options: readonly CheckboxGroupOption<T>[];
|
|
21
|
+
/** The checked values, in the order they were checked. */
|
|
22
|
+
values: readonly T[];
|
|
23
|
+
/** Receives the new list: a tap adds the option at the end, or removes it. */
|
|
24
|
+
onChange: (values: T[]) => void;
|
|
25
|
+
/** What the choice is about, read by screen readers on the group. */
|
|
26
|
+
label?: string;
|
|
27
|
+
/** Per-slot style overrides — see {@link CheckboxGroupStyles}. */
|
|
28
|
+
styles?: CheckboxGroupStyles;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Chips that each check and uncheck independently (extensions, tags, days…),
|
|
32
|
+
* wrapping onto as many lines as needed. Each chip is announced as a checkbox.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* import { CheckboxGroup } from "@forthtilliath/react-native-kit/components/picker/CheckboxGroup";
|
|
37
|
+
*
|
|
38
|
+
* <CheckboxGroup
|
|
39
|
+
* label="Extensions"
|
|
40
|
+
* options={[{ value: "leaders", label: "Leaders" }, { value: "cities", label: "Cités" }]}
|
|
41
|
+
* values={extensions}
|
|
42
|
+
* onChange={setExtensions}
|
|
43
|
+
* />
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function CheckboxGroup<T extends string>({ options, values, onChange, label, styles, }: CheckboxGroupProps<T>): import("react").JSX.Element;
|
|
47
|
+
//# sourceMappingURL=CheckboxGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckboxGroup.d.ts","sourceRoot":"","sources":["../../../src/components/picker/CheckboxGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKpE,yFAAyF;AACzF,MAAM,WAAW,mBAAmB;IAClC,0CAA0C;IAC1C,GAAG,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC3B,kBAAkB;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,mDAAmD;IACnD,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,0BAA0B;IAC1B,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,mDAAmD;IACnD,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM;IACnD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM;IAClD,OAAO,EAAE,SAAS,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,0DAA0D;IAC1D,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAChC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAuBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,EAC9C,OAAO,EACP,MAAM,EACN,QAAQ,EACR,KAAK,EACL,MAAM,GACP,EAAE,kBAAkB,CAAC,CAAC,CAAC,+BA8BvB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Pressable, Text, View } from "react-native";
|
|
3
|
+
import { mergeSlotStyles } from "../../utils/helpers/mergeSlotStyles.js";
|
|
4
|
+
const defaultStyles = {
|
|
5
|
+
row: { flexDirection: "row", flexWrap: "wrap", gap: 8 },
|
|
6
|
+
chip: {
|
|
7
|
+
paddingVertical: 8,
|
|
8
|
+
paddingHorizontal: 12,
|
|
9
|
+
borderRadius: 999,
|
|
10
|
+
borderWidth: 1.5,
|
|
11
|
+
borderColor: "#d4d4d4",
|
|
12
|
+
},
|
|
13
|
+
chipChecked: {
|
|
14
|
+
backgroundColor: "#2563eb",
|
|
15
|
+
borderColor: "#2563eb",
|
|
16
|
+
},
|
|
17
|
+
text: {
|
|
18
|
+
fontSize: 13,
|
|
19
|
+
fontWeight: "600",
|
|
20
|
+
color: "#6b7280",
|
|
21
|
+
},
|
|
22
|
+
textChecked: { color: "#ffffff" },
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Chips that each check and uncheck independently (extensions, tags, days…),
|
|
26
|
+
* wrapping onto as many lines as needed. Each chip is announced as a checkbox.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* import { CheckboxGroup } from "@forthtilliath/react-native-kit/components/picker/CheckboxGroup";
|
|
31
|
+
*
|
|
32
|
+
* <CheckboxGroup
|
|
33
|
+
* label="Extensions"
|
|
34
|
+
* options={[{ value: "leaders", label: "Leaders" }, { value: "cities", label: "Cités" }]}
|
|
35
|
+
* values={extensions}
|
|
36
|
+
* onChange={setExtensions}
|
|
37
|
+
* />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function CheckboxGroup({ options, values, onChange, label, styles, }) {
|
|
41
|
+
const merged = mergeSlotStyles(defaultStyles, styles);
|
|
42
|
+
return (_jsx(View, { style: merged.row, accessibilityLabel: label, children: options.map((option) => {
|
|
43
|
+
const checked = values.includes(option.value);
|
|
44
|
+
return (_jsx(Pressable, { style: [merged.chip, checked && merged.chipChecked], accessibilityRole: "checkbox", accessibilityState: { checked }, accessibilityLabel: option.label, onPress: () => {
|
|
45
|
+
onChange(checked
|
|
46
|
+
? values.filter((v) => v !== option.value)
|
|
47
|
+
: [...values, option.value]);
|
|
48
|
+
}, children: _jsx(Text, { style: [merged.text, checked && merged.textChecked], children: option.label }) }, option.value));
|
|
49
|
+
}) }));
|
|
50
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { StyleProp, TextStyle, ViewStyle } from "react-native";
|
|
2
|
+
import { type KitLocale } from "../../i18n/locale.js";
|
|
3
|
+
/** Per-slot style overrides for {@link MonthDayGrid}, each merged after its default. */
|
|
4
|
+
export interface MonthDayGridStyles {
|
|
5
|
+
/** Wraps the weekday header row and the grid. */
|
|
6
|
+
container?: StyleProp<ViewStyle>;
|
|
7
|
+
/** The weekday header row. */
|
|
8
|
+
weekdayRow?: StyleProp<ViewStyle>;
|
|
9
|
+
/** Each weekday initial. */
|
|
10
|
+
weekdayText?: StyleProp<TextStyle>;
|
|
11
|
+
/** The wrapping grid of days. */
|
|
12
|
+
grid?: StyleProp<ViewStyle>;
|
|
13
|
+
/** One seventh of the width — headers, leading blanks, and days alike. */
|
|
14
|
+
cell?: StyleProp<ViewStyle>;
|
|
15
|
+
/** The round, tappable day. */
|
|
16
|
+
dayBox?: StyleProp<ViewStyle>;
|
|
17
|
+
/** Added on top of `dayBox` for a selected day. */
|
|
18
|
+
dayBoxSelected?: StyleProp<ViewStyle>;
|
|
19
|
+
/** The day number. */
|
|
20
|
+
dayText?: StyleProp<TextStyle>;
|
|
21
|
+
/** Added on top of `dayText` for a selected day. */
|
|
22
|
+
dayTextSelected?: StyleProp<TextStyle>;
|
|
23
|
+
}
|
|
24
|
+
export interface MonthDayGridProps {
|
|
25
|
+
/** The month's days in order, as `YYYY-MM-DD` dates. */
|
|
26
|
+
days: readonly string[];
|
|
27
|
+
/** The selected days, as `YYYY-MM-DD` dates. */
|
|
28
|
+
selected: ReadonlySet<string>;
|
|
29
|
+
/** Called with the tapped day; the host adds it to or removes it from `selected`. */
|
|
30
|
+
onToggle: (day: string) => void;
|
|
31
|
+
/** Seven column headers, Monday first. Defaults to the locale's initials. */
|
|
32
|
+
weekdayLabels?: readonly string[];
|
|
33
|
+
/**
|
|
34
|
+
* Language of the default `weekdayLabels` — French by default, or the
|
|
35
|
+
* nearest `KitLocaleProvider`'s.
|
|
36
|
+
*/
|
|
37
|
+
locale?: KitLocale;
|
|
38
|
+
/** Per-slot style overrides — see {@link MonthDayGridStyles}. */
|
|
39
|
+
styles?: MonthDayGridStyles;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A Monday-first month calendar where days are toggled on and off — public
|
|
43
|
+
* holidays, days off, availability… The first day is offset under its
|
|
44
|
+
* weekday column; the selection itself lives in the host.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* import { MonthDayGrid } from "@forthtilliath/react-native-kit/components/picker/MonthDayGrid";
|
|
49
|
+
*
|
|
50
|
+
* <MonthDayGrid
|
|
51
|
+
* days={daysOfMonth}
|
|
52
|
+
* selected={holidays}
|
|
53
|
+
* onToggle={(day) => setHolidays((prev) => toggleInSet(prev, day))}
|
|
54
|
+
* />
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function MonthDayGrid({ days, selected, onToggle, weekdayLabels, locale, styles, }: MonthDayGridProps): import("react").JSX.Element;
|
|
58
|
+
//# sourceMappingURL=MonthDayGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MonthDayGrid.d.ts","sourceRoot":"","sources":["../../../src/components/picker/MonthDayGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAMpE,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAGpE,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,8BAA8B;IAC9B,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,4BAA4B;IAC5B,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,iCAAiC;IACjC,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,0EAA0E;IAC1E,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,mDAAmD;IACnD,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,sBAAsB;IACtB,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,oDAAoD;IACpD,eAAe,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,iBAAiB;IAChC,wDAAwD;IACxD,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,gDAAgD;IAChD,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9B,qFAAqF;IACrF,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,iEAAiE;IACjE,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAuCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,MAAM,EACN,MAAM,GACP,EAAE,iBAAiB,+BA8CnB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Pressable, Text, View } from "react-native";
|
|
3
|
+
import { mondayFirstWeekday } from "@forthtilliath/ts-kit/date/mondayFirstWeekday";
|
|
4
|
+
import { parseIsoDate } from "@forthtilliath/ts-kit/date/parseIsoDate";
|
|
5
|
+
import { useKitLocale } from "../../i18n/locale.js";
|
|
6
|
+
import { mergeSlotStyles } from "../../utils/helpers/mergeSlotStyles.js";
|
|
7
|
+
const defaultWeekdayLabels = {
|
|
8
|
+
fr: ["L", "M", "M", "J", "V", "S", "D"],
|
|
9
|
+
en: ["M", "T", "W", "T", "F", "S", "S"],
|
|
10
|
+
};
|
|
11
|
+
const defaultStyles = {
|
|
12
|
+
container: {},
|
|
13
|
+
weekdayRow: { flexDirection: "row" },
|
|
14
|
+
weekdayText: {
|
|
15
|
+
fontSize: 11,
|
|
16
|
+
fontWeight: "700",
|
|
17
|
+
opacity: 0.6,
|
|
18
|
+
color: "#111111",
|
|
19
|
+
},
|
|
20
|
+
grid: { flexDirection: "row", flexWrap: "wrap" },
|
|
21
|
+
cell: {
|
|
22
|
+
width: "14.28%",
|
|
23
|
+
alignItems: "center",
|
|
24
|
+
paddingVertical: 2,
|
|
25
|
+
},
|
|
26
|
+
dayBox: {
|
|
27
|
+
width: 32,
|
|
28
|
+
height: 32,
|
|
29
|
+
borderRadius: 16,
|
|
30
|
+
borderWidth: 1,
|
|
31
|
+
borderColor: "#d4d4d4",
|
|
32
|
+
alignItems: "center",
|
|
33
|
+
justifyContent: "center",
|
|
34
|
+
},
|
|
35
|
+
dayBoxSelected: {
|
|
36
|
+
backgroundColor: "#dc2626",
|
|
37
|
+
borderColor: "#dc2626",
|
|
38
|
+
},
|
|
39
|
+
dayText: { fontSize: 12, color: "#111111" },
|
|
40
|
+
dayTextSelected: { color: "#ffffff", fontWeight: "700" },
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* A Monday-first month calendar where days are toggled on and off — public
|
|
44
|
+
* holidays, days off, availability… The first day is offset under its
|
|
45
|
+
* weekday column; the selection itself lives in the host.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* import { MonthDayGrid } from "@forthtilliath/react-native-kit/components/picker/MonthDayGrid";
|
|
50
|
+
*
|
|
51
|
+
* <MonthDayGrid
|
|
52
|
+
* days={daysOfMonth}
|
|
53
|
+
* selected={holidays}
|
|
54
|
+
* onToggle={(day) => setHolidays((prev) => toggleInSet(prev, day))}
|
|
55
|
+
* />
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function MonthDayGrid({ days, selected, onToggle, weekdayLabels, locale, styles, }) {
|
|
59
|
+
const resolvedLocale = useKitLocale(locale);
|
|
60
|
+
const headers = weekdayLabels ?? defaultWeekdayLabels[resolvedLocale];
|
|
61
|
+
const merged = mergeSlotStyles(defaultStyles, styles);
|
|
62
|
+
const firstDay = days[0];
|
|
63
|
+
const leadingBlanks = firstDay ? mondayFirstWeekday(firstDay) : 0;
|
|
64
|
+
return (_jsxs(View, { style: merged.container, children: [_jsx(View, { style: merged.weekdayRow, children: headers.map((header, i) => (
|
|
65
|
+
// Initials repeat (M, M / S, S): the column index is the identity.
|
|
66
|
+
// eslint-disable-next-line @eslint-react/no-array-index-key
|
|
67
|
+
_jsx(View, { style: merged.cell, children: _jsx(Text, { style: merged.weekdayText, children: header }) }, i))) }), _jsxs(View, { style: merged.grid, children: [Array.from({ length: leadingBlanks }, (_, i) => (_jsx(View, { style: merged.cell }, `blank-${String(i)}`))), days.map((day) => {
|
|
68
|
+
const isSelected = selected.has(day);
|
|
69
|
+
return (_jsx(View, { style: merged.cell, children: _jsx(Pressable, { style: [merged.dayBox, isSelected && merged.dayBoxSelected], accessibilityRole: "checkbox", accessibilityState: { checked: isSelected }, onPress: () => {
|
|
70
|
+
onToggle(day);
|
|
71
|
+
}, children: _jsx(Text, { style: [merged.dayText, isSelected && merged.dayTextSelected], children: parseIsoDate(day).getDate() }) }) }, day));
|
|
72
|
+
})] })] }));
|
|
73
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { StyleProp, TextStyle, ViewStyle } from "react-native";
|
|
2
|
+
/** One choice of an {@link OptionsModal} or a `SelectField`. */
|
|
3
|
+
export interface SelectOption<T extends string | number> {
|
|
4
|
+
value: T;
|
|
5
|
+
label: string;
|
|
6
|
+
}
|
|
7
|
+
/** Per-slot style overrides for {@link OptionsModal}, each merged after its default. */
|
|
8
|
+
export interface OptionsModalStyles {
|
|
9
|
+
/** The dimmed full-screen backdrop centering the card; tapping it closes. */
|
|
10
|
+
overlay?: StyleProp<ViewStyle>;
|
|
11
|
+
/** The card holding the scrollable list. */
|
|
12
|
+
card?: StyleProp<ViewStyle>;
|
|
13
|
+
/** Each option row. */
|
|
14
|
+
option?: StyleProp<ViewStyle>;
|
|
15
|
+
/** Each option's label. */
|
|
16
|
+
optionText?: StyleProp<TextStyle>;
|
|
17
|
+
}
|
|
18
|
+
export interface OptionsModalProps<T extends string | number> {
|
|
19
|
+
visible: boolean;
|
|
20
|
+
/** Called on a backdrop tap, on Android's back button, and after a choice. */
|
|
21
|
+
onClose: () => void;
|
|
22
|
+
options: readonly SelectOption<T>[];
|
|
23
|
+
onSelect: (value: T) => void;
|
|
24
|
+
/** Per-slot style overrides — see {@link OptionsModalStyles}. */
|
|
25
|
+
styles?: OptionsModalStyles;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A centered popup listing options in a scrollable card: tapping one selects
|
|
29
|
+
* it and closes the popup. The building block of `SelectField`, usable on
|
|
30
|
+
* its own behind any custom trigger.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* import { OptionsModal } from "@forthtilliath/react-native-kit/components/picker/OptionsModal";
|
|
35
|
+
*
|
|
36
|
+
* <OptionsModal
|
|
37
|
+
* visible={open}
|
|
38
|
+
* onClose={() => setOpen(false)}
|
|
39
|
+
* options={[{ value: "a", label: "Option A" }, { value: "b", label: "Option B" }]}
|
|
40
|
+
* onSelect={setChoice}
|
|
41
|
+
* />
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function OptionsModal<T extends string | number>({ visible, onClose, options, onSelect, styles, }: OptionsModalProps<T>): import("react").JSX.Element;
|
|
45
|
+
//# sourceMappingURL=OptionsModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OptionsModal.d.ts","sourceRoot":"","sources":["../../../src/components/picker/OptionsModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKpE,gEAAgE;AAChE,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACrD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,4CAA4C;IAC5C,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,uBAAuB;IACvB,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,2BAA2B;IAC3B,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,8EAA8E;IAC9E,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,iEAAiE;IACjE,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAqBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,EACtD,OAAO,EACP,OAAO,EACP,OAAO,EACP,QAAQ,EACR,MAAM,GACP,EAAE,iBAAiB,CAAC,CAAC,CAAC,+BA+BtB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Modal, Pressable, ScrollView, Text, View } from "react-native";
|
|
3
|
+
import { mergeSlotStyles } from "../../utils/helpers/mergeSlotStyles.js";
|
|
4
|
+
const defaultStyles = {
|
|
5
|
+
overlay: {
|
|
6
|
+
flex: 1,
|
|
7
|
+
backgroundColor: "rgba(0,0,0,0.5)",
|
|
8
|
+
alignItems: "center",
|
|
9
|
+
justifyContent: "center",
|
|
10
|
+
padding: 24,
|
|
11
|
+
},
|
|
12
|
+
card: {
|
|
13
|
+
width: "100%",
|
|
14
|
+
maxHeight: "70%",
|
|
15
|
+
backgroundColor: "#ffffff",
|
|
16
|
+
borderRadius: 12,
|
|
17
|
+
paddingVertical: 8,
|
|
18
|
+
},
|
|
19
|
+
option: { paddingVertical: 14, paddingHorizontal: 20 },
|
|
20
|
+
optionText: { fontSize: 16, color: "#111111" },
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* A centered popup listing options in a scrollable card: tapping one selects
|
|
24
|
+
* it and closes the popup. The building block of `SelectField`, usable on
|
|
25
|
+
* its own behind any custom trigger.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* import { OptionsModal } from "@forthtilliath/react-native-kit/components/picker/OptionsModal";
|
|
30
|
+
*
|
|
31
|
+
* <OptionsModal
|
|
32
|
+
* visible={open}
|
|
33
|
+
* onClose={() => setOpen(false)}
|
|
34
|
+
* options={[{ value: "a", label: "Option A" }, { value: "b", label: "Option B" }]}
|
|
35
|
+
* onSelect={setChoice}
|
|
36
|
+
* />
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function OptionsModal({ visible, onClose, options, onSelect, styles, }) {
|
|
40
|
+
const merged = mergeSlotStyles(defaultStyles, styles);
|
|
41
|
+
return (_jsx(Modal, { visible: visible, transparent: true, animationType: "fade", onRequestClose: onClose, children: _jsx(Pressable, { style: merged.overlay, onPress: onClose, children: _jsx(View, { style: merged.card, children: _jsx(ScrollView, { children: options.map((option) => (_jsx(Pressable, { style: merged.option, accessibilityRole: "button", onPress: () => {
|
|
42
|
+
onSelect(option.value);
|
|
43
|
+
onClose();
|
|
44
|
+
}, children: _jsx(Text, { style: merged.optionText, children: option.label }) }, option.value))) }) }) }) }));
|
|
45
|
+
}
|
|
@@ -15,7 +15,12 @@ export interface PhotoPickerLabels {
|
|
|
15
15
|
addPlaceholderText?: string;
|
|
16
16
|
cameraPermissionTitle?: string;
|
|
17
17
|
cameraPermissionMessage?: string;
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated Unused: choosing from the library needs no permission (the
|
|
20
|
+
* system photo picker), so no "access denied" alert is ever shown.
|
|
21
|
+
*/
|
|
18
22
|
libraryPermissionTitle?: string;
|
|
23
|
+
/** @deprecated Unused — see `libraryPermissionTitle`. */
|
|
19
24
|
libraryPermissionMessage?: string;
|
|
20
25
|
takePhoto?: string;
|
|
21
26
|
chooseFromLibrary?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhotoPicker.d.ts","sourceRoot":"","sources":["../../../src/components/picker/PhotoPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKhF,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAGpE,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACrC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,oBAAoB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,sBAAsB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACxD,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACvD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"PhotoPicker.d.ts","sourceRoot":"","sources":["../../../src/components/picker/PhotoPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKhF,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAGpE,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACrC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,oBAAoB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,sBAAsB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACxD,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACvD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,yDAAyD;IACzD,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAyED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,+BAqGlB"}
|
|
@@ -41,8 +41,6 @@ const defaultLabels = {
|
|
|
41
41
|
addPlaceholderText: "Ajouter une photo",
|
|
42
42
|
cameraPermissionTitle: "Accès à l'appareil photo refusé",
|
|
43
43
|
cameraPermissionMessage: "Autorise l'accès dans les réglages du téléphone pour prendre une photo.",
|
|
44
|
-
libraryPermissionTitle: "Accès aux photos refusé",
|
|
45
|
-
libraryPermissionMessage: "Autorise l'accès dans les réglages du téléphone pour choisir une photo.",
|
|
46
44
|
takePhoto: "Prendre une photo",
|
|
47
45
|
chooseFromLibrary: "Choisir dans la galerie",
|
|
48
46
|
cancel: "Annuler",
|
|
@@ -55,8 +53,6 @@ const defaultLabels = {
|
|
|
55
53
|
addPlaceholderText: "Add a photo",
|
|
56
54
|
cameraPermissionTitle: "Camera access denied",
|
|
57
55
|
cameraPermissionMessage: "Allow access in the phone's settings to take a photo.",
|
|
58
|
-
libraryPermissionTitle: "Photo access denied",
|
|
59
|
-
libraryPermissionMessage: "Allow access in the phone's settings to choose a photo.",
|
|
60
56
|
takePhoto: "Take a photo",
|
|
61
57
|
chooseFromLibrary: "Choose from library",
|
|
62
58
|
cancel: "Cancel",
|
|
@@ -86,12 +82,10 @@ export function PhotoPicker({ photoUri, onChange, savePhoto, photoLabel, labels,
|
|
|
86
82
|
onChange(await savePhoto(result.assets[0].uri));
|
|
87
83
|
}
|
|
88
84
|
}
|
|
85
|
+
// No permission request: the library is opened through the system photo
|
|
86
|
+
// picker, which needs none — so apps don't have to keep the storage
|
|
87
|
+
// permissions just for this.
|
|
89
88
|
async function pickFromLibrary() {
|
|
90
|
-
const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
|
91
|
-
if (!permission.granted) {
|
|
92
|
-
Alert.alert(t.libraryPermissionTitle, t.libraryPermissionMessage);
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
89
|
const result = await ImagePicker.launchImageLibraryAsync({
|
|
96
90
|
mediaTypes: "images",
|
|
97
91
|
quality: 0.5,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { StyleProp, TextStyle, ViewStyle } from "react-native";
|
|
2
|
+
import { type KitLocale } from "../../i18n/locale.js";
|
|
3
|
+
/** Per-slot style overrides for {@link QuantityStepper}, each merged after its default. */
|
|
4
|
+
export interface QuantityStepperStyles {
|
|
5
|
+
/** The row: − button, field, + button. */
|
|
6
|
+
row?: StyleProp<ViewStyle>;
|
|
7
|
+
/** Both round buttons. */
|
|
8
|
+
button?: StyleProp<ViewStyle>;
|
|
9
|
+
/** Added on top of `button` for "−" at `min` and "+" at `max`. */
|
|
10
|
+
buttonDisabled?: StyleProp<ViewStyle>;
|
|
11
|
+
/** The "−" / "+" glyphs. */
|
|
12
|
+
buttonText?: StyleProp<TextStyle>;
|
|
13
|
+
/** The numeric field in the middle (its text color included). */
|
|
14
|
+
input?: StyleProp<TextStyle>;
|
|
15
|
+
}
|
|
16
|
+
/** Screen-reader labels of the three controls, built from the stepper's `label`. */
|
|
17
|
+
export interface QuantityStepperA11yLabels {
|
|
18
|
+
decrease: (label: string) => string;
|
|
19
|
+
increase: (label: string) => string;
|
|
20
|
+
input: (label: string) => string;
|
|
21
|
+
}
|
|
22
|
+
export interface QuantityStepperProps {
|
|
23
|
+
value: number;
|
|
24
|
+
/** Receives the new value, already clamped to `min…max`. */
|
|
25
|
+
onChange: (value: number) => void;
|
|
26
|
+
/** What is being counted — used in the screen-reader labels. */
|
|
27
|
+
label: string;
|
|
28
|
+
/** @defaultValue 0 */
|
|
29
|
+
min?: number;
|
|
30
|
+
/** @defaultValue 999 */
|
|
31
|
+
max?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Step applied by a long press on −/+, to reach large values quickly.
|
|
34
|
+
* Unset, a long press does nothing more than a tap.
|
|
35
|
+
*/
|
|
36
|
+
longPressStep?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Language of the default screen-reader labels — French by default, or the
|
|
39
|
+
* nearest `KitLocaleProvider`'s.
|
|
40
|
+
*/
|
|
41
|
+
locale?: KitLocale;
|
|
42
|
+
/** Overrides some or all of the screen-reader labels. */
|
|
43
|
+
a11yLabels?: Partial<QuantityStepperA11yLabels>;
|
|
44
|
+
/** Per-slot style overrides — see {@link QuantityStepperStyles}. */
|
|
45
|
+
styles?: QuantityStepperStyles;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A whole-number counter from `min` (0) to `max`: −/+ buttons to adjust
|
|
49
|
+
* (optionally faster on long press), and a numeric field in the middle to
|
|
50
|
+
* type a large number in one go (non-digits are dropped, the result is
|
|
51
|
+
* clamped). A typed value below `min` (an empty field, the "2" of "25" with
|
|
52
|
+
* `min={10}`) stays as typed until the field loses focus.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```tsx
|
|
56
|
+
* import { QuantityStepper } from "@forthtilliath/react-native-kit/components/picker/QuantityStepper";
|
|
57
|
+
*
|
|
58
|
+
* <QuantityStepper value={count} onChange={setCount} label="Croissants" />
|
|
59
|
+
* <QuantityStepper value={bans} onChange={setBans} label="Bannissements" min={1} max={40} longPressStep={5} />
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function QuantityStepper({ value, onChange, label, min, max, longPressStep, locale, a11yLabels, styles, }: QuantityStepperProps): import("react").JSX.Element;
|
|
63
|
+
//# sourceMappingURL=QuantityStepper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuantityStepper.d.ts","sourceRoot":"","sources":["../../../src/components/picker/QuantityStepper.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAGpE,2FAA2F;AAC3F,MAAM,WAAW,qBAAqB;IACpC,0CAA0C;IAC1C,GAAG,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC3B,0BAA0B;IAC1B,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,kEAAkE;IAClE,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,4BAA4B;IAC5B,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,iEAAiE;IACjE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,oFAAoF;AACpF,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,yDAAyD;IACzD,UAAU,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAChD,oEAAoE;IACpE,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AAkDD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,GAAO,EACP,GAAS,EACT,aAAa,EACb,MAAM,EACN,UAAU,EACV,MAAM,GACP,EAAE,oBAAoB,+BAwEtB"}
|