@sincpro/mobile-ui 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -29
- package/dist/Actions/Actions.Button.d.ts +10 -12
- package/dist/Actions/Actions.Button.js +9 -11
- package/dist/Actions/Actions.Dock.d.ts +20 -0
- package/dist/Actions/Actions.Dock.js +89 -0
- package/dist/Actions/Actions.FAB.d.ts +1 -2
- package/dist/Actions/Actions.FAB.js +5 -7
- package/dist/Actions/Actions.IconButton.d.ts +1 -2
- package/dist/Actions/Actions.IconButton.js +2 -2
- package/dist/Actions/index.d.ts +4 -0
- package/dist/Actions/index.js +3 -0
- package/dist/Dialog/BottomSheet/BottomSheet.Root.js +22 -34
- package/dist/Dialog/Dialog.ActionSheet.js +2 -16
- package/dist/Dialog/Dialog.Confirmation.js +7 -5
- package/dist/Dialog/Dialog.EditValue.js +3 -1
- package/dist/Dialog/Dialog.Sheet.d.ts +3 -3
- package/dist/Dialog/Dialog.Sheet.js +18 -25
- package/dist/Display/Display.Accordion.js +7 -3
- package/dist/Display/Display.AmountSummary.d.ts +28 -0
- package/dist/Display/Display.AmountSummary.js +25 -0
- package/dist/Display/Display.Carousel.d.ts +27 -4
- package/dist/Display/Display.Carousel.js +112 -12
- package/dist/Display/Display.ExpoImage.d.ts +8 -0
- package/dist/Display/Display.ExpoImage.js +15 -0
- package/dist/Display/Display.Image.d.ts +10 -6
- package/dist/Display/Display.Image.js +39 -6
- package/dist/Display/Display.ListItem.d.ts +1 -2
- package/dist/Display/Display.ListItem.js +3 -3
- package/dist/Display/Display.Logo.d.ts +2 -2
- package/dist/Display/Display.Logo.js +3 -2
- package/dist/Display/Display.MediaCard.d.ts +2 -2
- package/dist/Display/Display.MediaEmbed.d.ts +2 -2
- package/dist/Display/Display.ProductCard.d.ts +2 -2
- package/dist/Display/Display.Story.d.ts +3 -3
- package/dist/Display/Display.Story.js +5 -4
- package/dist/Display/Display.StoryTray.d.ts +4 -4
- package/dist/Display/Display.StoryTray.js +3 -2
- package/dist/Display/Display.StoryViewer.d.ts +3 -3
- package/dist/Display/Display.StoryViewer.js +6 -3
- package/dist/Display/index.d.ts +9 -0
- package/dist/Display/index.js +4 -0
- package/dist/Feedback/Feedback.DomainSplashScreen.d.ts +13 -4
- package/dist/Feedback/Feedback.DomainSplashScreen.js +68 -53
- package/dist/Feedback/Feedback.EmptyState.d.ts +3 -4
- package/dist/Feedback/Feedback.EmptyState.js +4 -3
- package/dist/Feedback/Feedback.Error.d.ts +1 -2
- package/dist/Feedback/Feedback.Error.js +2 -2
- package/dist/Feedback/Feedback.Loading.d.ts +6 -2
- package/dist/Feedback/Feedback.Loading.js +2 -2
- package/dist/Feedback/Feedback.Progress.d.ts +6 -3
- package/dist/Feedback/Feedback.Progress.js +29 -19
- package/dist/Feedback/Feedback.ProgressCircle.d.ts +3 -2
- package/dist/Feedback/Feedback.ProgressCircle.js +10 -7
- package/dist/Feedback/Feedback.Skeleton.d.ts +4 -4
- package/dist/Feedback/Feedback.Skeleton.js +15 -3
- package/dist/Feedback/Feedback.Spinner.d.ts +3 -3
- package/dist/Feedback/Feedback.Spinner.js +40 -9
- package/dist/Feedback/Feedback.Splash.d.ts +2 -2
- package/dist/Feedback/Feedback.Splash.js +5 -3
- package/dist/Feedback/Toast.context.d.ts +64 -3
- package/dist/Feedback/Toast.context.js +112 -31
- package/dist/Feedback/index.d.ts +15 -1
- package/dist/Feedback/index.js +4 -1
- package/dist/Form/Form.Checkbox.d.ts +1 -2
- package/dist/Form/Form.Checkbox.js +2 -2
- package/dist/Form/Form.DatePicker.d.ts +1 -2
- package/dist/Form/Form.DatePicker.js +2 -2
- package/dist/Form/Form.Dropdown.d.ts +15 -3
- package/dist/Form/Form.Dropdown.js +21 -6
- package/dist/Form/Form.ErrorSummary.d.ts +23 -0
- package/dist/Form/Form.ErrorSummary.js +53 -0
- package/dist/Form/Form.Input.d.ts +1 -2
- package/dist/Form/Form.Input.js +2 -2
- package/dist/Form/Form.Select.d.ts +1 -2
- package/dist/Form/Form.Select.js +6 -19
- package/dist/Form/index.d.ts +3 -0
- package/dist/Form/index.js +2 -0
- package/dist/Navigation/Navigation.AppBar.d.ts +2 -6
- package/dist/Navigation/Navigation.AppBar.js +9 -7
- package/dist/Navigation/Navigation.BottomNav.d.ts +1 -3
- package/dist/Navigation/Navigation.BottomNav.js +7 -6
- package/dist/Navigation/Navigation.Header.d.ts +2 -2
- package/dist/Navigation/Navigation.Menu.js +10 -3
- package/dist/Navigation/Navigation.Search.d.ts +41 -0
- package/dist/Navigation/Navigation.Search.js +47 -0
- package/dist/Navigation/Navigation.SearchBar.d.ts +1 -2
- package/dist/Navigation/Navigation.SearchBar.js +16 -19
- package/dist/Navigation/Navigation.SegmentedControl.d.ts +11 -3
- package/dist/Navigation/Navigation.SegmentedControl.js +29 -16
- package/dist/Navigation/index.d.ts +11 -2
- package/dist/Navigation/index.js +2 -0
- package/dist/branding.d.ts +3 -2
- package/dist/primitives/BaseButton.d.ts +10 -12
- package/dist/primitives/BaseButton.js +9 -11
- package/dist/theme/typography.d.ts +1 -1
- package/dist/utils/image.d.ts +3 -0
- package/dist/utils/image.js +13 -0
- package/dist/utils/keys.d.ts +1 -0
- package/dist/utils/keys.js +7 -0
- package/dist/utils/progress.d.ts +1 -0
- package/dist/utils/progress.js +5 -0
- package/dist/utils/reorder.js +2 -5
- package/dist/utils/useReducedMotion.d.ts +1 -0
- package/dist/utils/useReducedMotion.js +43 -0
- package/dist/utils/useSheetTranslation.d.ts +5 -0
- package/dist/utils/useSheetTranslation.js +23 -0
- package/dist/views/AppSplashView.d.ts +3 -2
- package/dist/views/AppSplashView.js +3 -2
- package/dist/views/AuthFormView.d.ts +2 -2
- package/dist/views/FormViewV2.d.ts +2 -2
- package/dist/views/ListViewV2.context.d.ts +3 -1
- package/dist/views/ListViewV2.context.js +41 -21
- package/dist/views/ListViewV2.d.ts +15 -7
- package/dist/views/ListViewV2.js +44 -23
- package/dist/views/types/IListView.js +6 -5
- package/dist/widgets/CollectionOptions.js +9 -7
- package/dist/widgets/FilterBar.d.ts +1 -1
- package/dist/widgets/FilterBar.js +1 -1
- package/dist/widgets/FilterBuilder.js +7 -7
- package/dist/widgets/HomeHeader.d.ts +2 -2
- package/dist/widgets/PromoModal.js +3 -1
- package/dist/widgets/ScreenHeader.d.ts +2 -2
- package/package.json +4 -1
|
@@ -7,6 +7,7 @@ import Pressable from "../primitives/Pressable.js";
|
|
|
7
7
|
import { themeToVars, useTheme } from "../theme/index.js";
|
|
8
8
|
import { Typography } from "../Typography/index.js";
|
|
9
9
|
import { describeCriteria, moveCollectionEntry, validateCriteria, } from "../utils/criteria.js";
|
|
10
|
+
import { useReducedMotion } from "../utils/useReducedMotion.js";
|
|
10
11
|
import FilterBuilder from "./FilterBuilder.js";
|
|
11
12
|
import QueryChoice from "./QueryChoice.js";
|
|
12
13
|
import { vars } from "nativewind";
|
|
@@ -24,6 +25,7 @@ const sections = [
|
|
|
24
25
|
];
|
|
25
26
|
function OptionsEditor({ value, fields, sortFields = [], groupFields = [], savedQueries = [], onApply, onClose, onSave, title = "Configurar colección", testID, }) {
|
|
26
27
|
const theme = useTheme();
|
|
28
|
+
const reducedMotion = useReducedMotion();
|
|
27
29
|
const insets = useSafeAreaInsets();
|
|
28
30
|
const [draft, setDraft] = useState(value);
|
|
29
31
|
const [section, setSection] = useState("filter");
|
|
@@ -56,7 +58,7 @@ function OptionsEditor({ value, fields, sortFields = [], groupFields = [], saved
|
|
|
56
58
|
}),
|
|
57
59
|
}
|
|
58
60
|
: { ...current, groupBy: next });
|
|
59
|
-
return (_jsx(Modal, { animationType: "slide", onRequestClose: close, presentationStyle: "fullScreen", visible: true, children: _jsxs(View, { accessibilityViewIsModal: true, onAccessibilityEscape: close, style: [
|
|
61
|
+
return (_jsx(Modal, { animationType: reducedMotion ? "none" : "slide", onRequestClose: close, presentationStyle: "fullScreen", visible: true, children: _jsxs(View, { accessibilityViewIsModal: true, onAccessibilityEscape: close, style: [
|
|
60
62
|
vars(themeToVars(theme)),
|
|
61
63
|
{
|
|
62
64
|
flex: 1,
|
|
@@ -64,7 +66,7 @@ function OptionsEditor({ value, fields, sortFields = [], groupFields = [], saved
|
|
|
64
66
|
paddingTop: insets.top,
|
|
65
67
|
paddingBottom: insets.bottom,
|
|
66
68
|
},
|
|
67
|
-
], testID: testID, children: [_jsxs(View, { className: "flex-row items-center justify-between gap-3 px-4", children: [_jsx(Typography.Text, { accessibilityRole: "header", semibold: true, style: { flex: 1, minWidth: 0 }, variant: "bodyReadable", children: title }), _jsx(IconButton, { accessibilityLabel: "Cancelar configuraci\u00F3n",
|
|
69
|
+
], testID: testID, children: [_jsxs(View, { className: "flex-row items-center justify-between gap-3 px-4", children: [_jsx(Typography.Text, { accessibilityRole: "header", semibold: true, style: { flex: 1, minWidth: 0 }, variant: "bodyReadable", children: title }), _jsx(IconButton, { accessibilityLabel: "Cancelar configuraci\u00F3n", disabled: saving, icon: "close", onPress: close })] }), _jsx(View, { accessibilityRole: "tablist", className: "flex-row flex-wrap px-4 gap-2", children: sections.map((item) => (_jsx(Pressable, { accessibilityLabel: item.label, accessibilityRole: "tab", accessibilityState: {
|
|
68
70
|
selected: item.id === section,
|
|
69
71
|
disabled: editing || saving,
|
|
70
72
|
}, disabled: editing || saving, onPress: () => {
|
|
@@ -75,11 +77,11 @@ function OptionsEditor({ value, fields, sortFields = [], groupFields = [], saved
|
|
|
75
77
|
}, style: { minHeight: 48, justifyContent: "center", paddingHorizontal: 8 }, children: _jsx(Typography.Text, { className: section === item.id ? "text-text-accent" : "text-text-secondary", semibold: section === item.id, variant: "bodyLarge", children: item.label }) }, item.id))) }), _jsxs(KeyboardForm, { contentContainerStyle: { padding: 16, gap: 16 }, children: [!editing ? (_jsx(Typography.Text, { className: "text-text-secondary", variant: "bodyLarge", children: describeCriteria(draft.filter, fields) })) : null, section === "filter" ? (_jsx(FilterBuilder, { fields: fields, onChange: (filter) => {
|
|
76
78
|
setError(undefined);
|
|
77
79
|
setDraft({ ...draft, filter });
|
|
78
|
-
}, onEditingChange: setEditing, value: draft.filter })) : section === "saved" ? (_jsxs(_Fragment, { children: [_jsx(Typography.Text, { variant: "bodyReadable", children: "Una configuraci\u00F3n incluye b\u00FAsqueda, condiciones, orden y niveles de agrupaci\u00F3n. Cargarla todav\u00EDa no modifica la colecci\u00F3n." }), !savedQueries.length ? (_jsx(Typography.Text, { children: "No hay configuraciones guardadas." })) : (savedQueries.map((saved) => (_jsx(Button, {
|
|
80
|
+
}, onEditingChange: setEditing, value: draft.filter })) : section === "saved" ? (_jsxs(_Fragment, { children: [_jsx(Typography.Text, { variant: "bodyReadable", children: "Una configuraci\u00F3n incluye b\u00FAsqueda, condiciones, orden y niveles de agrupaci\u00F3n. Cargarla todav\u00EDa no modifica la colecci\u00F3n." }), !savedQueries.length ? (_jsx(Typography.Text, { children: "No hay configuraciones guardadas." })) : (savedQueries.map((saved) => (_jsx(Button, { disabled: saving, onPress: () => {
|
|
79
81
|
setDraft(saved.query);
|
|
80
82
|
setError(undefined);
|
|
81
83
|
setStatus(`Configuración ${saved.label} cargada. Pulsa Aplicar configuración.`);
|
|
82
|
-
}, title: `Cargar ${saved.label}`, variant: "secondary" }, saved.id)))), onSave ? (_jsxs(_Fragment, { children: [_jsx(Input, {
|
|
84
|
+
}, title: `Cargar ${saved.label}`, variant: "secondary" }, saved.id)))), onSave ? (_jsxs(_Fragment, { children: [_jsx(Input, { editable: !saving, label: "Nombre de la configuraci\u00F3n", onChangeText: setLabel, testID: "collection-query-name", value: label }), _jsx(Button, { loading: saving, onPress: () => {
|
|
83
85
|
const invalid = problem();
|
|
84
86
|
if (invalid || !label.trim()) {
|
|
85
87
|
setError(invalid ?? "Escribe un nombre para guardar.");
|
|
@@ -102,7 +104,7 @@ function OptionsEditor({ value, fields, sortFields = [], groupFields = [], saved
|
|
|
102
104
|
: "Los grupos se anidan en este orden. La app aplica los niveles al conjunto completo." }), !ordered.length ? (_jsx(Typography.Text, { children: section === "sort" ? "Sin orden configurado." : "Sin agrupación." })) : null, ordered.map((id, index) => {
|
|
103
105
|
const field = available.find((item) => item.id === id);
|
|
104
106
|
const sort = draft.sort.find((entry) => entry.field === id);
|
|
105
|
-
return (_jsxs(View, { className: "gap-2 border-b border-border-light pb-3", children: [_jsxs(Typography.Text, { semibold: true, variant: "bodyReadable", children: [index + 1, ". ", field?.label ?? `${id} (no disponible)`] }), section === "sort" ? (_jsx(Button, {
|
|
107
|
+
return (_jsxs(View, { className: "gap-2 border-b border-border-light pb-3", children: [_jsxs(Typography.Text, { semibold: true, variant: "bodyReadable", children: [index + 1, ". ", field?.label ?? `${id} (no disponible)`] }), section === "sort" ? (_jsx(Button, { onPress: () => setDraft({
|
|
106
108
|
...draft,
|
|
107
109
|
sort: draft.sort.map((entry) => entry.field === id
|
|
108
110
|
? {
|
|
@@ -110,12 +112,12 @@ function OptionsEditor({ value, fields, sortFields = [], groupFields = [], saved
|
|
|
110
112
|
direction: entry.direction === "asc" ? "desc" : "asc",
|
|
111
113
|
}
|
|
112
114
|
: entry),
|
|
113
|
-
}), title: `${field?.label ?? id}: ${sort?.direction === "asc" ? (field?.ascLabel ?? "Ascendente") : (field?.descLabel ?? "Descendente")}`, variant: "secondary" })) : null, _jsxs(View, { className: "flex-row flex-wrap gap-2", children: [_jsx(Button, { accessibilityLabel: `Subir ${field?.label ?? id}`,
|
|
115
|
+
}), title: `${field?.label ?? id}: ${sort?.direction === "asc" ? (field?.ascLabel ?? "Ascendente") : (field?.descLabel ?? "Descendente")}`, variant: "secondary" })) : null, _jsxs(View, { className: "flex-row flex-wrap gap-2", children: [_jsx(Button, { accessibilityLabel: `Subir ${field?.label ?? id}`, disabled: index === 0, onPress: () => updateOrder(moveCollectionEntry(ordered, index, -1)), title: "Subir", variant: "link" }), _jsx(Button, { accessibilityLabel: `Bajar ${field?.label ?? id}`, disabled: index === ordered.length - 1, onPress: () => updateOrder(moveCollectionEntry(ordered, index, 1)), title: "Bajar", variant: "link" }), _jsx(Button, { accessibilityLabel: `Quitar ${field?.label ?? id}`, onPress: () => updateOrder(ordered.filter((key) => key !== id)), title: "Quitar", variant: "link" })] })] }, id));
|
|
114
116
|
}), available.some((field) => !ordered.includes(field.id)) ? (_jsx(QueryChoice, { label: section === "sort"
|
|
115
117
|
? "Añadir criterio de orden"
|
|
116
118
|
: "Añadir nivel de agrupación", onChange: (id) => updateOrder([...ordered, id]), options: available
|
|
117
119
|
.filter((field) => !ordered.includes(field.id))
|
|
118
|
-
.map((field) => ({ label: field.label, value: field.id })), value: undefined })) : null] })), status ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", children: status })) : null, error ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", className: "text-danger", children: error })) : null] }), _jsxs(View, { className: "px-4 py-3 border-t border-border-light gap-2", children: [editing ? (_jsx(Typography.Text, { children: "Guarda o cancela la condici\u00F3n antes de aplicar." })) : null, _jsx(Button, {
|
|
120
|
+
.map((field) => ({ label: field.label, value: field.id })), value: undefined })) : null] })), status ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", children: status })) : null, error ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", className: "text-danger", children: error })) : null] }), _jsxs(View, { className: "px-4 py-3 border-t border-border-light gap-2", children: [editing ? (_jsx(Typography.Text, { children: "Guarda o cancela la condici\u00F3n antes de aplicar." })) : null, _jsx(Button, { disabled: editing || saving, onPress: () => {
|
|
119
121
|
const invalid = problem();
|
|
120
122
|
if (invalid) {
|
|
121
123
|
setError(invalid);
|
|
@@ -8,7 +8,7 @@ export interface FilterBarOption {
|
|
|
8
8
|
export interface FilterBarProps {
|
|
9
9
|
filters: readonly FilterBarOption[];
|
|
10
10
|
onFilterPress: (id: string) => void;
|
|
11
|
-
search?:
|
|
11
|
+
search?: SearchBarProps;
|
|
12
12
|
onOpenFilters?: () => void;
|
|
13
13
|
filtersLabel?: string;
|
|
14
14
|
onClearFilters?: () => void;
|
|
@@ -10,5 +10,5 @@ export function FilterBar({ filters, onFilterPress, search, onOpenFilters, filte
|
|
|
10
10
|
const { fontScale } = useWindowDimensions();
|
|
11
11
|
const selectedCount = filters.filter((filter) => filter.selected).length;
|
|
12
12
|
const filterLayout = layout === "auto" ? (fontScale > 1.3 ? "wrap" : "scroll") : layout;
|
|
13
|
-
return (_jsxs(View, { className: cn("gap-2", className), testID: testID, children: [search || onOpenFilters ? (_jsxs(View, { className: "flex-row items-center gap-2", children: [search ? (_jsx(View, { className: "flex-1 min-w-0", children: _jsx(SearchBar, { ...search
|
|
13
|
+
return (_jsxs(View, { className: cn("gap-2", className), testID: testID, children: [search || onOpenFilters ? (_jsxs(View, { className: "flex-row items-center gap-2", children: [search ? (_jsx(View, { className: "flex-1 min-w-0", children: _jsx(SearchBar, { ...search }) })) : null, onOpenFilters ? (_jsx(IconButton, { accessibilityLabel: filtersLabel, icon: "sliders", onPress: onOpenFilters })) : null] })) : null, _jsx(FilterButtonGroup, { className: "p-0", layout: filterLayout, testID: testID ? `${testID}-options` : undefined, children: filters.map((filter) => (_jsx(FilterButton, { active: filter.selected, disabled: filter.disabled, onPress: () => onFilterPress(filter.id), testID: testID ? `${testID}-${filter.id}` : undefined, title: filter.label, variant: "mobile" }, filter.id))) }), resultsLabel || (selectedCount > 0 && onClearFilters) ? (_jsxs(View, { className: "flex-row flex-wrap items-center justify-between gap-x-3", children: [resultsLabel ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", className: "text-text-secondary", variant: "bodyLarge", children: resultsLabel })) : null, selectedCount > 0 && onClearFilters ? (_jsx(Pressable, { accessibilityLabel: clearLabel, accessibilityRole: "button", onPress: onClearFilters, style: { minHeight: 48, minWidth: 48, justifyContent: "center" }, children: _jsx(Typography.Text, { className: "text-text-accent", variant: "bodyLarge", children: clearLabel }) })) : null] })) : null] }));
|
|
14
14
|
}
|
|
@@ -21,7 +21,7 @@ export default function FilterBuilder({ fields, value, onChange, onEditingChange
|
|
|
21
21
|
current = current?.kind === "group" ? current.children[index] : undefined;
|
|
22
22
|
}
|
|
23
23
|
if (current?.kind !== "group")
|
|
24
|
-
return (_jsxs(View, { className: className, testID: testID, children: [_jsx(Typography.Text, { accessibilityLiveRegion: "polite", children: "Este grupo ya no est\u00E1 disponible. La configuraci\u00F3n cambi\u00F3." }), _jsx(Button, {
|
|
24
|
+
return (_jsxs(View, { className: className, testID: testID, children: [_jsx(Typography.Text, { accessibilityLiveRegion: "polite", children: "Este grupo ya no est\u00E1 disponible. La configuraci\u00F3n cambi\u00F3." }), _jsx(Button, { onPress: () => {
|
|
25
25
|
setPath([]);
|
|
26
26
|
setEditing(null);
|
|
27
27
|
}, title: "Volver a condiciones", variant: "secondary" })] }));
|
|
@@ -71,11 +71,11 @@ export default function FilterBuilder({ fields, value, onChange, onEditingChange
|
|
|
71
71
|
values[index] = next;
|
|
72
72
|
changeCondition({ ...condition, values });
|
|
73
73
|
};
|
|
74
|
-
return field?.type === "choice" ? (_jsx(QueryChoice, { label: label, onChange: update, options: field.options ?? [], value: condition.values[index] }, index)) : field?.type === "date" ? (_jsx(DatePicker, {
|
|
74
|
+
return field?.type === "choice" ? (_jsx(QueryChoice, { label: label, onChange: update, options: field.options ?? [], value: condition.values[index] }, index)) : field?.type === "date" ? (_jsx(DatePicker, { label: label, onChange: (date) => update(`${String(date.getFullYear()).padStart(4, "0")}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`), value: parseCriteriaDate(condition.values[index]) }, index)) : (_jsx(Input, { keyboardType: field?.type === "number" ? "numbers-and-punctuation" : "default", label: label, onChangeText: update, testID: `criteria-value-${index}`, value: condition.values[index] === undefined ||
|
|
75
75
|
Number.isNaN(condition.values[index])
|
|
76
76
|
? ""
|
|
77
77
|
: String(condition.values[index]) }, index));
|
|
78
|
-
}), error ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", className: "text-danger", children: error })) : null, _jsx(Button, {
|
|
78
|
+
}), error ? (_jsx(Typography.Text, { accessibilityLiveRegion: "polite", className: "text-danger", children: error })) : null, _jsx(Button, { onPress: () => {
|
|
79
79
|
const next = {
|
|
80
80
|
...condition,
|
|
81
81
|
values: field?.type === "number"
|
|
@@ -94,18 +94,18 @@ export default function FilterBuilder({ fields, value, onChange, onEditingChange
|
|
|
94
94
|
children[editing.index] = next;
|
|
95
95
|
changeGroup({ ...group, children });
|
|
96
96
|
setEditing(null);
|
|
97
|
-
}, title: "Guardar condici\u00F3n" }), _jsx(Button, {
|
|
97
|
+
}, title: "Guardar condici\u00F3n" }), _jsx(Button, { onPress: () => setEditing(null), title: "Cancelar condici\u00F3n", variant: "secondary" })] })) : (_jsxs(_Fragment, { children: [path.length ? (_jsx(Button, { onPress: () => setPath(path.slice(0, -1)), title: "Volver al grupo anterior", variant: "link" })) : null, _jsx(QueryChoice, { label: "Coinciden", onChange: (join) => changeGroup({ ...group, join }), options: [
|
|
98
98
|
{ label: "Todas las condiciones", value: "all" },
|
|
99
99
|
{ label: "Cualquiera de las condiciones", value: "any" },
|
|
100
100
|
{ label: "Ninguna de las condiciones", value: "none" },
|
|
101
|
-
], value: group.join }), !group.children.length ? (_jsx(Typography.Text, { className: "text-text-secondary", children: "Sin condiciones en este grupo." })) : null, group.children.map((child, index) => (_jsxs(View, { className: "border-b border-border-light pb-3 gap-2", children: [_jsx(Typography.Text, { variant: "bodyReadable", children: describeCriteria(child, fields) }), _jsxs(View, { className: "flex-row flex-wrap gap-2", children: [_jsx(Button, {
|
|
101
|
+
], value: group.join }), !group.children.length ? (_jsx(Typography.Text, { className: "text-text-secondary", children: "Sin condiciones en este grupo." })) : null, group.children.map((child, index) => (_jsxs(View, { className: "border-b border-border-light pb-3 gap-2", children: [_jsx(Typography.Text, { variant: "bodyReadable", children: describeCriteria(child, fields) }), _jsxs(View, { className: "flex-row flex-wrap gap-2", children: [_jsx(Button, { onPress: () => child.kind === "group"
|
|
102
102
|
? setPath([...path, index])
|
|
103
103
|
: (setError(undefined), setEditing({ index, condition: child })), title: child.kind === "group"
|
|
104
104
|
? `Abrir grupo ${index + 1}`
|
|
105
|
-
: `Editar condición ${index + 1}`, variant: "secondary" }), _jsx(Button, {
|
|
105
|
+
: `Editar condición ${index + 1}`, variant: "secondary" }), _jsx(Button, { onPress: () => changeGroup({
|
|
106
106
|
...group,
|
|
107
107
|
children: group.children.filter((_, position) => position !== index),
|
|
108
|
-
}), title: `Eliminar ${child.kind === "group" ? "grupo" : "condición"} ${index + 1}`, variant: "link" })] })] }, index))), _jsx(Button, {
|
|
108
|
+
}), title: `Eliminar ${child.kind === "group" ? "grupo" : "condición"} ${index + 1}`, variant: "link" })] })] }, index))), _jsx(Button, { disabled: !fields.some((item) => item.operators.length), onPress: addCondition, title: "A\u00F1adir condici\u00F3n", variant: "secondary" }), _jsx(Button, { onPress: () => {
|
|
109
109
|
changeGroup({
|
|
110
110
|
...group,
|
|
111
111
|
children: [...group.children, { kind: "group", join: "any", children: [] }],
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import type { ImageSource } from "../utils/image.js";
|
|
1
2
|
import React, { ReactNode } from "react";
|
|
2
|
-
import { type ImageSourcePropType } from "react-native";
|
|
3
3
|
interface HomeHeaderProps {
|
|
4
4
|
readonly title?: string;
|
|
5
5
|
readonly logo?: ReactNode;
|
|
6
|
-
readonly logoSource?:
|
|
6
|
+
readonly logoSource?: ImageSource;
|
|
7
7
|
readonly backButton?: boolean;
|
|
8
8
|
readonly onBack?: () => void;
|
|
9
9
|
}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
|
2
2
|
import GradientSurface from "../Display/Display.GradientSurface.js";
|
|
3
3
|
import { useTheme } from "../theme/index.js";
|
|
4
4
|
import { Typography } from "../Typography/index.js";
|
|
5
|
+
import { useReducedMotion } from "../utils/useReducedMotion.js";
|
|
5
6
|
import { Modal, TouchableOpacity, TouchableWithoutFeedback, View } from "react-native";
|
|
6
7
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
7
8
|
/**
|
|
@@ -23,9 +24,10 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
|
23
24
|
*/
|
|
24
25
|
export function PromoModal({ visible, onDismiss, title, body, icon: Icon, headerGradient, ctaLabel, onPressCta, dismissLabel = "Ahora no", badge, accentColor, }) {
|
|
25
26
|
const theme = useTheme();
|
|
27
|
+
const reducedMotion = useReducedMotion();
|
|
26
28
|
const insets = useSafeAreaInsets();
|
|
27
29
|
const accent = accentColor ?? theme.accent;
|
|
28
|
-
return (_jsxs(Modal, { animationType: "fade", onRequestClose: onDismiss, presentationStyle: "overFullScreen", statusBarTranslucent: true, transparent: true, visible: visible, children: [_jsx(TouchableWithoutFeedback, { onPress: onDismiss, children: _jsx(View, { style: {
|
|
30
|
+
return (_jsxs(Modal, { animationType: reducedMotion ? "none" : "fade", onRequestClose: onDismiss, presentationStyle: "overFullScreen", statusBarTranslucent: true, transparent: true, visible: visible, children: [_jsx(TouchableWithoutFeedback, { onPress: onDismiss, children: _jsx(View, { style: {
|
|
29
31
|
flex: 1,
|
|
30
32
|
backgroundColor: "rgba(0,0,0,0.55)",
|
|
31
33
|
alignItems: "center",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ImageSource } from "../utils/image.js";
|
|
2
2
|
export declare enum EVariantScreenHeader {
|
|
3
3
|
FLAT_HEADER = "FLAT_HEADER",
|
|
4
4
|
ROUNDED_HEADER = "ROUNDED_HEADER",
|
|
@@ -11,7 +11,7 @@ interface ScreenHeaderProps {
|
|
|
11
11
|
centerTitle?: boolean;
|
|
12
12
|
subtitle?: string;
|
|
13
13
|
logo?: boolean;
|
|
14
|
-
logoSource?:
|
|
14
|
+
logoSource?: ImageSource;
|
|
15
15
|
rightComponent?: React.ReactNode;
|
|
16
16
|
children?: React.ReactNode;
|
|
17
17
|
withGradientContainer?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sincpro/mobile-ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Sincpro Mobile design system: generic, presentational React Native components (no domain logic)",
|
|
5
5
|
"main": "expo/AppEntry.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"./Dialog/NativeSheet": "./dist/Dialog/Dialog.NativeSheet.js",
|
|
23
23
|
"./Actions": "./dist/Actions/index.js",
|
|
24
24
|
"./Display": "./dist/Display/index.js",
|
|
25
|
+
"./Display/ExpoImage": "./dist/Display/Display.ExpoImage.js",
|
|
25
26
|
"./Feedback": "./dist/Feedback/index.js",
|
|
26
27
|
"./Form": "./dist/Form/index.js",
|
|
27
28
|
"./Navigation": "./dist/Navigation/index.js",
|
|
@@ -63,6 +64,7 @@
|
|
|
63
64
|
"expo-checkbox": ">=58.0.0",
|
|
64
65
|
"expo-clipboard": ">=58.0.0",
|
|
65
66
|
"expo-linear-gradient": ">=58.0.0",
|
|
67
|
+
"expo-image": ">=58.0.0",
|
|
66
68
|
"expo-localization": ">=58.0.0",
|
|
67
69
|
"nativewind": ">=4.2.7",
|
|
68
70
|
"react": ">=19.3",
|
|
@@ -124,6 +126,7 @@
|
|
|
124
126
|
"expo-checkbox": "~58.0.2",
|
|
125
127
|
"expo-clipboard": "~58.0.4",
|
|
126
128
|
"expo-font": "~58.0.11",
|
|
129
|
+
"expo-image": "~58.0.18",
|
|
127
130
|
"expo-linear-gradient": "~58.0.3",
|
|
128
131
|
"expo-localization": "~58.0.5",
|
|
129
132
|
"expo-status-bar": "~58.0.4",
|