@rojaostudio/ds 1.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/LICENSE +21 -0
- package/README.md +89 -0
- package/brand/rojao-black-on-white.png +0 -0
- package/brand/rojao-black.png +0 -0
- package/brand/rojao-white-on-black.png +0 -0
- package/brand/rojao-white.png +0 -0
- package/dist/chunk-ORMEWXMH.js +37 -0
- package/dist/compat/generate.d.ts +6 -0
- package/dist/compat/generate.js +1 -0
- package/dist/compat/recipes.d.ts +1 -0
- package/dist/compat/recipes.js +1 -0
- package/dist/compat/themes.d.ts +1 -0
- package/dist/compat/themes.js +1 -0
- package/dist/compat/tokens.d.ts +1 -0
- package/dist/compat/tokens.js +1 -0
- package/dist/components/accordion.d.ts +35 -0
- package/dist/components/accordion.js +95 -0
- package/dist/components/alert.d.ts +24 -0
- package/dist/components/alert.js +72 -0
- package/dist/components/avatar.d.ts +45 -0
- package/dist/components/avatar.js +97 -0
- package/dist/components/badge.d.ts +45 -0
- package/dist/components/badge.js +114 -0
- package/dist/components/blocker-card.d.ts +42 -0
- package/dist/components/blocker-card.js +45 -0
- package/dist/components/bottom-sheet.d.ts +31 -0
- package/dist/components/bottom-sheet.js +120 -0
- package/dist/components/breadcrumb.d.ts +28 -0
- package/dist/components/breadcrumb.js +52 -0
- package/dist/components/button.d.ts +27 -0
- package/dist/components/button.js +124 -0
- package/dist/components/card.d.ts +27 -0
- package/dist/components/card.js +52 -0
- package/dist/components/chat-bubble.d.ts +16 -0
- package/dist/components/chat-bubble.js +55 -0
- package/dist/components/checkbox.d.ts +14 -0
- package/dist/components/checkbox.js +78 -0
- package/dist/components/chip-input.d.ts +26 -0
- package/dist/components/chip-input.js +182 -0
- package/dist/components/chips.d.ts +22 -0
- package/dist/components/chips.js +94 -0
- package/dist/components/choice-card.d.ts +16 -0
- package/dist/components/choice-card.js +60 -0
- package/dist/components/choice-carousel.d.ts +16 -0
- package/dist/components/choice-carousel.js +154 -0
- package/dist/components/choice-preview-card.d.ts +37 -0
- package/dist/components/choice-preview-card.js +39 -0
- package/dist/components/color-input.d.ts +20 -0
- package/dist/components/color-input.js +79 -0
- package/dist/components/combobox.d.ts +70 -0
- package/dist/components/combobox.js +213 -0
- package/dist/components/context-menu.d.ts +33 -0
- package/dist/components/context-menu.js +70 -0
- package/dist/components/copilot-hint.d.ts +18 -0
- package/dist/components/copilot-hint.js +63 -0
- package/dist/components/copy-field.d.ts +16 -0
- package/dist/components/copy-field.js +41 -0
- package/dist/components/currency-input.d.ts +32 -0
- package/dist/components/currency-input.js +138 -0
- package/dist/components/danger-zone.d.ts +20 -0
- package/dist/components/danger-zone.js +21 -0
- package/dist/components/data-table-header.d.ts +43 -0
- package/dist/components/data-table-header.js +205 -0
- package/dist/components/date-picker.d.ts +40 -0
- package/dist/components/date-picker.js +252 -0
- package/dist/components/divider.d.ts +20 -0
- package/dist/components/divider.js +47 -0
- package/dist/components/drawer.d.ts +26 -0
- package/dist/components/drawer.js +82 -0
- package/dist/components/dropzone.d.ts +19 -0
- package/dist/components/dropzone.js +65 -0
- package/dist/components/empty-state.d.ts +48 -0
- package/dist/components/empty-state.js +91 -0
- package/dist/components/fab.d.ts +38 -0
- package/dist/components/fab.js +100 -0
- package/dist/components/filter-chip.d.ts +54 -0
- package/dist/components/filter-chip.js +66 -0
- package/dist/components/floating-stepper.d.ts +44 -0
- package/dist/components/floating-stepper.js +53 -0
- package/dist/components/form-card-header.d.ts +13 -0
- package/dist/components/form-card-header.js +8 -0
- package/dist/components/icon-button.d.ts +17 -0
- package/dist/components/icon-button.js +80 -0
- package/dist/components/image-crop-modal.d.ts +59 -0
- package/dist/components/image-crop-modal.js +240 -0
- package/dist/components/image-upload.d.ts +72 -0
- package/dist/components/image-upload.js +271 -0
- package/dist/components/index.d.ts +85 -0
- package/dist/components/index.js +200 -0
- package/dist/components/input.d.ts +25 -0
- package/dist/components/input.js +136 -0
- package/dist/components/insight-card.d.ts +19 -0
- package/dist/components/insight-card.js +27 -0
- package/dist/components/label.d.ts +16 -0
- package/dist/components/label.js +43 -0
- package/dist/components/media-tile.d.ts +24 -0
- package/dist/components/media-tile.js +28 -0
- package/dist/components/menu.d.ts +50 -0
- package/dist/components/menu.js +80 -0
- package/dist/components/modal.d.ts +25 -0
- package/dist/components/modal.js +71 -0
- package/dist/components/notice.d.ts +50 -0
- package/dist/components/notice.js +103 -0
- package/dist/components/option-tile.d.ts +60 -0
- package/dist/components/option-tile.js +144 -0
- package/dist/components/page-shell.d.ts +29 -0
- package/dist/components/page-shell.js +36 -0
- package/dist/components/page-skeleton.d.ts +35 -0
- package/dist/components/page-skeleton.js +12 -0
- package/dist/components/page-tabs.d.ts +35 -0
- package/dist/components/page-tabs.js +55 -0
- package/dist/components/pagination.d.ts +31 -0
- package/dist/components/pagination.js +80 -0
- package/dist/components/paywall-banner.d.ts +37 -0
- package/dist/components/paywall-banner.js +42 -0
- package/dist/components/paywall.d.ts +44 -0
- package/dist/components/paywall.js +55 -0
- package/dist/components/phone-frame.d.ts +9 -0
- package/dist/components/phone-frame.js +18 -0
- package/dist/components/phone-input.d.ts +24 -0
- package/dist/components/phone-input.js +92 -0
- package/dist/components/pix-icon.d.ts +8 -0
- package/dist/components/pix-icon.js +24 -0
- package/dist/components/popover.d.ts +44 -0
- package/dist/components/popover.js +140 -0
- package/dist/components/pricing-card.d.ts +42 -0
- package/dist/components/pricing-card.js +29 -0
- package/dist/components/qr-display.d.ts +19 -0
- package/dist/components/qr-display.js +24 -0
- package/dist/components/radio.d.ts +33 -0
- package/dist/components/radio.js +97 -0
- package/dist/components/row-actions.d.ts +24 -0
- package/dist/components/row-actions.js +76 -0
- package/dist/components/saving-bar-context.d.ts +40 -0
- package/dist/components/saving-bar-context.js +125 -0
- package/dist/components/saving-bar.d.ts +18 -0
- package/dist/components/saving-bar.js +72 -0
- package/dist/components/search.d.ts +30 -0
- package/dist/components/search.js +81 -0
- package/dist/components/section-card.d.ts +14 -0
- package/dist/components/section-card.js +49 -0
- package/dist/components/section-header.d.ts +29 -0
- package/dist/components/section-header.js +7 -0
- package/dist/components/select.d.ts +21 -0
- package/dist/components/select.js +140 -0
- package/dist/components/selectable-card.d.ts +35 -0
- package/dist/components/selectable-card.js +27 -0
- package/dist/components/setting-row.d.ts +33 -0
- package/dist/components/setting-row.js +19 -0
- package/dist/components/settings-list.d.ts +25 -0
- package/dist/components/settings-list.js +22 -0
- package/dist/components/skeleton.d.ts +24 -0
- package/dist/components/skeleton.js +49 -0
- package/dist/components/slider.d.ts +32 -0
- package/dist/components/slider.js +79 -0
- package/dist/components/spinner.d.ts +14 -0
- package/dist/components/spinner.js +36 -0
- package/dist/components/step-progress.d.ts +12 -0
- package/dist/components/step-progress.js +24 -0
- package/dist/components/summary-bar.d.ts +31 -0
- package/dist/components/summary-bar.js +54 -0
- package/dist/components/table.d.ts +23 -0
- package/dist/components/table.js +80 -0
- package/dist/components/textarea.d.ts +21 -0
- package/dist/components/textarea.js +95 -0
- package/dist/components/themed.d.ts +36 -0
- package/dist/components/themed.js +22 -0
- package/dist/components/time-picker.d.ts +34 -0
- package/dist/components/time-picker.js +213 -0
- package/dist/components/toaster.d.ts +84 -0
- package/dist/components/toaster.js +284 -0
- package/dist/components/toggle-card-compact.d.ts +21 -0
- package/dist/components/toggle-card-compact.js +99 -0
- package/dist/components/toggle-card.d.ts +15 -0
- package/dist/components/toggle-card.js +76 -0
- package/dist/components/toggle-group.d.ts +67 -0
- package/dist/components/toggle-group.js +80 -0
- package/dist/components/toggle.d.ts +13 -0
- package/dist/components/toggle.js +64 -0
- package/dist/components/tooltip.d.ts +17 -0
- package/dist/components/tooltip.js +89 -0
- package/dist/components/typing-indicator.d.ts +8 -0
- package/dist/components/typing-indicator.js +27 -0
- package/dist/components/use-dismiss.d.ts +9 -0
- package/dist/components/use-dismiss.js +28 -0
- package/dist/components/use-focus-trap.d.ts +5 -0
- package/dist/components/use-focus-trap.js +54 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +89 -0
- package/dist/targets/native/components/accordion.d.ts +18 -0
- package/dist/targets/native/components/accordion.js +122 -0
- package/dist/targets/native/components/alert.d.ts +16 -0
- package/dist/targets/native/components/alert.js +58 -0
- package/dist/targets/native/components/avatar.d.ts +25 -0
- package/dist/targets/native/components/avatar.js +88 -0
- package/dist/targets/native/components/badge.d.ts +27 -0
- package/dist/targets/native/components/badge.js +59 -0
- package/dist/targets/native/components/button.d.ts +18 -0
- package/dist/targets/native/components/button.js +84 -0
- package/dist/targets/native/components/card.d.ts +6 -0
- package/dist/targets/native/components/card.js +36 -0
- package/dist/targets/native/components/checkbox.d.ts +12 -0
- package/dist/targets/native/components/checkbox.js +59 -0
- package/dist/targets/native/components/chips.d.ts +17 -0
- package/dist/targets/native/components/chips.js +77 -0
- package/dist/targets/native/components/choice-card.d.ts +11 -0
- package/dist/targets/native/components/choice-card.js +52 -0
- package/dist/targets/native/components/context-menu.d.ts +11 -0
- package/dist/targets/native/components/context-menu.js +19 -0
- package/dist/targets/native/components/currency-input.d.ts +22 -0
- package/dist/targets/native/components/currency-input.js +105 -0
- package/dist/targets/native/components/danger-zone.d.ts +13 -0
- package/dist/targets/native/components/danger-zone.js +27 -0
- package/dist/targets/native/components/date-picker.d.ts +13 -0
- package/dist/targets/native/components/date-picker.js +185 -0
- package/dist/targets/native/components/divider.d.ts +9 -0
- package/dist/targets/native/components/divider.js +36 -0
- package/dist/targets/native/components/empty-state.d.ts +13 -0
- package/dist/targets/native/components/empty-state.js +10 -0
- package/dist/targets/native/components/fab.d.ts +25 -0
- package/dist/targets/native/components/fab.js +112 -0
- package/dist/targets/native/components/filter-chip.d.ts +22 -0
- package/dist/targets/native/components/filter-chip.js +70 -0
- package/dist/targets/native/components/form-field.d.ts +13 -0
- package/dist/targets/native/components/form-field.js +29 -0
- package/dist/targets/native/components/form-screen.d.ts +19 -0
- package/dist/targets/native/components/form-screen.js +88 -0
- package/dist/targets/native/components/google-icon.d.ts +8 -0
- package/dist/targets/native/components/google-icon.js +32 -0
- package/dist/targets/native/components/icon-button.d.ts +18 -0
- package/dist/targets/native/components/icon-button.js +80 -0
- package/dist/targets/native/components/icon.d.ts +11 -0
- package/dist/targets/native/components/icon.js +9 -0
- package/dist/targets/native/components/image-upload.d.ts +12 -0
- package/dist/targets/native/components/image-upload.js +95 -0
- package/dist/targets/native/components/index.d.ts +45 -0
- package/dist/targets/native/components/index.js +100 -0
- package/dist/targets/native/components/input.d.ts +17 -0
- package/dist/targets/native/components/input.js +103 -0
- package/dist/targets/native/components/list-item.d.ts +20 -0
- package/dist/targets/native/components/list-item.js +71 -0
- package/dist/targets/native/components/menu.d.ts +24 -0
- package/dist/targets/native/components/menu.js +71 -0
- package/dist/targets/native/components/modal.d.ts +15 -0
- package/dist/targets/native/components/modal.js +110 -0
- package/dist/targets/native/components/paywall-banner.d.ts +11 -0
- package/dist/targets/native/components/paywall-banner.js +46 -0
- package/dist/targets/native/components/paywall.d.ts +18 -0
- package/dist/targets/native/components/paywall.js +61 -0
- package/dist/targets/native/components/radio.d.ts +20 -0
- package/dist/targets/native/components/radio.js +71 -0
- package/dist/targets/native/components/search.d.ts +22 -0
- package/dist/targets/native/components/search.js +92 -0
- package/dist/targets/native/components/select.d.ts +17 -0
- package/dist/targets/native/components/select.js +86 -0
- package/dist/targets/native/components/sheet.d.ts +11 -0
- package/dist/targets/native/components/sheet.js +51 -0
- package/dist/targets/native/components/skeleton.d.ts +18 -0
- package/dist/targets/native/components/skeleton.js +52 -0
- package/dist/targets/native/components/slider.d.ts +18 -0
- package/dist/targets/native/components/slider.js +153 -0
- package/dist/targets/native/components/spinner.d.ts +7 -0
- package/dist/targets/native/components/spinner.js +10 -0
- package/dist/targets/native/components/stepper.d.ts +10 -0
- package/dist/targets/native/components/stepper.js +33 -0
- package/dist/targets/native/components/switch.d.ts +20 -0
- package/dist/targets/native/components/switch.js +68 -0
- package/dist/targets/native/components/text.d.ts +12 -0
- package/dist/targets/native/components/text.js +31 -0
- package/dist/targets/native/components/textarea.d.ts +13 -0
- package/dist/targets/native/components/textarea.js +92 -0
- package/dist/targets/native/components/theme.d.ts +18 -0
- package/dist/targets/native/components/theme.js +20 -0
- package/dist/targets/native/components/toaster.d.ts +35 -0
- package/dist/targets/native/components/toaster.js +159 -0
- package/dist/targets/native/fonts.d.ts +9 -0
- package/dist/targets/native/fonts.js +10 -0
- package/dist/targets/native/icons.d.ts +1 -0
- package/dist/targets/native/icons.js +1 -0
- package/dist/targets/native/index.d.ts +3 -0
- package/dist/targets/native/index.js +11 -0
- package/dist/targets/native/preset.cjs +69 -0
- package/dist/targets/native/resolve.d.ts +22 -0
- package/dist/targets/native/resolve.js +85 -0
- package/dist/targets/native/theme.css +118 -0
- package/dist/targets/native/theme.d.ts +117 -0
- package/dist/targets/native/theme.js +118 -0
- package/package.json +194 -0
- package/styles/_primitives.generated.css +284 -0
- package/styles/base.css +950 -0
- package/styles/themes/rojao.css +107 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { TextInputProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
type Props = Omit<TextInputProps, 'value' | 'onChangeText' | 'keyboardType'> & {
|
|
5
|
+
value: number;
|
|
6
|
+
onChangeValueCents: (cents: number) => void;
|
|
7
|
+
label?: string;
|
|
8
|
+
accessibilityLabel?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
error?: boolean;
|
|
11
|
+
/** Símbolo da moeda à esquerda. default = 'R$'. */
|
|
12
|
+
currency?: string;
|
|
13
|
+
/** Casas decimais. default = 2 (BRL/USD). JPY = 0, BTC = 8. */
|
|
14
|
+
decimals?: number;
|
|
15
|
+
/** Separador decimal. default = ','. */
|
|
16
|
+
decimalSeparator?: string;
|
|
17
|
+
/** Separador de milhar. default = '.'. */
|
|
18
|
+
thousandSeparator?: string;
|
|
19
|
+
};
|
|
20
|
+
declare function CurrencyInput({ value, onChangeValueCents, label, accessibilityLabel, disabled, error, currency, decimals, decimalSeparator, thousandSeparator, style, onFocus, onBlur, ...rest }: Props): react.JSX.Element;
|
|
21
|
+
|
|
22
|
+
export { CurrencyInput };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__objRest,
|
|
3
|
+
__spreadValues
|
|
4
|
+
} from "../../../chunk-ORMEWXMH.js";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import { StyleSheet, TextInput, View } from "react-native";
|
|
7
|
+
import { Text } from "./text.js";
|
|
8
|
+
import { useTheme } from "./theme.js";
|
|
9
|
+
function formatAmount(subunits, decimals, decimalSeparator, thousandSeparator) {
|
|
10
|
+
const divisor = Math.pow(10, decimals);
|
|
11
|
+
const fixed = (subunits / divisor).toFixed(decimals);
|
|
12
|
+
const [intPart, decPart] = fixed.split(".");
|
|
13
|
+
const grouped = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);
|
|
14
|
+
return decimals > 0 ? `${grouped}${decimalSeparator}${decPart}` : grouped;
|
|
15
|
+
}
|
|
16
|
+
function CurrencyInput(_a) {
|
|
17
|
+
var _b = _a, {
|
|
18
|
+
value,
|
|
19
|
+
onChangeValueCents,
|
|
20
|
+
label,
|
|
21
|
+
accessibilityLabel,
|
|
22
|
+
disabled,
|
|
23
|
+
error,
|
|
24
|
+
currency = "R$",
|
|
25
|
+
decimals = 2,
|
|
26
|
+
decimalSeparator = ",",
|
|
27
|
+
thousandSeparator = ".",
|
|
28
|
+
style,
|
|
29
|
+
onFocus,
|
|
30
|
+
onBlur
|
|
31
|
+
} = _b, rest = __objRest(_b, [
|
|
32
|
+
"value",
|
|
33
|
+
"onChangeValueCents",
|
|
34
|
+
"label",
|
|
35
|
+
"accessibilityLabel",
|
|
36
|
+
"disabled",
|
|
37
|
+
"error",
|
|
38
|
+
"currency",
|
|
39
|
+
"decimals",
|
|
40
|
+
"decimalSeparator",
|
|
41
|
+
"thousandSeparator",
|
|
42
|
+
"style",
|
|
43
|
+
"onFocus",
|
|
44
|
+
"onBlur"
|
|
45
|
+
]);
|
|
46
|
+
const t = useTheme();
|
|
47
|
+
const [focused, setFocused] = useState(false);
|
|
48
|
+
const display = formatAmount(value, decimals, decimalSeparator, thousandSeparator);
|
|
49
|
+
const borderColor = error ? t["--danger"] : focused ? t["--border-focus"] : t["--border-default"];
|
|
50
|
+
function handle(text) {
|
|
51
|
+
const digits = text.replace(/\D/g, "").slice(0, 12);
|
|
52
|
+
onChangeValueCents(digits ? parseInt(digits, 10) : 0);
|
|
53
|
+
}
|
|
54
|
+
return /* @__PURE__ */ React.createElement(
|
|
55
|
+
View,
|
|
56
|
+
{
|
|
57
|
+
style: [
|
|
58
|
+
styles.wrap,
|
|
59
|
+
{
|
|
60
|
+
borderColor,
|
|
61
|
+
backgroundColor: disabled ? t["--surface-raised"] : t["--surface-default"],
|
|
62
|
+
opacity: disabled ? 0.5 : 1
|
|
63
|
+
},
|
|
64
|
+
style
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
/* @__PURE__ */ React.createElement(Text, { variant: "body", color: "muted", style: { marginRight: 6 } }, currency),
|
|
68
|
+
/* @__PURE__ */ React.createElement(
|
|
69
|
+
TextInput,
|
|
70
|
+
__spreadValues({
|
|
71
|
+
value: display,
|
|
72
|
+
onChangeText: handle,
|
|
73
|
+
keyboardType: "number-pad",
|
|
74
|
+
editable: !disabled,
|
|
75
|
+
accessibilityLabel: accessibilityLabel != null ? accessibilityLabel : label,
|
|
76
|
+
accessibilityState: { disabled: !!disabled },
|
|
77
|
+
selectTextOnFocus: true,
|
|
78
|
+
placeholderTextColor: t["--text-placeholder"],
|
|
79
|
+
onFocus: (e) => {
|
|
80
|
+
setFocused(true);
|
|
81
|
+
onFocus == null ? void 0 : onFocus(e);
|
|
82
|
+
},
|
|
83
|
+
onBlur: (e) => {
|
|
84
|
+
setFocused(false);
|
|
85
|
+
onBlur == null ? void 0 : onBlur(e);
|
|
86
|
+
},
|
|
87
|
+
style: [styles.input, { color: disabled ? t["--text-disabled"] : t["--text-primary"] }]
|
|
88
|
+
}, rest)
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
const styles = StyleSheet.create({
|
|
93
|
+
wrap: {
|
|
94
|
+
height: 48,
|
|
95
|
+
borderRadius: 12,
|
|
96
|
+
borderWidth: 1,
|
|
97
|
+
paddingHorizontal: 16,
|
|
98
|
+
flexDirection: "row",
|
|
99
|
+
alignItems: "center"
|
|
100
|
+
},
|
|
101
|
+
input: { flex: 1, fontSize: 16, padding: 0 }
|
|
102
|
+
});
|
|
103
|
+
export {
|
|
104
|
+
CurrencyInput
|
|
105
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { ViewStyle } from 'react-native';
|
|
4
|
+
|
|
5
|
+
interface DangerZoneProps {
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
style?: ViewStyle;
|
|
10
|
+
}
|
|
11
|
+
declare function DangerZone({ title, description, children, style }: DangerZoneProps): react.JSX.Element;
|
|
12
|
+
|
|
13
|
+
export { DangerZone, type DangerZoneProps };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import "../../../chunk-ORMEWXMH.js";
|
|
2
|
+
import { StyleSheet, View } from "react-native";
|
|
3
|
+
import { Text } from "./text.js";
|
|
4
|
+
import { useTheme } from "./theme.js";
|
|
5
|
+
function DangerZone({ title, description, children, style }) {
|
|
6
|
+
const t = useTheme();
|
|
7
|
+
return /* @__PURE__ */ React.createElement(
|
|
8
|
+
View,
|
|
9
|
+
{
|
|
10
|
+
style: [
|
|
11
|
+
styles.box,
|
|
12
|
+
{ backgroundColor: t["--danger-soft"], borderColor: t["--danger-border"] },
|
|
13
|
+
style
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
(title || description) && /* @__PURE__ */ React.createElement(View, { style: styles.header }, title ? /* @__PURE__ */ React.createElement(Text, { variant: "label", color: "danger" }, title) : null, description ? /* @__PURE__ */ React.createElement(Text, { variant: "caption", color: "danger", style: styles.description }, description) : null),
|
|
17
|
+
children
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
const styles = StyleSheet.create({
|
|
21
|
+
box: { borderRadius: 12, borderWidth: 1, padding: 20 },
|
|
22
|
+
header: { marginBottom: 16 },
|
|
23
|
+
description: { opacity: 0.75, marginTop: 2 }
|
|
24
|
+
});
|
|
25
|
+
export {
|
|
26
|
+
DangerZone
|
|
27
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
interface DatePickerProps {
|
|
4
|
+
value: Date | null;
|
|
5
|
+
onChange: (date: Date | null) => void;
|
|
6
|
+
min?: Date;
|
|
7
|
+
max?: Date;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare function DatePicker({ value, onChange, min, max, placeholder, disabled }: DatePickerProps): react.JSX.Element;
|
|
12
|
+
|
|
13
|
+
export { DatePicker, type DatePickerProps };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import "../../../chunk-ORMEWXMH.js";
|
|
2
|
+
import { Calendar, ChevronLeft, ChevronRight } from "lucide-react-native";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Modal, Pressable, StyleSheet, View } from "react-native";
|
|
5
|
+
import { Text } from "./text.js";
|
|
6
|
+
import { useTheme } from "./theme.js";
|
|
7
|
+
const WEEKDAYS = ["S", "T", "Q", "Q", "S", "S", "D"];
|
|
8
|
+
const MONTHS = [
|
|
9
|
+
"Janeiro",
|
|
10
|
+
"Fevereiro",
|
|
11
|
+
"Mar\xE7o",
|
|
12
|
+
"Abril",
|
|
13
|
+
"Maio",
|
|
14
|
+
"Junho",
|
|
15
|
+
"Julho",
|
|
16
|
+
"Agosto",
|
|
17
|
+
"Setembro",
|
|
18
|
+
"Outubro",
|
|
19
|
+
"Novembro",
|
|
20
|
+
"Dezembro"
|
|
21
|
+
];
|
|
22
|
+
function pad(n) {
|
|
23
|
+
return String(n).padStart(2, "0");
|
|
24
|
+
}
|
|
25
|
+
function formatDate(d) {
|
|
26
|
+
return `${pad(d.getDate())}/${pad(d.getMonth() + 1)}/${d.getFullYear()}`;
|
|
27
|
+
}
|
|
28
|
+
function formatLong(d) {
|
|
29
|
+
return `${d.getDate()} de ${MONTHS[d.getMonth()]} de ${d.getFullYear()}`;
|
|
30
|
+
}
|
|
31
|
+
function sameDay(a, b) {
|
|
32
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
33
|
+
}
|
|
34
|
+
function startOfDay(d) {
|
|
35
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
36
|
+
}
|
|
37
|
+
function monthGrid(year, month) {
|
|
38
|
+
const first = new Date(year, month, 1);
|
|
39
|
+
const offset = (first.getDay() + 6) % 7;
|
|
40
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
41
|
+
const cells = [];
|
|
42
|
+
for (let i = 0; i < offset; i++) cells.push(null);
|
|
43
|
+
for (let day = 1; day <= daysInMonth; day++) cells.push(new Date(year, month, day));
|
|
44
|
+
while (cells.length % 7 !== 0) cells.push(null);
|
|
45
|
+
return cells;
|
|
46
|
+
}
|
|
47
|
+
function DatePicker({ value, onChange, min, max, placeholder, disabled }) {
|
|
48
|
+
const t = useTheme();
|
|
49
|
+
const [open, setOpen] = useState(false);
|
|
50
|
+
const initial = value != null ? value : /* @__PURE__ */ new Date();
|
|
51
|
+
const [viewYear, setViewYear] = useState(initial.getFullYear());
|
|
52
|
+
const [viewMonth, setViewMonth] = useState(initial.getMonth());
|
|
53
|
+
const minDay = min ? startOfDay(min) : null;
|
|
54
|
+
const maxDay = max ? startOfDay(max) : null;
|
|
55
|
+
function isDisabled(d) {
|
|
56
|
+
const day = startOfDay(d);
|
|
57
|
+
if (minDay && day < minDay) return true;
|
|
58
|
+
if (maxDay && day > maxDay) return true;
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
function openPicker() {
|
|
62
|
+
if (disabled) return;
|
|
63
|
+
const base = value != null ? value : /* @__PURE__ */ new Date();
|
|
64
|
+
setViewYear(base.getFullYear());
|
|
65
|
+
setViewMonth(base.getMonth());
|
|
66
|
+
setOpen(true);
|
|
67
|
+
}
|
|
68
|
+
function shiftMonth(delta) {
|
|
69
|
+
const d = new Date(viewYear, viewMonth + delta, 1);
|
|
70
|
+
setViewYear(d.getFullYear());
|
|
71
|
+
setViewMonth(d.getMonth());
|
|
72
|
+
}
|
|
73
|
+
function pick(d) {
|
|
74
|
+
if (isDisabled(d)) return;
|
|
75
|
+
onChange(d);
|
|
76
|
+
setOpen(false);
|
|
77
|
+
}
|
|
78
|
+
const cells = monthGrid(viewYear, viewMonth);
|
|
79
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
80
|
+
Pressable,
|
|
81
|
+
{
|
|
82
|
+
onPress: openPicker,
|
|
83
|
+
disabled,
|
|
84
|
+
accessibilityRole: "button",
|
|
85
|
+
accessibilityLabel: value ? `Data: ${formatLong(value)}` : placeholder != null ? placeholder : "Selecione uma data",
|
|
86
|
+
accessibilityState: { disabled: !!disabled },
|
|
87
|
+
style: [
|
|
88
|
+
styles.field,
|
|
89
|
+
{
|
|
90
|
+
borderColor: t["--border-default"],
|
|
91
|
+
backgroundColor: t["--surface-default"],
|
|
92
|
+
opacity: disabled ? 0.5 : 1
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
/* @__PURE__ */ React.createElement(Text, { variant: "body", color: value ? "primary" : "muted", style: { flex: 1 } }, value ? formatDate(value) : placeholder != null ? placeholder : "Selecione uma data"),
|
|
97
|
+
/* @__PURE__ */ React.createElement(Calendar, { size: 20, color: t["--text-muted"] })
|
|
98
|
+
), /* @__PURE__ */ React.createElement(Modal, { visible: open, transparent: true, animationType: "fade", onRequestClose: () => setOpen(false) }, /* @__PURE__ */ React.createElement(Pressable, { style: styles.backdrop, onPress: () => setOpen(false) }, /* @__PURE__ */ React.createElement(
|
|
99
|
+
Pressable,
|
|
100
|
+
{
|
|
101
|
+
style: [styles.card, { backgroundColor: t["--surface-default"] }],
|
|
102
|
+
onPress: (e) => e.stopPropagation(),
|
|
103
|
+
accessibilityViewIsModal: true
|
|
104
|
+
},
|
|
105
|
+
/* @__PURE__ */ React.createElement(View, { style: styles.header }, /* @__PURE__ */ React.createElement(Pressable, { onPress: () => shiftMonth(-1), hitSlop: 8, accessibilityRole: "button", accessibilityLabel: "M\xEAs anterior", style: styles.navBtn }, /* @__PURE__ */ React.createElement(ChevronLeft, { size: 22, color: t["--text-primary"] })), /* @__PURE__ */ React.createElement(Text, { variant: "label" }, MONTHS[viewMonth], " ", viewYear), /* @__PURE__ */ React.createElement(Pressable, { onPress: () => shiftMonth(1), hitSlop: 8, accessibilityRole: "button", accessibilityLabel: "Pr\xF3ximo m\xEAs", style: styles.navBtn }, /* @__PURE__ */ React.createElement(ChevronRight, { size: 22, color: t["--text-primary"] }))),
|
|
106
|
+
/* @__PURE__ */ React.createElement(View, { style: styles.week }, WEEKDAYS.map((w, i) => /* @__PURE__ */ React.createElement(View, { key: i, style: styles.cell }, /* @__PURE__ */ React.createElement(Text, { variant: "caption", color: "muted" }, w)))),
|
|
107
|
+
/* @__PURE__ */ React.createElement(View, { style: styles.grid }, cells.map((d, i) => {
|
|
108
|
+
if (!d) return /* @__PURE__ */ React.createElement(View, { key: i, style: styles.cell });
|
|
109
|
+
const selected = value ? sameDay(d, value) : false;
|
|
110
|
+
const off = isDisabled(d);
|
|
111
|
+
return /* @__PURE__ */ React.createElement(
|
|
112
|
+
Pressable,
|
|
113
|
+
{
|
|
114
|
+
key: i,
|
|
115
|
+
onPress: () => pick(d),
|
|
116
|
+
disabled: off,
|
|
117
|
+
accessibilityRole: "button",
|
|
118
|
+
accessibilityLabel: formatLong(d),
|
|
119
|
+
accessibilityState: { selected, disabled: off },
|
|
120
|
+
style: [
|
|
121
|
+
styles.cell,
|
|
122
|
+
styles.day,
|
|
123
|
+
selected ? { backgroundColor: t["--brand-primary"] } : null
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
/* @__PURE__ */ React.createElement(
|
|
127
|
+
Text,
|
|
128
|
+
{
|
|
129
|
+
variant: "body-sm",
|
|
130
|
+
style: {
|
|
131
|
+
color: selected ? t["--brand-on-primary"] : off ? t["--text-placeholder"] : t["--text-primary"]
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
d.getDate()
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
})),
|
|
138
|
+
value && /* @__PURE__ */ React.createElement(
|
|
139
|
+
Pressable,
|
|
140
|
+
{
|
|
141
|
+
onPress: () => {
|
|
142
|
+
onChange(null);
|
|
143
|
+
setOpen(false);
|
|
144
|
+
},
|
|
145
|
+
accessibilityRole: "button",
|
|
146
|
+
accessibilityLabel: "Limpar data",
|
|
147
|
+
style: styles.clear
|
|
148
|
+
},
|
|
149
|
+
/* @__PURE__ */ React.createElement(Text, { variant: "body-sm", color: "muted" }, "Limpar")
|
|
150
|
+
)
|
|
151
|
+
))));
|
|
152
|
+
}
|
|
153
|
+
const styles = StyleSheet.create({
|
|
154
|
+
field: {
|
|
155
|
+
height: 48,
|
|
156
|
+
borderRadius: 12,
|
|
157
|
+
borderWidth: 1,
|
|
158
|
+
paddingHorizontal: 16,
|
|
159
|
+
flexDirection: "row",
|
|
160
|
+
alignItems: "center"
|
|
161
|
+
},
|
|
162
|
+
backdrop: {
|
|
163
|
+
flex: 1,
|
|
164
|
+
backgroundColor: "rgba(0,0,0,0.4)",
|
|
165
|
+
alignItems: "center",
|
|
166
|
+
justifyContent: "center",
|
|
167
|
+
padding: 24
|
|
168
|
+
},
|
|
169
|
+
card: { width: "100%", maxWidth: 360, borderRadius: 16, padding: 16, gap: 8 },
|
|
170
|
+
header: {
|
|
171
|
+
flexDirection: "row",
|
|
172
|
+
alignItems: "center",
|
|
173
|
+
justifyContent: "space-between",
|
|
174
|
+
marginBottom: 4
|
|
175
|
+
},
|
|
176
|
+
navBtn: { width: 44, height: 44, alignItems: "center", justifyContent: "center" },
|
|
177
|
+
week: { flexDirection: "row" },
|
|
178
|
+
grid: { flexDirection: "row", flexWrap: "wrap" },
|
|
179
|
+
cell: { width: `${100 / 7}%`, aspectRatio: 1, alignItems: "center", justifyContent: "center" },
|
|
180
|
+
day: { borderRadius: 999 },
|
|
181
|
+
clear: { paddingVertical: 10, alignItems: "center", marginTop: 4 }
|
|
182
|
+
});
|
|
183
|
+
export {
|
|
184
|
+
DatePicker
|
|
185
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import "../../../chunk-ORMEWXMH.js";
|
|
2
|
+
import { StyleSheet, View } from "react-native";
|
|
3
|
+
import { useTheme } from "./theme.js";
|
|
4
|
+
function Divider({ vertical, spacing }) {
|
|
5
|
+
const t = useTheme();
|
|
6
|
+
const hairline = StyleSheet.hairlineWidth;
|
|
7
|
+
if (vertical) {
|
|
8
|
+
return /* @__PURE__ */ React.createElement(
|
|
9
|
+
View,
|
|
10
|
+
{
|
|
11
|
+
accessibilityRole: "none",
|
|
12
|
+
style: {
|
|
13
|
+
alignSelf: "stretch",
|
|
14
|
+
width: hairline,
|
|
15
|
+
backgroundColor: t["--border-default"],
|
|
16
|
+
marginHorizontal: spacing != null ? spacing : 0
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return /* @__PURE__ */ React.createElement(
|
|
22
|
+
View,
|
|
23
|
+
{
|
|
24
|
+
accessibilityRole: "none",
|
|
25
|
+
style: {
|
|
26
|
+
alignSelf: "stretch",
|
|
27
|
+
height: hairline,
|
|
28
|
+
backgroundColor: t["--border-default"],
|
|
29
|
+
marginVertical: spacing != null ? spacing : 0
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
Divider
|
|
36
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
type Props = {
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
cta?: {
|
|
7
|
+
label: string;
|
|
8
|
+
onPress: () => void;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
declare function EmptyState({ title, description, cta }: Props): react.JSX.Element;
|
|
12
|
+
|
|
13
|
+
export { EmptyState };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "../../../chunk-ORMEWXMH.js";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import { Text } from "./text.js";
|
|
5
|
+
function EmptyState({ title, description, cta }) {
|
|
6
|
+
return /* @__PURE__ */ React.createElement(View, { style: { flex: 1, alignItems: "center", justifyContent: "center", gap: 12, paddingHorizontal: 32 } }, /* @__PURE__ */ React.createElement(Text, { variant: "title", style: { textAlign: "center" } }, title), description ? /* @__PURE__ */ React.createElement(Text, { variant: "body-sm", color: "muted", style: { textAlign: "center" } }, description) : null, cta ? /* @__PURE__ */ React.createElement(Button, { label: cta.label, onPress: cta.onPress, fullWidth: true }) : null);
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
EmptyState
|
|
10
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type FABProps = {
|
|
5
|
+
/** Glifo lucide-react-native. Default: Plus. */
|
|
6
|
+
icon?: ReactNode;
|
|
7
|
+
onPress: () => void;
|
|
8
|
+
/** Obrigatório para screen readers (o FAB é só ícone no modo padrão). */
|
|
9
|
+
accessibilityLabel: string;
|
|
10
|
+
/** Mostra um label ao lado do ícone (pill estendida). */
|
|
11
|
+
extended?: boolean;
|
|
12
|
+
label?: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare function FAB({ icon, onPress, accessibilityLabel, extended, label, disabled, }: FABProps): react.JSX.Element;
|
|
16
|
+
type FABContextValue = {
|
|
17
|
+
config: FABProps | null;
|
|
18
|
+
setFAB: (config: FABProps | null) => void;
|
|
19
|
+
};
|
|
20
|
+
declare function FABProvider({ children }: {
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
}): react.JSX.Element;
|
|
23
|
+
declare function useFAB(): FABContextValue;
|
|
24
|
+
|
|
25
|
+
export { FAB, type FABProps, FABProvider, useFAB };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__spreadValues
|
|
3
|
+
} from "../../../chunk-ORMEWXMH.js";
|
|
4
|
+
import { Plus } from "lucide-react-native";
|
|
5
|
+
import {
|
|
6
|
+
cloneElement,
|
|
7
|
+
createContext,
|
|
8
|
+
isValidElement,
|
|
9
|
+
useCallback,
|
|
10
|
+
useContext,
|
|
11
|
+
useState
|
|
12
|
+
} from "react";
|
|
13
|
+
import { Platform, Pressable, StyleSheet, Text, View } from "react-native";
|
|
14
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
15
|
+
import { useTheme } from "./theme.js";
|
|
16
|
+
function tintIcon(icon, color, size) {
|
|
17
|
+
var _a, _b;
|
|
18
|
+
if (!isValidElement(icon)) return icon != null ? icon : null;
|
|
19
|
+
const el = icon;
|
|
20
|
+
return cloneElement(el, { color: (_a = el.props.color) != null ? _a : color, size: (_b = el.props.size) != null ? _b : size });
|
|
21
|
+
}
|
|
22
|
+
function FAB({
|
|
23
|
+
icon,
|
|
24
|
+
onPress,
|
|
25
|
+
accessibilityLabel,
|
|
26
|
+
extended = false,
|
|
27
|
+
label,
|
|
28
|
+
disabled = false
|
|
29
|
+
}) {
|
|
30
|
+
const t = useTheme();
|
|
31
|
+
const insets = useSafeAreaInsets();
|
|
32
|
+
const fg = t["--brand-on-primary"];
|
|
33
|
+
const glyph = tintIcon(icon != null ? icon : /* @__PURE__ */ React.createElement(Plus, null), fg, 24);
|
|
34
|
+
return /* @__PURE__ */ React.createElement(
|
|
35
|
+
View,
|
|
36
|
+
{
|
|
37
|
+
pointerEvents: "box-none",
|
|
38
|
+
style: [
|
|
39
|
+
styles.anchor,
|
|
40
|
+
{ right: 16, bottom: (insets.bottom > 0 ? insets.bottom : 16) + 16 }
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
/* @__PURE__ */ React.createElement(
|
|
44
|
+
Pressable,
|
|
45
|
+
{
|
|
46
|
+
accessibilityRole: "button",
|
|
47
|
+
accessibilityLabel,
|
|
48
|
+
accessibilityState: { disabled },
|
|
49
|
+
disabled,
|
|
50
|
+
hitSlop: 8,
|
|
51
|
+
onPress,
|
|
52
|
+
style: ({ pressed }) => [
|
|
53
|
+
styles.base,
|
|
54
|
+
extended ? styles.extended : styles.circle,
|
|
55
|
+
{
|
|
56
|
+
backgroundColor: t["--brand-primary"],
|
|
57
|
+
opacity: disabled ? 0.5 : pressed ? 0.85 : 1
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
glyph,
|
|
62
|
+
extended && label ? /* @__PURE__ */ React.createElement(Text, { style: [styles.label, { color: fg }], numberOfLines: 1 }, label) : null
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const FABContext = createContext({
|
|
67
|
+
config: null,
|
|
68
|
+
setFAB: () => {
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
function FABProvider({ children }) {
|
|
72
|
+
const [config, setConfig] = useState(null);
|
|
73
|
+
const setFAB = useCallback((next) => setConfig(next), []);
|
|
74
|
+
return /* @__PURE__ */ React.createElement(FABContext.Provider, { value: { config, setFAB } }, children, config ? /* @__PURE__ */ React.createElement(FAB, __spreadValues({}, config)) : null);
|
|
75
|
+
}
|
|
76
|
+
function useFAB() {
|
|
77
|
+
return useContext(FABContext);
|
|
78
|
+
}
|
|
79
|
+
const SHADOW = Platform.OS === "android" ? { elevation: 6 } : {
|
|
80
|
+
shadowColor: "#000000",
|
|
81
|
+
shadowOpacity: 0.25,
|
|
82
|
+
shadowRadius: 8,
|
|
83
|
+
shadowOffset: { width: 0, height: 4 }
|
|
84
|
+
};
|
|
85
|
+
const styles = StyleSheet.create({
|
|
86
|
+
anchor: {
|
|
87
|
+
position: "absolute",
|
|
88
|
+
alignItems: "flex-end"
|
|
89
|
+
},
|
|
90
|
+
base: __spreadValues({
|
|
91
|
+
flexDirection: "row",
|
|
92
|
+
alignItems: "center",
|
|
93
|
+
justifyContent: "center",
|
|
94
|
+
gap: 8
|
|
95
|
+
}, SHADOW),
|
|
96
|
+
circle: {
|
|
97
|
+
width: 56,
|
|
98
|
+
height: 56,
|
|
99
|
+
borderRadius: 28
|
|
100
|
+
},
|
|
101
|
+
extended: {
|
|
102
|
+
height: 56,
|
|
103
|
+
borderRadius: 28,
|
|
104
|
+
paddingHorizontal: 20
|
|
105
|
+
},
|
|
106
|
+
label: { fontSize: 16, fontWeight: "600" }
|
|
107
|
+
});
|
|
108
|
+
export {
|
|
109
|
+
FAB,
|
|
110
|
+
FABProvider,
|
|
111
|
+
useFAB
|
|
112
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
type FilterChipProps = {
|
|
4
|
+
label: string;
|
|
5
|
+
active: boolean;
|
|
6
|
+
onPress: () => void;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
};
|
|
9
|
+
declare function FilterChip({ label, active, onPress, disabled }: FilterChipProps): react.JSX.Element;
|
|
10
|
+
type FilterChipItem<T extends string> = {
|
|
11
|
+
label: string;
|
|
12
|
+
value: T;
|
|
13
|
+
};
|
|
14
|
+
type FilterChipGroupProps<T extends string> = {
|
|
15
|
+
items: FilterChipItem<T>[];
|
|
16
|
+
value: T;
|
|
17
|
+
onChange: (value: T) => void;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
};
|
|
20
|
+
declare function FilterChipGroup<T extends string>({ items, value, onChange, disabled, }: FilterChipGroupProps<T>): react.JSX.Element;
|
|
21
|
+
|
|
22
|
+
export { FilterChip, FilterChipGroup };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import "../../../chunk-ORMEWXMH.js";
|
|
2
|
+
import { Pressable, StyleSheet, View } from "react-native";
|
|
3
|
+
import { Text } from "./text.js";
|
|
4
|
+
import { useTheme } from "./theme.js";
|
|
5
|
+
function FilterChip({ label, active, onPress, disabled = false }) {
|
|
6
|
+
const t = useTheme();
|
|
7
|
+
const bg = active ? t["--brand-primary"] : t["--surface-default"];
|
|
8
|
+
const fg = active ? t["--brand-on-primary"] : t["--text-primary"];
|
|
9
|
+
const border = active ? t["--brand-primary"] : t["--border-default"];
|
|
10
|
+
return /* @__PURE__ */ React.createElement(
|
|
11
|
+
Pressable,
|
|
12
|
+
{
|
|
13
|
+
onPress: disabled ? void 0 : onPress,
|
|
14
|
+
disabled,
|
|
15
|
+
hitSlop: 8,
|
|
16
|
+
accessibilityRole: "button",
|
|
17
|
+
accessibilityLabel: label,
|
|
18
|
+
accessibilityState: { selected: active, disabled: !!disabled },
|
|
19
|
+
style: ({ pressed }) => [
|
|
20
|
+
styles.chip,
|
|
21
|
+
{
|
|
22
|
+
backgroundColor: bg,
|
|
23
|
+
borderColor: border,
|
|
24
|
+
opacity: disabled ? 0.5 : pressed ? 0.85 : 1
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
/* @__PURE__ */ React.createElement(Text, { variant: "caption", style: [styles.label, { color: fg }] }, label)
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
function FilterChipGroup({
|
|
32
|
+
items,
|
|
33
|
+
value,
|
|
34
|
+
onChange,
|
|
35
|
+
disabled = false
|
|
36
|
+
}) {
|
|
37
|
+
return /* @__PURE__ */ React.createElement(View, { style: styles.group }, items.map((item) => /* @__PURE__ */ React.createElement(
|
|
38
|
+
FilterChip,
|
|
39
|
+
{
|
|
40
|
+
key: item.value,
|
|
41
|
+
label: item.label,
|
|
42
|
+
active: item.value === value,
|
|
43
|
+
onPress: () => onChange(item.value),
|
|
44
|
+
disabled
|
|
45
|
+
}
|
|
46
|
+
)));
|
|
47
|
+
}
|
|
48
|
+
const styles = StyleSheet.create({
|
|
49
|
+
chip: {
|
|
50
|
+
minHeight: 32,
|
|
51
|
+
paddingHorizontal: 12,
|
|
52
|
+
borderRadius: 999,
|
|
53
|
+
borderWidth: 1,
|
|
54
|
+
alignItems: "center",
|
|
55
|
+
justifyContent: "center",
|
|
56
|
+
alignSelf: "flex-start"
|
|
57
|
+
},
|
|
58
|
+
label: {
|
|
59
|
+
fontWeight: "500"
|
|
60
|
+
},
|
|
61
|
+
group: {
|
|
62
|
+
flexDirection: "row",
|
|
63
|
+
flexWrap: "wrap",
|
|
64
|
+
gap: 8
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
export {
|
|
68
|
+
FilterChip,
|
|
69
|
+
FilterChipGroup
|
|
70
|
+
};
|