@sincpro/mobile-ui 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -20
- package/dist/Dialog/BottomSheet/BottomSheet.Root.d.ts +13 -9
- package/dist/Dialog/BottomSheet/BottomSheet.Root.js +6 -2
- package/dist/Dialog/Confirmation.context.d.ts +1 -1
- package/dist/Dialog/Dialog.ActionSheet.d.ts +17 -0
- package/dist/Dialog/Dialog.ActionSheet.js +16 -0
- package/dist/Dialog/Dialog.Confirmation.js +5 -1
- package/dist/Dialog/Dialog.EditValue.d.ts +1 -1
- package/dist/Dialog/Dialog.EditValue.js +1 -1
- package/dist/Dialog/Dialog.Sheet.d.ts +26 -0
- package/dist/Dialog/Dialog.Sheet.js +55 -0
- package/dist/Dialog/index.d.ts +9 -7
- package/dist/Dialog/index.js +2 -0
- package/dist/Display/Display.Accordion.d.ts +18 -0
- package/dist/Display/Display.Accordion.js +22 -0
- package/dist/Display/Display.AvatarGroup.d.ts +12 -0
- package/dist/Display/Display.AvatarGroup.js +23 -0
- package/dist/Display/Display.Badge.d.ts +1 -1
- package/dist/Display/Display.Card.d.ts +46 -0
- package/dist/Display/Display.Card.js +36 -0
- package/dist/Display/Display.Carousel.d.ts +13 -0
- package/dist/Display/Display.Carousel.js +19 -0
- package/dist/Display/Display.Chip.d.ts +105 -0
- package/dist/Display/Display.Chip.js +45 -0
- package/dist/Display/Display.CopyableText.d.ts +1 -1
- package/dist/Display/Display.CountRecords.d.ts +1 -1
- package/dist/Display/Display.DataTable.d.ts +19 -0
- package/dist/Display/Display.DataTable.js +22 -0
- package/dist/Display/Display.Date.d.ts +15 -2
- package/dist/Display/Display.Date.js +34 -4
- package/dist/Display/Display.Divider.d.ts +1 -1
- package/dist/Display/Display.GradientSurface.d.ts +116 -0
- package/dist/Display/Display.GradientSurface.js +62 -0
- package/dist/Display/Display.IconBadge.d.ts +13 -0
- package/dist/Display/Display.IconBadge.js +30 -0
- package/dist/Display/Display.Image.d.ts +15 -0
- package/dist/Display/Display.Image.js +17 -0
- package/dist/Display/Display.KeyValue.d.ts +10 -0
- package/dist/Display/Display.KeyValue.js +9 -0
- package/dist/Display/Display.ListItem.d.ts +17 -0
- package/dist/Display/Display.ListItem.js +18 -0
- package/dist/Display/Display.Logo.js +3 -1
- package/dist/Display/Display.MediaCard.d.ts +17 -0
- package/dist/Display/Display.MediaCard.js +12 -0
- package/dist/Display/Display.MediaEmbed.d.ts +19 -0
- package/dist/Display/Display.MediaEmbed.js +39 -0
- package/dist/Display/Display.MenuButton.d.ts +1 -1
- package/dist/Display/Display.Monetary.d.ts +1 -1
- package/dist/Display/Display.Monetary.js +1 -1
- package/dist/Display/Display.Pattern.d.ts +26 -0
- package/dist/Display/Display.Pattern.js +27 -0
- package/dist/Display/Display.PriceTag.d.ts +10 -0
- package/dist/Display/Display.PriceTag.js +23 -0
- package/dist/Display/Display.ProductCard.d.ts +17 -0
- package/dist/Display/Display.ProductCard.js +13 -0
- package/dist/Display/Display.Rating.d.ts +11 -0
- package/dist/Display/Display.Rating.js +16 -0
- package/dist/Display/Display.SearchHistory.d.ts +12 -0
- package/dist/Display/Display.SearchHistory.js +13 -0
- package/dist/Display/Display.SectionHeader.d.ts +13 -0
- package/dist/Display/Display.SectionHeader.js +9 -0
- package/dist/Display/Display.Stat.d.ts +10 -0
- package/dist/Display/Display.Stat.js +9 -0
- package/dist/Display/Display.StatCard.d.ts +14 -0
- package/dist/Display/Display.StatCard.js +13 -0
- package/dist/Display/Display.StatusDot.d.ts +11 -0
- package/dist/Display/Display.StatusDot.js +28 -0
- package/dist/Display/Display.Story.d.ts +15 -0
- package/dist/Display/Display.Story.js +43 -0
- package/dist/Display/Display.StoryTray.d.ts +26 -0
- package/dist/Display/Display.StoryTray.js +43 -0
- package/dist/Display/Display.StoryViewer.d.ts +26 -0
- package/dist/Display/Display.StoryViewer.js +79 -0
- package/dist/Display/Display.SwipeableRow.d.ts +15 -0
- package/dist/Display/Display.SwipeableRow.js +28 -0
- package/dist/Display/Display.Tag.d.ts +11 -0
- package/dist/Display/Display.Tag.js +9 -0
- package/dist/Display/Display.Timeline.d.ts +13 -0
- package/dist/Display/Display.Timeline.js +19 -0
- package/dist/Display/Display.Tooltip.d.ts +10 -0
- package/dist/Display/Display.Tooltip.js +24 -0
- package/dist/Display/index.d.ts +70 -0
- package/dist/Display/index.js +58 -0
- package/dist/Feedback/ErrorBoundary.d.ts +1 -1
- package/dist/Feedback/Feedback.Banner.d.ts +82 -0
- package/dist/Feedback/Feedback.Banner.js +35 -0
- package/dist/Feedback/Feedback.DomainSplashScreen.d.ts +2 -1
- package/dist/Feedback/Feedback.DomainSplashScreen.js +3 -2
- package/dist/Feedback/Feedback.Empty.d.ts +1 -1
- package/dist/Feedback/Feedback.EmptyState.d.ts +15 -0
- package/dist/Feedback/Feedback.EmptyState.js +11 -0
- package/dist/Feedback/Feedback.Error.d.ts +1 -1
- package/dist/Feedback/Feedback.Loading.d.ts +8 -1
- package/dist/Feedback/Feedback.Loading.js +7 -1
- package/dist/Feedback/Feedback.PermissionCard.d.ts +15 -0
- package/dist/Feedback/Feedback.PermissionCard.js +11 -0
- package/dist/Feedback/Feedback.Progress.d.ts +9 -0
- package/dist/Feedback/Feedback.Progress.js +35 -0
- package/dist/Feedback/Feedback.ProgressCircle.d.ts +12 -0
- package/dist/Feedback/Feedback.ProgressCircle.js +15 -0
- package/dist/Feedback/Feedback.Skeleton.d.ts +11 -0
- package/dist/Feedback/Feedback.Skeleton.js +29 -0
- package/dist/Feedback/Feedback.Spinner.js +2 -1
- package/dist/Feedback/Feedback.Splash.d.ts +7 -1
- package/dist/Feedback/Feedback.Splash.js +11 -2
- package/dist/Feedback/Toast.context.d.ts +42 -0
- package/dist/Feedback/Toast.context.js +121 -0
- package/dist/Feedback/index.d.ts +15 -0
- package/dist/Feedback/index.js +15 -0
- package/dist/Form/Form.Button.d.ts +10 -4
- package/dist/Form/Form.Button.js +27 -16
- package/dist/Form/Form.Checkbox.d.ts +1 -1
- package/dist/Form/Form.Checkbox.js +1 -1
- package/dist/Form/Form.ControlledCheckbox.d.ts +1 -1
- package/dist/Form/Form.ControlledInput.d.ts +1 -1
- package/dist/Form/Form.ControlledMonetaryInput.d.ts +1 -1
- package/dist/Form/Form.ControlledRadioButton.d.ts +1 -1
- package/dist/Form/Form.DatePicker.d.ts +20 -0
- package/dist/Form/Form.DatePicker.js +38 -0
- package/dist/Form/Form.Dropdown.d.ts +1 -1
- package/dist/Form/Form.FAB.d.ts +10 -0
- package/dist/Form/Form.FAB.js +17 -0
- package/dist/Form/Form.FilterButton.d.ts +1 -1
- package/dist/Form/Form.FractionalQuantityInput.d.ts +1 -1
- package/dist/Form/Form.IconButton.d.ts +1 -1
- package/dist/Form/Form.Input.d.ts +2 -1
- package/dist/Form/Form.Input.js +1 -1
- package/dist/Form/Form.InputField.js +1 -1
- package/dist/Form/Form.MonetaryInput.d.ts +1 -1
- package/dist/Form/Form.PinInput.d.ts +12 -0
- package/dist/Form/Form.PinInput.js +23 -0
- package/dist/Form/Form.QuantitySelector.d.ts +2 -1
- package/dist/Form/Form.QuantitySelector.js +1 -1
- package/dist/Form/Form.RadioButton.d.ts +1 -1
- package/dist/Form/Form.SearchBar.d.ts +6 -1
- package/dist/Form/Form.SearchBar.js +4 -0
- package/dist/Form/Form.Select.d.ts +17 -0
- package/dist/Form/Form.Select.js +26 -0
- package/dist/Form/Form.Slider.d.ts +20 -0
- package/dist/Form/Form.Slider.js +16 -0
- package/dist/Form/Form.Switch.d.ts +10 -0
- package/dist/Form/Form.Switch.js +9 -0
- package/dist/Form/index.d.ts +12 -0
- package/dist/Form/index.js +12 -0
- package/dist/Navigation/Navigation.AppBar.d.ts +57 -0
- package/dist/Navigation/Navigation.AppBar.js +72 -0
- package/dist/Navigation/Navigation.BottomNav.d.ts +57 -0
- package/dist/Navigation/Navigation.BottomNav.js +108 -0
- package/dist/Navigation/Navigation.CollapsingHeader.d.ts +34 -0
- package/dist/Navigation/Navigation.CollapsingHeader.js +47 -0
- package/dist/Navigation/Navigation.FloatingBar.d.ts +15 -0
- package/dist/Navigation/Navigation.FloatingBar.js +21 -0
- package/dist/Navigation/Navigation.Header.d.ts +6 -2
- package/dist/Navigation/Navigation.Header.js +4 -0
- package/dist/Navigation/Navigation.HeaderToolbar.d.ts +1 -1
- package/dist/Navigation/Navigation.Menu.d.ts +21 -0
- package/dist/Navigation/Navigation.Menu.js +42 -0
- package/dist/Navigation/Navigation.RowItem.d.ts +1 -1
- package/dist/Navigation/Navigation.SearchBar.d.ts +18 -0
- package/dist/Navigation/Navigation.SearchBar.js +28 -0
- package/dist/Navigation/Navigation.SegmentedControl.d.ts +14 -0
- package/dist/Navigation/Navigation.SegmentedControl.js +13 -0
- package/dist/Navigation/Navigation.Steps.d.ts +8 -0
- package/dist/Navigation/Navigation.Steps.js +17 -0
- package/dist/Navigation/Navigation.TabIcon.d.ts +5 -1
- package/dist/Navigation/Navigation.TabIcon.js +4 -0
- package/dist/Navigation/Navigation.TabItem.d.ts +5 -0
- package/dist/Navigation/Navigation.TabItem.js +5 -0
- package/dist/Navigation/Navigation.Tabs.d.ts +28 -0
- package/dist/Navigation/Navigation.Tabs.js +45 -0
- package/dist/Navigation/index.d.ts +32 -1
- package/dist/Navigation/index.js +18 -0
- package/dist/Typography/Typography.Text.d.ts +3 -2
- package/dist/Typography/Typography.Text.js +16 -6
- package/dist/branding.d.ts +6 -0
- package/dist/branding.js +7 -0
- package/dist/icons/ArrowDownIcon.d.ts +2 -1
- package/dist/icons/ArrowUpIcon.d.ts +2 -1
- package/dist/icons/CreditIcon.d.ts +1 -1
- package/dist/icons/OdooIcon.d.ts +6 -1
- package/dist/icons/OdooIcon.js +5 -0
- package/dist/icons/PrinterIcon.d.ts +5 -0
- package/dist/icons/PrinterIcon.js +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/layouts/AuthContainer.d.ts +1 -1
- package/dist/layouts/AuthContainer.js +2 -2
- package/dist/layouts/Container.d.ts +1 -0
- package/dist/layouts/Container.js +2 -3
- package/dist/layouts/GradientContainer.d.ts +1 -1
- package/dist/layouts/PlainLayout.d.ts +1 -1
- package/dist/layouts/ScrollContainer.d.ts +2 -2
- package/dist/layouts/ScrollContainer.js +1 -1
- package/dist/layouts/TabNavigatorLayout.d.ts +2 -2
- package/dist/layouts/TabNavigatorLayout.js +4 -0
- package/dist/primitives/AspectRatio.d.ts +10 -0
- package/dist/primitives/AspectRatio.js +8 -0
- package/dist/primitives/Box.d.ts +1 -1
- package/dist/primitives/Pressable.d.ts +10 -0
- package/dist/primitives/Pressable.js +9 -0
- package/dist/primitives/Row.d.ts +1 -1
- package/dist/primitives/Spacer.d.ts +8 -0
- package/dist/primitives/Spacer.js +9 -0
- package/dist/primitives/Stack.d.ts +1 -1
- package/dist/primitives/index.d.ts +3 -0
- package/dist/primitives/index.js +3 -0
- package/dist/theme/active.d.ts +2 -0
- package/dist/theme/active.js +13 -0
- package/dist/theme/components/ThemedActivityIndicator.d.ts +1 -1
- package/dist/theme/components/index.d.ts +1 -1
- package/dist/theme/components/index.js +1 -1
- package/dist/theme/dark.d.ts +7 -0
- package/dist/theme/dark.js +85 -0
- package/dist/theme/default.js +1 -0
- package/dist/theme/define.d.ts +5 -5
- package/dist/theme/define.js +5 -5
- package/dist/theme/index.d.ts +4 -1
- package/dist/theme/index.js +4 -1
- package/dist/theme/theme.d.ts +1 -1
- package/dist/theme/theme.js +1 -1
- package/dist/theme/types.d.ts +15 -14
- package/dist/theme/types.js +2 -2
- package/dist/theme/typography.d.ts +117 -60
- package/dist/theme/typography.js +115 -29
- package/dist/theme/useTheme.d.ts +3 -1
- package/dist/theme/useTheme.js +6 -1
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.js +2 -0
- package/dist/tokens/motion.d.ts +71 -0
- package/dist/tokens/motion.js +25 -0
- package/dist/utils/date.d.ts +33 -33
- package/dist/utils/date.js +39 -39
- package/dist/utils/timezone.d.ts +5 -0
- package/dist/views/AuthFormView.d.ts +1 -1
- package/dist/views/FormViewV2.context.d.ts +1 -1
- package/dist/views/FormViewV2.d.ts +12 -11
- package/dist/views/FormViewV2.js +8 -4
- package/dist/views/ListViewV2.context.d.ts +6 -2
- package/dist/views/ListViewV2.context.js +3 -1
- package/dist/views/ListViewV2.d.ts +26 -21
- package/dist/views/ListViewV2.js +18 -20
- package/dist/views/Wizard/Wizard.context.d.ts +1 -1
- package/dist/widgets/CircleButton.d.ts +6 -2
- package/dist/widgets/CircleButton.js +4 -0
- package/dist/widgets/GeoPermissionCard.d.ts +6 -1
- package/dist/widgets/GeoPermissionCard.js +8 -3
- package/dist/widgets/HomeHeader.d.ts +4 -0
- package/dist/widgets/HomeHeader.js +4 -0
- package/dist/widgets/JSONViewer.d.ts +2 -1
- package/dist/widgets/JSONViewer.js +9 -12
- package/dist/widgets/MenuCard.d.ts +1 -1
- package/dist/widgets/ScreenHeader.d.ts +5 -1
- package/dist/widgets/ScreenHeader.js +4 -0
- package/dist/widgets/TimeZoneSelector.d.ts +6 -1
- package/dist/widgets/TimeZoneSelector.js +6 -1
- package/dist/widgets/TimeZoneSelectorModal.d.ts +6 -1
- package/dist/widgets/TimeZoneSelectorModal.js +8 -3
- package/package.json +41 -23
- package/tailwind.preset.js +14 -0
- package/dist/notifications/index.d.ts +0 -1
- package/dist/notifications/index.js +0 -1
- package/dist/providers/index.d.ts +0 -1
- package/dist/providers/index.js +0 -2
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface CarouselProps<T> {
|
|
3
|
+
data: T[];
|
|
4
|
+
renderItem: (item: T, index: number) => ReactNode;
|
|
5
|
+
keyExtractor: (item: T, index: number) => string;
|
|
6
|
+
itemWidth: number;
|
|
7
|
+
gap?: number;
|
|
8
|
+
showDots?: boolean;
|
|
9
|
+
className?: string;
|
|
10
|
+
testID?: string;
|
|
11
|
+
}
|
|
12
|
+
declare function Carousel<T>({ data, renderItem, keyExtractor, itemWidth, gap, showDots, className, testID, }: CarouselProps<T>): import("react").JSX.Element;
|
|
13
|
+
export default Carousel;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { theme } from "../theme";
|
|
3
|
+
import { cn } from "../theme/tw";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { ScrollView, View, } from "react-native";
|
|
6
|
+
function Carousel({ data, renderItem, keyExtractor, itemWidth, gap = 12, showDots = true, className, testID, }) {
|
|
7
|
+
const [active, setActive] = useState(0);
|
|
8
|
+
const snap = itemWidth + gap;
|
|
9
|
+
const onScroll = (e) => {
|
|
10
|
+
const index = Math.round(e.nativeEvent.contentOffset.x / snap);
|
|
11
|
+
if (index !== active)
|
|
12
|
+
setActive(index);
|
|
13
|
+
};
|
|
14
|
+
return (_jsxs(View, { className: className, testID: testID, children: [_jsx(ScrollView, { decelerationRate: "fast", horizontal: true, onMomentumScrollEnd: onScroll, showsHorizontalScrollIndicator: false, snapToInterval: snap, children: data.map((item, index) => (_jsx(View, { style: { width: itemWidth, marginRight: index < data.length - 1 ? gap : 0 }, children: renderItem(item, index) }, keyExtractor(item, index)))) }), showDots && data.length > 1 ? (_jsx(View, { className: "flex-row justify-center gap-1.5 mt-3", children: data.map((item, index) => (_jsx(View, { className: cn("h-1.5 rounded-full"), style: {
|
|
15
|
+
width: index === active ? 16 : 6,
|
|
16
|
+
backgroundColor: index === active ? theme.primary : theme.border.strong,
|
|
17
|
+
} }, keyExtractor(item, index)))) })) : null] }));
|
|
18
|
+
}
|
|
19
|
+
export default Carousel;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { type VariantProps } from "../theme/tw";
|
|
2
|
+
declare const chip: import("tailwind-variants").TVReturnType<{
|
|
3
|
+
tone: {
|
|
4
|
+
neutral: {
|
|
5
|
+
root: string;
|
|
6
|
+
label: string;
|
|
7
|
+
};
|
|
8
|
+
primary: {
|
|
9
|
+
root: string;
|
|
10
|
+
label: string;
|
|
11
|
+
};
|
|
12
|
+
success: {
|
|
13
|
+
root: string;
|
|
14
|
+
label: string;
|
|
15
|
+
};
|
|
16
|
+
warning: {
|
|
17
|
+
root: string;
|
|
18
|
+
label: string;
|
|
19
|
+
};
|
|
20
|
+
danger: {
|
|
21
|
+
root: string;
|
|
22
|
+
label: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
selected: {
|
|
26
|
+
true: {
|
|
27
|
+
root: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
}, {
|
|
31
|
+
root: string;
|
|
32
|
+
label: string;
|
|
33
|
+
}, undefined, {
|
|
34
|
+
tone: {
|
|
35
|
+
neutral: {
|
|
36
|
+
root: string;
|
|
37
|
+
label: string;
|
|
38
|
+
};
|
|
39
|
+
primary: {
|
|
40
|
+
root: string;
|
|
41
|
+
label: string;
|
|
42
|
+
};
|
|
43
|
+
success: {
|
|
44
|
+
root: string;
|
|
45
|
+
label: string;
|
|
46
|
+
};
|
|
47
|
+
warning: {
|
|
48
|
+
root: string;
|
|
49
|
+
label: string;
|
|
50
|
+
};
|
|
51
|
+
danger: {
|
|
52
|
+
root: string;
|
|
53
|
+
label: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
selected: {
|
|
57
|
+
true: {
|
|
58
|
+
root: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}, {
|
|
62
|
+
root: string;
|
|
63
|
+
label: string;
|
|
64
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
65
|
+
tone: {
|
|
66
|
+
neutral: {
|
|
67
|
+
root: string;
|
|
68
|
+
label: string;
|
|
69
|
+
};
|
|
70
|
+
primary: {
|
|
71
|
+
root: string;
|
|
72
|
+
label: string;
|
|
73
|
+
};
|
|
74
|
+
success: {
|
|
75
|
+
root: string;
|
|
76
|
+
label: string;
|
|
77
|
+
};
|
|
78
|
+
warning: {
|
|
79
|
+
root: string;
|
|
80
|
+
label: string;
|
|
81
|
+
};
|
|
82
|
+
danger: {
|
|
83
|
+
root: string;
|
|
84
|
+
label: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
selected: {
|
|
88
|
+
true: {
|
|
89
|
+
root: string;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
}, {
|
|
93
|
+
root: string;
|
|
94
|
+
label: string;
|
|
95
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
96
|
+
export interface ChipProps extends VariantProps<typeof chip> {
|
|
97
|
+
label: string;
|
|
98
|
+
onPress?: () => void;
|
|
99
|
+
onRemove?: () => void;
|
|
100
|
+
className?: string;
|
|
101
|
+
testID?: string;
|
|
102
|
+
}
|
|
103
|
+
declare function Chip({ label, tone, selected, onPress, onRemove, className, testID, }: ChipProps): import("react").JSX.Element;
|
|
104
|
+
export default Chip;
|
|
105
|
+
export { Chip };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import Icon from "../Display/Display.Icon";
|
|
3
|
+
import Pressable from "../primitives/Pressable";
|
|
4
|
+
import { theme } from "../theme";
|
|
5
|
+
import { tv } from "../theme/tw";
|
|
6
|
+
import { Text, View } from "react-native";
|
|
7
|
+
const chip = tv({
|
|
8
|
+
slots: {
|
|
9
|
+
root: "flex-row items-center self-start rounded-full px-3 py-1.5 gap-1",
|
|
10
|
+
label: "text-xs font-medium",
|
|
11
|
+
},
|
|
12
|
+
variants: {
|
|
13
|
+
tone: {
|
|
14
|
+
neutral: { root: "bg-bg-muted", label: "text-text-secondary" },
|
|
15
|
+
primary: { root: "bg-bg-accent", label: "text-text-accent" },
|
|
16
|
+
success: { root: "bg-success-light", label: "text-success" },
|
|
17
|
+
warning: { root: "bg-warning-light", label: "text-warning" },
|
|
18
|
+
danger: { root: "bg-danger-light", label: "text-danger" },
|
|
19
|
+
},
|
|
20
|
+
selected: {
|
|
21
|
+
true: { root: "border border-primary" },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
tone: "neutral",
|
|
26
|
+
selected: false,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
const removeIconColor = {
|
|
30
|
+
neutral: theme.text.secondary,
|
|
31
|
+
primary: theme.text.accent,
|
|
32
|
+
success: theme.success,
|
|
33
|
+
warning: theme.warning,
|
|
34
|
+
danger: theme.danger,
|
|
35
|
+
};
|
|
36
|
+
function Chip({ label, tone = "neutral", selected = false, onPress, onRemove, className, testID, }) {
|
|
37
|
+
const styles = chip({ tone, selected });
|
|
38
|
+
const content = (_jsxs(_Fragment, { children: [_jsx(Text, { className: styles.label(), numberOfLines: 1, children: label }), onRemove ? (_jsx(Pressable, { accessibilityLabel: `Quitar ${label}`, hitSlop: 8, onPress: onRemove, children: _jsx(Icon, { color: removeIconColor[tone ?? "neutral"], name: "close", size: 14 }) })) : null] }));
|
|
39
|
+
if (onPress) {
|
|
40
|
+
return (_jsx(Pressable, { accessibilityLabel: label, accessibilityState: { selected }, className: styles.root({ className }), onPress: onPress, testID: testID, children: content }));
|
|
41
|
+
}
|
|
42
|
+
return (_jsx(View, { className: styles.root({ className }), testID: testID, children: content }));
|
|
43
|
+
}
|
|
44
|
+
export default Chip;
|
|
45
|
+
export { Chip };
|
|
@@ -9,5 +9,5 @@ type CopyableTextProps = {
|
|
|
9
9
|
label?: string;
|
|
10
10
|
className?: string;
|
|
11
11
|
};
|
|
12
|
-
declare function CopyableText({ value, getValue, label, className }: CopyableTextProps): import("react
|
|
12
|
+
declare function CopyableText({ value, getValue, label, className }: CopyableTextProps): import("react").JSX.Element;
|
|
13
13
|
export default CopyableText;
|
|
@@ -4,5 +4,5 @@ interface IProps {
|
|
|
4
4
|
withPadding?: boolean;
|
|
5
5
|
className?: string;
|
|
6
6
|
}
|
|
7
|
-
declare function CountRecords({ name, count, withPadding, className }: IProps): import("react
|
|
7
|
+
declare function CountRecords({ name, count, withPadding, className }: IProps): import("react").JSX.Element;
|
|
8
8
|
export default CountRecords;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface DataTableColumn<T> {
|
|
3
|
+
key: string;
|
|
4
|
+
header: string;
|
|
5
|
+
align?: "left" | "right" | "center";
|
|
6
|
+
flex?: number;
|
|
7
|
+
render?: (row: T) => ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export interface DataTableProps<T> {
|
|
10
|
+
columns: DataTableColumn<T>[];
|
|
11
|
+
data: T[];
|
|
12
|
+
keyExtractor: (row: T, index: number) => string;
|
|
13
|
+
footer?: ReactNode;
|
|
14
|
+
emptyText?: string;
|
|
15
|
+
className?: string;
|
|
16
|
+
testID?: string;
|
|
17
|
+
}
|
|
18
|
+
declare function DataTable<T>({ columns, data, keyExtractor, footer, emptyText, className, testID, }: DataTableProps<T>): import("react").JSX.Element;
|
|
19
|
+
export default DataTable;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { cn } from "../theme/tw";
|
|
3
|
+
import { Typography } from "../Typography";
|
|
4
|
+
import { ScrollView, View } from "react-native";
|
|
5
|
+
const alignClass = {
|
|
6
|
+
left: "text-left",
|
|
7
|
+
right: "text-right",
|
|
8
|
+
center: "text-center",
|
|
9
|
+
};
|
|
10
|
+
function cellValue(col, row) {
|
|
11
|
+
if (col.render)
|
|
12
|
+
return col.render(row);
|
|
13
|
+
const raw = row[col.key];
|
|
14
|
+
return raw == null ? "" : String(raw);
|
|
15
|
+
}
|
|
16
|
+
function DataTable({ columns, data, keyExtractor, footer, emptyText = "Sin datos", className, testID, }) {
|
|
17
|
+
return (_jsxs(View, { className: cn("bg-bg-card rounded-lg border border-border-light overflow-hidden", className), testID: testID, children: [_jsx(View, { className: "flex-row bg-bg-muted px-3 py-2.5", children: columns.map((col) => (_jsx(View, { style: { flex: col.flex ?? 1 }, children: _jsx(Typography.Text, { className: cn("text-text-secondary font-semibold", alignClass[col.align ?? "left"]), numberOfLines: 1, variant: "caption", children: col.header }) }, col.key))) }), data.length === 0 ? (_jsx(View, { className: "px-3 py-6 items-center", children: _jsx(Typography.Text, { className: "text-text-tertiary", variant: "bodySmall", children: emptyText }) })) : (_jsx(ScrollView, { children: data.map((row, index) => (_jsx(View, { className: "flex-row px-3 py-3 border-t border-border-light", children: columns.map((col) => {
|
|
18
|
+
const content = cellValue(col, row);
|
|
19
|
+
return (_jsx(View, { style: { flex: col.flex ?? 1 }, children: typeof content === "string" || typeof content === "number" ? (_jsx(Typography.Text, { className: cn("text-text-primary", alignClass[col.align ?? "left"]), variant: "bodySmall", children: content })) : (content) }, col.key));
|
|
20
|
+
}) }, keyExtractor(row, index)))) })), footer ? (_jsx(View, { className: "flex-row px-3 py-3 border-t border-border-default bg-bg-muted", children: footer })) : null] }));
|
|
21
|
+
}
|
|
22
|
+
export default DataTable;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { typographyVariants } from "../theme/typography";
|
|
2
|
-
import type
|
|
2
|
+
import { type StyleProp, type TextStyle } from "react-native";
|
|
3
3
|
type DateFormat = "short" | "long" | "numeric";
|
|
4
|
+
/**
|
|
5
|
+
* Visual layout:
|
|
6
|
+
* - `inline` (default): plain text, backward-compatible with previous usage.
|
|
7
|
+
* - `withIcon`: leading calendar/clock icon + text — the app-like default.
|
|
8
|
+
* - `pill`: tokenized rounded chip with icon (compact metadata).
|
|
9
|
+
*/
|
|
10
|
+
type DateVariant = "inline" | "withIcon" | "pill";
|
|
4
11
|
interface DateFieldProps {
|
|
5
12
|
value: string | Date | null | undefined;
|
|
6
13
|
format?: DateFormat;
|
|
@@ -13,6 +20,12 @@ interface DateFieldProps {
|
|
|
13
20
|
className?: string;
|
|
14
21
|
showTime?: boolean;
|
|
15
22
|
timezone?: string;
|
|
23
|
+
/** App-like layout. Default `inline` (no visual change vs. previous version). */
|
|
24
|
+
variant?: DateVariant;
|
|
25
|
+
/** Override the leading icon (ionicons). Defaults: calendar, or clock if `showTime`. */
|
|
26
|
+
icon?: string;
|
|
27
|
+
/** Show relative time ("hace 2 h") instead of the absolute date. */
|
|
28
|
+
relative?: boolean;
|
|
16
29
|
}
|
|
17
|
-
declare function DateField({ value, format, prefix, textVariant, color, style, semibold, bold, className, showTime, timezone, }: DateFieldProps): import("react
|
|
30
|
+
declare function DateField({ value, format, prefix, textVariant, color, style, semibold, bold, className, showTime, timezone, variant, icon, relative, }: DateFieldProps): import("react").JSX.Element;
|
|
18
31
|
export default DateField;
|
|
@@ -1,13 +1,43 @@
|
|
|
1
|
-
import { jsx as _jsx } from "nativewind/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import Icon from "../Display/Display.Icon";
|
|
3
|
+
import { theme } from "../theme";
|
|
4
|
+
import { cn } from "../theme/tw";
|
|
2
5
|
import { Typography } from "../Typography";
|
|
3
6
|
import { formatDate, formatDateWithDefaultTimezone } from "../utils/date";
|
|
4
|
-
|
|
7
|
+
import { View } from "react-native";
|
|
8
|
+
function relativeTime(value) {
|
|
9
|
+
const then = new Date(value).getTime();
|
|
10
|
+
const diffSec = Math.round((Date.now() - then) / 1000);
|
|
11
|
+
const abs = Math.abs(diffSec);
|
|
12
|
+
const fut = diffSec < 0;
|
|
13
|
+
const fmt = (n, unit) => (fut ? `en ${n} ${unit}` : `hace ${n} ${unit}`);
|
|
14
|
+
if (abs < 60)
|
|
15
|
+
return "ahora";
|
|
16
|
+
if (abs < 3600)
|
|
17
|
+
return fmt(Math.floor(abs / 60), "min");
|
|
18
|
+
if (abs < 86400)
|
|
19
|
+
return fmt(Math.floor(abs / 3600), "h");
|
|
20
|
+
if (abs < 604800)
|
|
21
|
+
return fmt(Math.floor(abs / 86400), "d");
|
|
22
|
+
return fmt(Math.floor(abs / 604800), "sem");
|
|
23
|
+
}
|
|
24
|
+
function DateField({ value, format = "short", prefix = "", textVariant = "body", color, style = {}, semibold = false, bold = false, className, showTime = true, timezone, variant = "inline", icon, relative = false, }) {
|
|
5
25
|
const locale = "es-CR";
|
|
6
|
-
const
|
|
26
|
+
const absolute = !value
|
|
7
27
|
? "-"
|
|
8
28
|
: timezone
|
|
9
29
|
? formatDate(value, timezone, { showTime, locale })
|
|
10
30
|
: formatDateWithDefaultTimezone(value, { showTime, locale });
|
|
11
|
-
|
|
31
|
+
const formatted = value && relative ? relativeTime(value) : absolute;
|
|
32
|
+
const text = prefix ? `${prefix}${formatted}` : formatted;
|
|
33
|
+
const iconName = icon ?? (showTime && !relative ? "time-outline" : "calendar-outline");
|
|
34
|
+
const label = (_jsx(Typography.Text, { bold: bold, color: color, semibold: semibold && !bold, style: style, variant: textVariant, children: text }));
|
|
35
|
+
if (variant === "inline") {
|
|
36
|
+
return (_jsx(Typography.Text, { bold: bold, className: className, color: color, semibold: semibold && !bold, style: style, variant: textVariant, children: text }));
|
|
37
|
+
}
|
|
38
|
+
if (variant === "pill") {
|
|
39
|
+
return (_jsxs(View, { className: cn("flex-row items-center self-start gap-1.5 rounded-full bg-bg-muted px-2.5 py-1", className), children: [_jsx(Icon, { color: color ?? theme.icon.secondary, name: iconName, size: 14 }), label] }));
|
|
40
|
+
}
|
|
41
|
+
return (_jsxs(View, { className: cn("flex-row items-center gap-1.5", className), children: [_jsx(Icon, { color: color ?? theme.icon.secondary, name: iconName, size: 16 }), label] }));
|
|
12
42
|
}
|
|
13
43
|
export default DateField;
|
|
@@ -40,5 +40,5 @@ interface DividerProps extends VariantProps<typeof divider> {
|
|
|
40
40
|
thickness?: number;
|
|
41
41
|
className?: string;
|
|
42
42
|
}
|
|
43
|
-
declare function Divider({ thickness, spacing, colorScheme, className }: DividerProps): import("react
|
|
43
|
+
declare function Divider({ thickness, spacing, colorScheme, className }: DividerProps): import("react").JSX.Element;
|
|
44
44
|
export default Divider;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { type VariantProps } from "../theme/tw";
|
|
2
|
+
import { type LinearGradientPoint } from "expo-linear-gradient";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import { type ViewStyle } from "react-native";
|
|
5
|
+
/**
|
|
6
|
+
* Decorative gradient presets (2026 art direction). `brand` is themeable (reads
|
|
7
|
+
* `theme.gradient.primary`); the rest are intentional design constants for heroes/splash.
|
|
8
|
+
* Each is [from, …, to].
|
|
9
|
+
*/
|
|
10
|
+
declare const GRADIENT_PRESETS: {
|
|
11
|
+
readonly "neon-teal": {
|
|
12
|
+
readonly colors: readonly ["#22E584", "#0FB8A0"];
|
|
13
|
+
readonly start: {
|
|
14
|
+
readonly x: 0;
|
|
15
|
+
readonly y: 0;
|
|
16
|
+
};
|
|
17
|
+
readonly end: {
|
|
18
|
+
readonly x: 1;
|
|
19
|
+
readonly y: 1;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
readonly "night-green": {
|
|
23
|
+
readonly colors: readonly ["#0B1410", "#0E2A1E", "#08120D"];
|
|
24
|
+
readonly start: {
|
|
25
|
+
readonly x: 0;
|
|
26
|
+
readonly y: 0;
|
|
27
|
+
};
|
|
28
|
+
readonly end: {
|
|
29
|
+
readonly x: 1;
|
|
30
|
+
readonly y: 1;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
readonly mesh: {
|
|
34
|
+
readonly colors: readonly ["#0B1410", "#10B981", "#0B1410", "#1E1B8A"];
|
|
35
|
+
readonly start: {
|
|
36
|
+
readonly x: 0;
|
|
37
|
+
readonly y: 0;
|
|
38
|
+
};
|
|
39
|
+
readonly end: {
|
|
40
|
+
readonly x: 1;
|
|
41
|
+
readonly y: 1;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
readonly emerald: {
|
|
45
|
+
readonly colors: readonly ["#00C357", "#00A862"];
|
|
46
|
+
readonly start: {
|
|
47
|
+
readonly x: 0;
|
|
48
|
+
readonly y: 0;
|
|
49
|
+
};
|
|
50
|
+
readonly end: {
|
|
51
|
+
readonly x: 1;
|
|
52
|
+
readonly y: 1;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export type GradientPreset = keyof typeof GRADIENT_PRESETS | "brand";
|
|
57
|
+
declare const surface: import("tailwind-variants").TVReturnType<{
|
|
58
|
+
radius: {
|
|
59
|
+
none: string;
|
|
60
|
+
md: string;
|
|
61
|
+
lg: string;
|
|
62
|
+
full: string;
|
|
63
|
+
};
|
|
64
|
+
padding: {
|
|
65
|
+
none: string;
|
|
66
|
+
sm: string;
|
|
67
|
+
md: string;
|
|
68
|
+
lg: string;
|
|
69
|
+
};
|
|
70
|
+
}, undefined, undefined, {
|
|
71
|
+
radius: {
|
|
72
|
+
none: string;
|
|
73
|
+
md: string;
|
|
74
|
+
lg: string;
|
|
75
|
+
full: string;
|
|
76
|
+
};
|
|
77
|
+
padding: {
|
|
78
|
+
none: string;
|
|
79
|
+
sm: string;
|
|
80
|
+
md: string;
|
|
81
|
+
lg: string;
|
|
82
|
+
};
|
|
83
|
+
}, undefined, import("tailwind-variants").TVReturnType<{
|
|
84
|
+
radius: {
|
|
85
|
+
none: string;
|
|
86
|
+
md: string;
|
|
87
|
+
lg: string;
|
|
88
|
+
full: string;
|
|
89
|
+
};
|
|
90
|
+
padding: {
|
|
91
|
+
none: string;
|
|
92
|
+
sm: string;
|
|
93
|
+
md: string;
|
|
94
|
+
lg: string;
|
|
95
|
+
};
|
|
96
|
+
}, undefined, undefined, unknown, unknown, undefined>>;
|
|
97
|
+
export interface GradientSurfaceProps extends VariantProps<typeof surface> {
|
|
98
|
+
/** Named brand preset. Ignored if `colors` is provided. */
|
|
99
|
+
preset?: GradientPreset;
|
|
100
|
+
/** Custom gradient stops (overrides `preset`). */
|
|
101
|
+
colors?: readonly [string, string, ...string[]];
|
|
102
|
+
start?: LinearGradientPoint;
|
|
103
|
+
end?: LinearGradientPoint;
|
|
104
|
+
children?: ReactNode;
|
|
105
|
+
className?: string;
|
|
106
|
+
style?: ViewStyle;
|
|
107
|
+
testID?: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Modern gradient surface (delivery/fintech 2026 look). Wraps `expo-linear-gradient` with
|
|
111
|
+
* named brand presets + tokenized radius/padding. iOS + Android (no native dep beyond the
|
|
112
|
+
* already-peer `expo-linear-gradient`). Replaces the legacy `GradientContainer`.
|
|
113
|
+
*/
|
|
114
|
+
declare function GradientSurface({ preset, colors, start, end, radius, padding, children, className, style, testID, }: GradientSurfaceProps): import("react").JSX.Element;
|
|
115
|
+
export default GradientSurface;
|
|
116
|
+
export { GRADIENT_PRESETS, GradientSurface };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { theme } from "../theme";
|
|
3
|
+
import { cn, tv } from "../theme/tw";
|
|
4
|
+
import { LinearGradient } from "expo-linear-gradient";
|
|
5
|
+
import { View } from "react-native";
|
|
6
|
+
/**
|
|
7
|
+
* Decorative gradient presets (2026 art direction). `brand` is themeable (reads
|
|
8
|
+
* `theme.gradient.primary`); the rest are intentional design constants for heroes/splash.
|
|
9
|
+
* Each is [from, …, to].
|
|
10
|
+
*/
|
|
11
|
+
const GRADIENT_PRESETS = {
|
|
12
|
+
"neon-teal": {
|
|
13
|
+
colors: ["#22E584", "#0FB8A0"],
|
|
14
|
+
start: { x: 0, y: 0 },
|
|
15
|
+
end: { x: 1, y: 1 },
|
|
16
|
+
},
|
|
17
|
+
"night-green": {
|
|
18
|
+
colors: ["#0B1410", "#0E2A1E", "#08120D"],
|
|
19
|
+
start: { x: 0, y: 0 },
|
|
20
|
+
end: { x: 1, y: 1 },
|
|
21
|
+
},
|
|
22
|
+
mesh: {
|
|
23
|
+
colors: ["#0B1410", "#10B981", "#0B1410", "#1E1B8A"],
|
|
24
|
+
start: { x: 0, y: 0 },
|
|
25
|
+
end: { x: 1, y: 1 },
|
|
26
|
+
},
|
|
27
|
+
emerald: {
|
|
28
|
+
colors: ["#00C357", "#00A862"],
|
|
29
|
+
start: { x: 0, y: 0 },
|
|
30
|
+
end: { x: 1, y: 1 },
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
const surface = tv({
|
|
34
|
+
variants: {
|
|
35
|
+
radius: {
|
|
36
|
+
none: "rounded-none",
|
|
37
|
+
md: "rounded-xl",
|
|
38
|
+
lg: "rounded-2xl",
|
|
39
|
+
full: "rounded-full",
|
|
40
|
+
},
|
|
41
|
+
padding: {
|
|
42
|
+
none: "p-0",
|
|
43
|
+
sm: "p-3",
|
|
44
|
+
md: "p-4",
|
|
45
|
+
lg: "p-6",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
defaultVariants: { radius: "lg", padding: "none" },
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* Modern gradient surface (delivery/fintech 2026 look). Wraps `expo-linear-gradient` with
|
|
52
|
+
* named brand presets + tokenized radius/padding. iOS + Android (no native dep beyond the
|
|
53
|
+
* already-peer `expo-linear-gradient`). Replaces the legacy `GradientContainer`.
|
|
54
|
+
*/
|
|
55
|
+
function GradientSurface({ preset = "neon-teal", colors, start, end, radius, padding, children, className, style, testID, }) {
|
|
56
|
+
const p = preset === "brand" ? GRADIENT_PRESETS["neon-teal"] : GRADIENT_PRESETS[preset];
|
|
57
|
+
const presetColors = preset === "brand" ? theme.gradient.primary : p.colors;
|
|
58
|
+
const resolvedColors = (colors ?? presetColors);
|
|
59
|
+
return (_jsxs(View, { className: cn("overflow-hidden", surface({ radius })), style: style, testID: testID, children: [_jsx(LinearGradient, { colors: [...resolvedColors], end: end ?? p.end, start: start ?? p.start, style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0 } }), _jsx(View, { className: cn(surface({ padding }), className), children: children })] }));
|
|
60
|
+
}
|
|
61
|
+
export default GradientSurface;
|
|
62
|
+
export { GRADIENT_PRESETS, GradientSurface };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface IconBadgeProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
count?: number;
|
|
5
|
+
max?: number;
|
|
6
|
+
dot?: boolean;
|
|
7
|
+
color?: string;
|
|
8
|
+
onPress?: () => void;
|
|
9
|
+
accessibilityLabel?: string;
|
|
10
|
+
testID?: string;
|
|
11
|
+
}
|
|
12
|
+
declare function IconBadge({ children, count, max, dot, color, onPress, accessibilityLabel, testID, }: IconBadgeProps): import("react").JSX.Element;
|
|
13
|
+
export default IconBadge;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import Pressable from "../primitives/Pressable";
|
|
3
|
+
import { theme } from "../theme";
|
|
4
|
+
import { Typography } from "../Typography";
|
|
5
|
+
import { View } from "react-native";
|
|
6
|
+
function IconBadge({ children, count, max = 99, dot = false, color, onPress, accessibilityLabel, testID, }) {
|
|
7
|
+
const showCount = typeof count === "number" && count > 0;
|
|
8
|
+
const showBadge = dot || showCount;
|
|
9
|
+
const label = showCount ? (count > max ? `${max}+` : String(count)) : "";
|
|
10
|
+
const badgeColor = color ?? theme.danger;
|
|
11
|
+
const content = (_jsxs(View, { style: { position: "relative" }, children: [children, showBadge ? (_jsx(View, { style: {
|
|
12
|
+
position: "absolute",
|
|
13
|
+
top: -4,
|
|
14
|
+
right: -6,
|
|
15
|
+
minWidth: dot ? 10 : 18,
|
|
16
|
+
height: dot ? 10 : 18,
|
|
17
|
+
borderRadius: 999,
|
|
18
|
+
paddingHorizontal: dot ? 0 : 4,
|
|
19
|
+
backgroundColor: badgeColor,
|
|
20
|
+
alignItems: "center",
|
|
21
|
+
justifyContent: "center",
|
|
22
|
+
borderWidth: 2,
|
|
23
|
+
borderColor: theme.bg.card,
|
|
24
|
+
}, children: !dot && label ? (_jsx(Typography.Text, { style: { color: theme.text.inverse, fontSize: 10, lineHeight: 12 }, children: label })) : null })) : null] }));
|
|
25
|
+
if (onPress) {
|
|
26
|
+
return (_jsx(Pressable, { accessibilityLabel: accessibilityLabel, hitSlop: 10, onPress: onPress, testID: testID, children: content }));
|
|
27
|
+
}
|
|
28
|
+
return (_jsx(View, { accessibilityLabel: accessibilityLabel, testID: testID, children: content }));
|
|
29
|
+
}
|
|
30
|
+
export default IconBadge;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ImageResizeMode, type ImageSourcePropType, type ImageStyle } from "react-native";
|
|
2
|
+
export interface DisplayImageProps {
|
|
3
|
+
source: ImageSourcePropType;
|
|
4
|
+
width?: number | `${number}%`;
|
|
5
|
+
height?: number;
|
|
6
|
+
aspectRatio?: number;
|
|
7
|
+
radius?: number;
|
|
8
|
+
resizeMode?: ImageResizeMode;
|
|
9
|
+
fallbackIcon?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
style?: ImageStyle;
|
|
12
|
+
testID?: string;
|
|
13
|
+
}
|
|
14
|
+
declare function DisplayImage({ source, width, height, aspectRatio, radius, resizeMode, fallbackIcon, className, style, testID, }: DisplayImageProps): import("react").JSX.Element;
|
|
15
|
+
export default DisplayImage;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import Icon from "../Display/Display.Icon";
|
|
3
|
+
import Skeleton from "../Feedback/Feedback.Skeleton";
|
|
4
|
+
import { theme } from "../theme";
|
|
5
|
+
import { cn } from "../theme/tw";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { Image, View, } from "react-native";
|
|
8
|
+
function DisplayImage({ source, width = "100%", height, aspectRatio, radius = 12, resizeMode = "cover", fallbackIcon = "image-outline", className, style, testID, }) {
|
|
9
|
+
const [loading, setLoading] = useState(true);
|
|
10
|
+
const [failed, setFailed] = useState(false);
|
|
11
|
+
const dimensions = { width, height, aspectRatio, borderRadius: radius };
|
|
12
|
+
return (_jsx(View, { className: cn("overflow-hidden bg-bg-muted", className), style: dimensions, testID: testID, children: failed ? (_jsx(View, { className: "flex-1 items-center justify-center", children: _jsx(Icon, { color: theme.icon.disabled, name: fallbackIcon, size: 32 }) })) : (_jsxs(_Fragment, { children: [_jsx(Image, { onError: () => {
|
|
13
|
+
setFailed(true);
|
|
14
|
+
setLoading(false);
|
|
15
|
+
}, onLoadEnd: () => setLoading(false), resizeMode: resizeMode, source: source, style: [{ width: "100%", height: "100%" }, style] }), loading ? (_jsx(View, { style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0 }, children: _jsx(Skeleton, { height: "100%", radius: radius, width: "100%" }) })) : null] })) }));
|
|
16
|
+
}
|
|
17
|
+
export default DisplayImage;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface KeyValueProps {
|
|
3
|
+
label: string;
|
|
4
|
+
value?: ReactNode;
|
|
5
|
+
align?: "row" | "stacked";
|
|
6
|
+
className?: string;
|
|
7
|
+
testID?: string;
|
|
8
|
+
}
|
|
9
|
+
declare function KeyValue({ label, value, align, className, testID }: KeyValueProps): import("react").JSX.Element;
|
|
10
|
+
export default KeyValue;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { cn } from "../theme/tw";
|
|
3
|
+
import { Typography } from "../Typography";
|
|
4
|
+
import { View } from "react-native";
|
|
5
|
+
function KeyValue({ label, value, align = "row", className, testID }) {
|
|
6
|
+
const isRow = align === "row";
|
|
7
|
+
return (_jsxs(View, { className: cn(isRow ? "flex-row items-center justify-between gap-3" : "gap-0.5", "py-2", className), testID: testID, children: [_jsx(Typography.Text, { className: "text-text-secondary", variant: "caption", children: label }), typeof value === "string" || typeof value === "number" ? (_jsx(Typography.Text, { className: cn("text-text-primary", isRow && "text-right"), semibold: isRow, children: value })) : (value)] }));
|
|
8
|
+
}
|
|
9
|
+
export default KeyValue;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface ListItemProps {
|
|
3
|
+
title: string;
|
|
4
|
+
subtitle?: string;
|
|
5
|
+
/** Leading slot — icon, avatar, status dot. */
|
|
6
|
+
leading?: ReactNode;
|
|
7
|
+
/** Trailing slot — value text, toggle, badge. Overrides the auto `chevron`. */
|
|
8
|
+
trailing?: ReactNode;
|
|
9
|
+
/** Show a forward chevron on the right (navigational row). Ignored if `trailing` is set. */
|
|
10
|
+
chevron?: boolean;
|
|
11
|
+
onPress?: () => void;
|
|
12
|
+
showDivider?: boolean;
|
|
13
|
+
className?: string;
|
|
14
|
+
testID?: string;
|
|
15
|
+
}
|
|
16
|
+
declare function ListItem({ title, subtitle, leading, trailing, chevron, onPress, showDivider, className, testID, }: ListItemProps): import("react").JSX.Element;
|
|
17
|
+
export default ListItem;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
|
|
2
|
+
import Icon from "../Display/Display.Icon";
|
|
3
|
+
import Pressable from "../primitives/Pressable";
|
|
4
|
+
import { theme } from "../theme";
|
|
5
|
+
import { cn } from "../theme/tw";
|
|
6
|
+
import { Typography } from "../Typography";
|
|
7
|
+
import { View } from "react-native";
|
|
8
|
+
function ListItem({ title, subtitle, leading, trailing, chevron = false, onPress, showDivider = true, className, testID, }) {
|
|
9
|
+
const right = trailing ??
|
|
10
|
+
(chevron ? _jsx(Icon, { color: theme.icon.tertiary, name: "chevron-forward", size: 18 }) : null);
|
|
11
|
+
const content = (_jsxs(_Fragment, { children: [leading ? _jsx(View, { className: "mr-3 justify-center", children: leading }) : null, _jsxs(View, { className: "flex-1 gap-0.5", children: [_jsx(Typography.Text, { className: "text-text-primary", numberOfLines: 1, semibold: true, variant: "body", children: title }), subtitle ? (_jsx(Typography.Text, { className: "text-text-secondary", numberOfLines: 1, variant: "bodySmall", children: subtitle })) : null] }), right ? _jsx(View, { className: "ml-3 justify-center", children: right }) : null] }));
|
|
12
|
+
const base = cn("flex-row items-center py-3 px-4 bg-bg-card", showDivider && "border-b border-border-default", className);
|
|
13
|
+
if (onPress) {
|
|
14
|
+
return (_jsx(Pressable, { className: base, onPress: onPress, testID: testID, children: content }));
|
|
15
|
+
}
|
|
16
|
+
return (_jsx(View, { className: base, testID: testID, children: content }));
|
|
17
|
+
}
|
|
18
|
+
export default ListItem;
|