@retray-dev/ui-kit 9.0.0 → 9.2.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/COMPONENTS.md +178 -7
- package/CONSUMER.md +247 -0
- package/DESIGN.md +668 -0
- package/EXAMPLES.md +19 -12
- package/FONTS.md +107 -0
- package/README.md +3 -3
- package/dist/AlertBanner.d.mts +3 -1
- package/dist/AlertBanner.d.ts +3 -1
- package/dist/AlertBanner.js +18 -2
- package/dist/AlertBanner.mjs +1 -1
- package/dist/ConfirmDialog.d.mts +3 -1
- package/dist/ConfirmDialog.d.ts +3 -1
- package/dist/ConfirmDialog.js +3 -0
- package/dist/ConfirmDialog.mjs +1 -1
- package/dist/CurrencyInput.d.mts +3 -1
- package/dist/CurrencyInput.d.ts +3 -1
- package/dist/CurrencyInput.js +31 -4
- package/dist/CurrencyInput.mjs +2 -2
- package/dist/ImageUpload.d.mts +27 -0
- package/dist/ImageUpload.d.ts +27 -0
- package/dist/ImageUpload.js +399 -0
- package/dist/ImageUpload.mjs +9 -0
- package/dist/Input.d.mts +3 -1
- package/dist/Input.d.ts +3 -1
- package/dist/Input.js +27 -2
- package/dist/Input.mjs +1 -1
- package/dist/ListItem.d.mts +3 -1
- package/dist/ListItem.d.ts +3 -1
- package/dist/ListItem.js +2 -1
- package/dist/ListItem.mjs +1 -1
- package/dist/SheetSelect.d.mts +25 -0
- package/dist/SheetSelect.d.ts +25 -0
- package/dist/SheetSelect.js +440 -0
- package/dist/SheetSelect.mjs +9 -0
- package/dist/{chunk-M6ZXVBTK.mjs → chunk-6MKGPAR2.mjs} +21 -5
- package/dist/{chunk-7QHVVCB3.mjs → chunk-FZZLPJ6B.mjs} +3 -0
- package/dist/{chunk-MAC465BB.mjs → chunk-KNSENOV4.mjs} +5 -3
- package/dist/{chunk-756RAKE4.mjs → chunk-LVYEU5ZK.mjs} +27 -2
- package/dist/{chunk-BNP626TY.mjs → chunk-T4I5WVHA.mjs} +2 -1
- package/dist/chunk-URI2WBIV.mjs +147 -0
- package/dist/chunk-Y4GL2MHX.mjs +112 -0
- package/dist/index.d.mts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +327 -8
- package/dist/index.mjs +51 -12
- package/package.json +18 -5
- package/src/components/AlertBanner/AlertBanner.tsx +21 -3
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +5 -0
- package/src/components/CurrencyInput/CurrencyInput.tsx +4 -0
- package/src/components/ImageUpload/ImageUpload.tsx +158 -0
- package/src/components/ImageUpload/index.ts +1 -0
- package/src/components/Input/Input.tsx +51 -23
- package/src/components/ListItem/ListItem.tsx +4 -1
- package/src/components/SheetSelect/SheetSelect.tsx +192 -0
- package/src/components/SheetSelect/index.ts +1 -0
- package/src/hooks/useConfirmDialog.ts +67 -0
- package/src/index.ts +6 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React3 = require('react');
|
|
4
|
+
var reactNative = require('react-native');
|
|
5
|
+
var vectorIcons = require('@expo/vector-icons');
|
|
6
|
+
var reactNativeSizeMatters = require('react-native-size-matters');
|
|
7
|
+
var pressto = require('pressto');
|
|
8
|
+
var reactNativeReanimated = require('react-native-reanimated');
|
|
9
|
+
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var React3__default = /*#__PURE__*/_interopDefault(React3);
|
|
13
|
+
|
|
14
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
15
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
16
|
+
}) : x)(function(x) {
|
|
17
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
18
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
19
|
+
});
|
|
20
|
+
var _haptics = null;
|
|
21
|
+
var _hapticsLoaded = false;
|
|
22
|
+
async function getHaptics() {
|
|
23
|
+
if (reactNative.Platform.OS === "web") return null;
|
|
24
|
+
if (!_hapticsLoaded) {
|
|
25
|
+
_hapticsLoaded = true;
|
|
26
|
+
try {
|
|
27
|
+
_haptics = await import('expo-haptics');
|
|
28
|
+
} catch {
|
|
29
|
+
_haptics = null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return _haptics;
|
|
33
|
+
}
|
|
34
|
+
var _pulsar = null;
|
|
35
|
+
var _pulsarChecked = false;
|
|
36
|
+
var _pulsarAvailable = false;
|
|
37
|
+
function isPulsarNativeRegistered() {
|
|
38
|
+
try {
|
|
39
|
+
const g = globalThis;
|
|
40
|
+
if (typeof g.__turboModuleProxy === "function") {
|
|
41
|
+
return g.__turboModuleProxy("RNPulsar") != null;
|
|
42
|
+
}
|
|
43
|
+
return reactNative.NativeModules?.RNPulsar != null;
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function getPulsar() {
|
|
49
|
+
if (reactNative.Platform.OS === "web") return null;
|
|
50
|
+
if (!_pulsarChecked) {
|
|
51
|
+
_pulsarChecked = true;
|
|
52
|
+
try {
|
|
53
|
+
if (isPulsarNativeRegistered()) {
|
|
54
|
+
_pulsar = __require("react-native-pulsar");
|
|
55
|
+
_pulsarAvailable = true;
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
_pulsar = null;
|
|
59
|
+
_pulsarAvailable = false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return _pulsarAvailable ? _pulsar : null;
|
|
63
|
+
}
|
|
64
|
+
function impactLight() {
|
|
65
|
+
if (reactNative.Platform.OS === "web") return;
|
|
66
|
+
getHaptics().then((h) => {
|
|
67
|
+
if (h) {
|
|
68
|
+
h.impactAsync(h.ImpactFeedbackStyle.Light);
|
|
69
|
+
} else {
|
|
70
|
+
getPulsar()?.Presets.System.impactLight();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/theme/colorUtils.ts
|
|
76
|
+
function hexToRgb(hex) {
|
|
77
|
+
const clean = hex.replace("#", "");
|
|
78
|
+
const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
|
|
79
|
+
if (full.length !== 6) return null;
|
|
80
|
+
return {
|
|
81
|
+
r: parseInt(full.slice(0, 2), 16),
|
|
82
|
+
g: parseInt(full.slice(2, 4), 16),
|
|
83
|
+
b: parseInt(full.slice(4, 6), 16)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function componentToHex(c) {
|
|
87
|
+
return Math.round(Math.max(0, Math.min(255, c))).toString(16).padStart(2, "0");
|
|
88
|
+
}
|
|
89
|
+
function rgbToHex(r, g, b) {
|
|
90
|
+
return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
|
|
91
|
+
}
|
|
92
|
+
function withAlphaOnWhite(hex, alpha) {
|
|
93
|
+
const rgb = hexToRgb(hex);
|
|
94
|
+
if (!rgb) return hex;
|
|
95
|
+
const r = rgb.r * alpha + 255 * (1 - alpha);
|
|
96
|
+
const g = rgb.g * alpha + 255 * (1 - alpha);
|
|
97
|
+
const b = rgb.b * alpha + 255 * (1 - alpha);
|
|
98
|
+
return rgbToHex(r, g, b);
|
|
99
|
+
}
|
|
100
|
+
function withAlphaOnDark(hex, alpha, bgHex = "#0f0f0f") {
|
|
101
|
+
const rgb = hexToRgb(hex);
|
|
102
|
+
const bg = hexToRgb(bgHex);
|
|
103
|
+
if (!rgb || !bg) return hex;
|
|
104
|
+
const r = rgb.r * alpha + bg.r * (1 - alpha);
|
|
105
|
+
const g = rgb.g * alpha + bg.g * (1 - alpha);
|
|
106
|
+
const b = rgb.b * alpha + bg.b * (1 - alpha);
|
|
107
|
+
return rgbToHex(r, g, b);
|
|
108
|
+
}
|
|
109
|
+
function mixWithBackground(fgHex, bgHex, opacity) {
|
|
110
|
+
const fg = hexToRgb(fgHex);
|
|
111
|
+
const bg = hexToRgb(bgHex);
|
|
112
|
+
if (!fg || !bg) return fgHex;
|
|
113
|
+
const r = fg.r * opacity + bg.r * (1 - opacity);
|
|
114
|
+
const g = fg.g * opacity + bg.g * (1 - opacity);
|
|
115
|
+
const b = fg.b * opacity + bg.b * (1 - opacity);
|
|
116
|
+
return rgbToHex(r, g, b);
|
|
117
|
+
}
|
|
118
|
+
function lighten(hex, amount) {
|
|
119
|
+
return withAlphaOnWhite(hex, 1 - amount);
|
|
120
|
+
}
|
|
121
|
+
function darken(hex, amount) {
|
|
122
|
+
const rgb = hexToRgb(hex);
|
|
123
|
+
if (!rgb) return hex;
|
|
124
|
+
return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/theme/colors.ts
|
|
128
|
+
var defaultLight = {
|
|
129
|
+
background: "#ffffff",
|
|
130
|
+
foreground: "#1a1a1a",
|
|
131
|
+
card: "#ffffff",
|
|
132
|
+
primary: "#1a1a1a",
|
|
133
|
+
primaryForeground: "#ffffff",
|
|
134
|
+
// AUDIT FIX: brand accent — was undefined; falls back to primary when omitted
|
|
135
|
+
accent: "#d4561d",
|
|
136
|
+
accentForeground: "#ffffff",
|
|
137
|
+
border: "#dddddd",
|
|
138
|
+
// AUDIT FIX: was #e53935 (4.22:1 on white — fails AA); #c72828 = 5.59:1 ✓
|
|
139
|
+
destructive: "#c72828",
|
|
140
|
+
destructiveForeground: "#ffffff",
|
|
141
|
+
success: "#1a7a45",
|
|
142
|
+
successForeground: "#ffffff",
|
|
143
|
+
// AUDIT FIX: was #e67e00 (2.86:1 — severe fail); #9a5200 = 5.86:1 ✓ AAA-near
|
|
144
|
+
warning: "#9a5200",
|
|
145
|
+
warningForeground: "#ffffff"
|
|
146
|
+
};
|
|
147
|
+
function deriveColors(t, scheme) {
|
|
148
|
+
const dark = scheme === "dark";
|
|
149
|
+
const bg = t.background;
|
|
150
|
+
const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.7);
|
|
151
|
+
const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62);
|
|
152
|
+
const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
|
|
153
|
+
const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
|
|
154
|
+
const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
|
|
155
|
+
const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
|
|
156
|
+
const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
|
|
157
|
+
const successBorder = dark ? withAlphaOnDark(t.success, 0.45, bg) : withAlphaOnWhite(t.success, 0.3);
|
|
158
|
+
const warningTint = dark ? withAlphaOnDark(t.warning, 0.15, bg) : withAlphaOnWhite(t.warning, 0.08);
|
|
159
|
+
const warningBorder = dark ? withAlphaOnDark(t.warning, 0.45, bg) : withAlphaOnWhite(t.warning, 0.3);
|
|
160
|
+
return {
|
|
161
|
+
...t,
|
|
162
|
+
foregroundSubtle,
|
|
163
|
+
foregroundMuted,
|
|
164
|
+
surface,
|
|
165
|
+
surfaceStrong,
|
|
166
|
+
destructiveTint,
|
|
167
|
+
destructiveBorder,
|
|
168
|
+
successTint,
|
|
169
|
+
successBorder,
|
|
170
|
+
warningTint,
|
|
171
|
+
warningBorder,
|
|
172
|
+
overlay: t.overlay ?? "rgba(0,0,0,0.45)",
|
|
173
|
+
accentResolved: t.accent ?? t.primary,
|
|
174
|
+
accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
|
|
175
|
+
ring: t.accent ?? t.primary,
|
|
176
|
+
input: t.border,
|
|
177
|
+
separator: dark ? lighten(t.border, 0.22) : darken(t.border, 0.16)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/theme/ThemeProvider.tsx
|
|
182
|
+
var ThemeContext = React3.createContext({
|
|
183
|
+
colors: deriveColors(defaultLight, "light"),
|
|
184
|
+
colorScheme: "light"
|
|
185
|
+
});
|
|
186
|
+
function useTheme() {
|
|
187
|
+
const context = React3.useContext(ThemeContext);
|
|
188
|
+
if (!context) {
|
|
189
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
190
|
+
}
|
|
191
|
+
return context;
|
|
192
|
+
}
|
|
193
|
+
var isWeb = reactNative.Platform.OS === "web";
|
|
194
|
+
var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
|
|
195
|
+
var vs = isWeb ? (n) => n : reactNativeSizeMatters.verticalScale;
|
|
196
|
+
var ms = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateScale;
|
|
197
|
+
var mvs = isWeb ? (n, _factor) => n : reactNativeSizeMatters.moderateVerticalScale;
|
|
198
|
+
|
|
199
|
+
// src/tokens.ts
|
|
200
|
+
var RADIUS = {
|
|
201
|
+
lg: 20};
|
|
202
|
+
var sizeMap = {
|
|
203
|
+
sm: "small",
|
|
204
|
+
md: "small",
|
|
205
|
+
lg: "large"
|
|
206
|
+
};
|
|
207
|
+
var labelFontSize = {
|
|
208
|
+
sm: ms(11),
|
|
209
|
+
md: ms(13),
|
|
210
|
+
lg: ms(14)
|
|
211
|
+
};
|
|
212
|
+
function Spinner({ size = "md", color, label, ...props }) {
|
|
213
|
+
const { colors } = useTheme();
|
|
214
|
+
const a11yLabel = label || "Loading";
|
|
215
|
+
if (label) {
|
|
216
|
+
return /* @__PURE__ */ React3__default.default.createElement(
|
|
217
|
+
reactNative.View,
|
|
218
|
+
{
|
|
219
|
+
style: styles.wrapper,
|
|
220
|
+
accessibilityRole: "progressbar",
|
|
221
|
+
accessibilityLabel: a11yLabel,
|
|
222
|
+
accessibilityState: { busy: true }
|
|
223
|
+
},
|
|
224
|
+
/* @__PURE__ */ React3__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap[size], color: color ?? colors.primary, ...props }),
|
|
225
|
+
/* @__PURE__ */ React3__default.default.createElement(
|
|
226
|
+
reactNative.Text,
|
|
227
|
+
{
|
|
228
|
+
style: [styles.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
|
|
229
|
+
allowFontScaling: true
|
|
230
|
+
},
|
|
231
|
+
label
|
|
232
|
+
)
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
return /* @__PURE__ */ React3__default.default.createElement(
|
|
236
|
+
reactNative.ActivityIndicator,
|
|
237
|
+
{
|
|
238
|
+
size: sizeMap[size],
|
|
239
|
+
color: color ?? colors.primary,
|
|
240
|
+
accessibilityRole: "progressbar",
|
|
241
|
+
accessibilityLabel: a11yLabel,
|
|
242
|
+
accessibilityState: { busy: true },
|
|
243
|
+
...props
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
var styles = reactNative.StyleSheet.create({
|
|
248
|
+
wrapper: {
|
|
249
|
+
alignItems: "center",
|
|
250
|
+
gap: vs(6)
|
|
251
|
+
},
|
|
252
|
+
label: {
|
|
253
|
+
fontFamily: "Sohne-Regular",
|
|
254
|
+
lineHeight: mvs(18)
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
({
|
|
258
|
+
/** Material-style ease-out — natural deceleration for state changes. */
|
|
259
|
+
standard: reactNativeReanimated.Easing.bezier(0.2, 0, 0, 1),
|
|
260
|
+
/** Strong ease-out for expanding surfaces (Accordion open). */
|
|
261
|
+
expand: reactNativeReanimated.Easing.bezier(0.23, 1, 0.32, 1),
|
|
262
|
+
/** Quick ease-in for collapsing. */
|
|
263
|
+
collapse: reactNativeReanimated.Easing.in(reactNativeReanimated.Easing.ease)
|
|
264
|
+
});
|
|
265
|
+
var PRESS_SCALE = {
|
|
266
|
+
button: 0.95,
|
|
267
|
+
card: 0.98,
|
|
268
|
+
row: 0.97,
|
|
269
|
+
chip: 0.94
|
|
270
|
+
};
|
|
271
|
+
pressto.createAnimatedPressable((progress) => {
|
|
272
|
+
"worklet";
|
|
273
|
+
const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
|
|
274
|
+
return { transform: [{ scale: scale2 }] };
|
|
275
|
+
});
|
|
276
|
+
var PressableCard = pressto.createAnimatedPressable((progress) => {
|
|
277
|
+
"worklet";
|
|
278
|
+
const scale2 = 1 - (1 - PRESS_SCALE.card) * progress;
|
|
279
|
+
return { transform: [{ scale: scale2 }] };
|
|
280
|
+
});
|
|
281
|
+
pressto.createAnimatedPressable((progress) => {
|
|
282
|
+
"worklet";
|
|
283
|
+
const scale2 = 1 - (1 - PRESS_SCALE.row) * progress;
|
|
284
|
+
return { transform: [{ scale: scale2 }] };
|
|
285
|
+
});
|
|
286
|
+
pressto.createAnimatedPressable((progress) => {
|
|
287
|
+
"worklet";
|
|
288
|
+
const scale2 = 1 - (1 - PRESS_SCALE.chip) * progress;
|
|
289
|
+
return { transform: [{ scale: scale2 }] };
|
|
290
|
+
});
|
|
291
|
+
pressto.createAnimatedPressable((progress) => {
|
|
292
|
+
"worklet";
|
|
293
|
+
const scale2 = 1 - (1 - PRESS_SCALE.button) * progress;
|
|
294
|
+
return { transform: [{ scale: scale2 }] };
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// src/components/ImageUpload/ImageUpload.tsx
|
|
298
|
+
function ImageUpload({
|
|
299
|
+
value,
|
|
300
|
+
onChange,
|
|
301
|
+
loading = false,
|
|
302
|
+
placeholder = "Tap to add image",
|
|
303
|
+
width,
|
|
304
|
+
height = 200,
|
|
305
|
+
borderRadius = RADIUS.lg,
|
|
306
|
+
resizeMode = "cover",
|
|
307
|
+
disabled = false,
|
|
308
|
+
style,
|
|
309
|
+
accessibilityLabel
|
|
310
|
+
}) {
|
|
311
|
+
const { colors } = useTheme();
|
|
312
|
+
const handlePress = async () => {
|
|
313
|
+
if (disabled || loading) return;
|
|
314
|
+
impactLight();
|
|
315
|
+
let ImagePicker;
|
|
316
|
+
try {
|
|
317
|
+
ImagePicker = await import('expo-image-picker');
|
|
318
|
+
} catch {
|
|
319
|
+
if (__DEV__) console.warn("[ImageUpload] expo-image-picker not installed. Add it as a dependency.");
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
if (reactNative.Platform.OS !== "web") {
|
|
323
|
+
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
|
324
|
+
if (status !== "granted") return;
|
|
325
|
+
}
|
|
326
|
+
const result = await ImagePicker.launchImageLibraryAsync({
|
|
327
|
+
mediaTypes: ["images"],
|
|
328
|
+
allowsEditing: true,
|
|
329
|
+
quality: 0.8
|
|
330
|
+
});
|
|
331
|
+
if (!result.canceled && result.assets[0]) {
|
|
332
|
+
onChange?.(result.assets[0].uri);
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
const containerStyle = {
|
|
336
|
+
width,
|
|
337
|
+
height,
|
|
338
|
+
borderRadius,
|
|
339
|
+
borderWidth: value ? 0 : 1,
|
|
340
|
+
borderStyle: "dashed",
|
|
341
|
+
borderColor: colors.border,
|
|
342
|
+
backgroundColor: value ? "transparent" : colors.surface,
|
|
343
|
+
overflow: "hidden"
|
|
344
|
+
};
|
|
345
|
+
return /* @__PURE__ */ React3__default.default.createElement(
|
|
346
|
+
PressableCard,
|
|
347
|
+
{
|
|
348
|
+
onPress: handlePress,
|
|
349
|
+
enabled: !disabled && !loading,
|
|
350
|
+
rippleColor: "transparent",
|
|
351
|
+
touchSoundDisabled: true,
|
|
352
|
+
accessibilityRole: "button",
|
|
353
|
+
accessibilityLabel: accessibilityLabel ?? (value ? "Change image" : placeholder),
|
|
354
|
+
accessibilityState: { disabled: disabled || loading },
|
|
355
|
+
style: [containerStyle, style]
|
|
356
|
+
},
|
|
357
|
+
value ? /* @__PURE__ */ React3__default.default.createElement(
|
|
358
|
+
reactNative.Image,
|
|
359
|
+
{
|
|
360
|
+
source: { uri: value },
|
|
361
|
+
style: [reactNative.StyleSheet.absoluteFillObject, { borderRadius }],
|
|
362
|
+
resizeMode
|
|
363
|
+
}
|
|
364
|
+
) : /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: styles2.placeholder }, /* @__PURE__ */ React3__default.default.createElement(vectorIcons.Feather, { name: "image", size: ms(28), color: colors.foregroundMuted }), /* @__PURE__ */ React3__default.default.createElement(reactNative.Text, { style: [styles2.placeholderText, { color: colors.foregroundMuted }], allowFontScaling: true }, placeholder)),
|
|
365
|
+
loading ? /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: [styles2.loadingOverlay, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React3__default.default.createElement(Spinner, { size: "md" })) : null,
|
|
366
|
+
value && !loading ? /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: styles2.editBadge, pointerEvents: "none" }, /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: [styles2.editBadgeInner, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React3__default.default.createElement(vectorIcons.Feather, { name: "edit-2", size: ms(12), color: "#fff" }))) : null
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
var styles2 = reactNative.StyleSheet.create({
|
|
370
|
+
placeholder: {
|
|
371
|
+
flex: 1,
|
|
372
|
+
alignItems: "center",
|
|
373
|
+
justifyContent: "center",
|
|
374
|
+
gap: vs(8)
|
|
375
|
+
},
|
|
376
|
+
placeholderText: {
|
|
377
|
+
fontFamily: "Sohne-Regular",
|
|
378
|
+
fontSize: ms(13)
|
|
379
|
+
},
|
|
380
|
+
loadingOverlay: {
|
|
381
|
+
...reactNative.StyleSheet.absoluteFillObject,
|
|
382
|
+
alignItems: "center",
|
|
383
|
+
justifyContent: "center"
|
|
384
|
+
},
|
|
385
|
+
editBadge: {
|
|
386
|
+
position: "absolute",
|
|
387
|
+
bottom: vs(8),
|
|
388
|
+
right: s(8)
|
|
389
|
+
},
|
|
390
|
+
editBadgeInner: {
|
|
391
|
+
width: s(28),
|
|
392
|
+
height: s(28),
|
|
393
|
+
borderRadius: 999,
|
|
394
|
+
alignItems: "center",
|
|
395
|
+
justifyContent: "center"
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
exports.ImageUpload = ImageUpload;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ImageUpload } from './chunk-Y4GL2MHX.mjs';
|
|
2
|
+
import './chunk-WBOOUHSS.mjs';
|
|
3
|
+
import './chunk-3DKJ2GIC.mjs';
|
|
4
|
+
import './chunk-EJ7ZPXOH.mjs';
|
|
5
|
+
import './chunk-DVK4G2GT.mjs';
|
|
6
|
+
import './chunk-QY3X2UYR.mjs';
|
|
7
|
+
import './chunk-SOYNZDVY.mjs';
|
|
8
|
+
import './chunk-2CE3TQVY.mjs';
|
|
9
|
+
import './chunk-Y6FXYEAI.mjs';
|
package/dist/Input.d.mts
CHANGED
|
@@ -17,7 +17,9 @@ interface InputProps extends TextInputProps {
|
|
|
17
17
|
type?: 'text' | 'password';
|
|
18
18
|
containerStyle?: ViewStyle;
|
|
19
19
|
inputWrapperStyle?: ViewStyle;
|
|
20
|
+
/** Use inside a Sheet/BottomSheet — swaps TextInput for BottomSheetTextInput to fix keyboard handling. */
|
|
21
|
+
sheetMode?: boolean;
|
|
20
22
|
}
|
|
21
|
-
declare function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type, containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }: InputProps): React.JSX.Element;
|
|
23
|
+
declare function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type, containerStyle, inputWrapperStyle, sheetMode, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }: InputProps): React.JSX.Element;
|
|
22
24
|
|
|
23
25
|
export { Input, type InputProps };
|
package/dist/Input.d.ts
CHANGED
|
@@ -17,7 +17,9 @@ interface InputProps extends TextInputProps {
|
|
|
17
17
|
type?: 'text' | 'password';
|
|
18
18
|
containerStyle?: ViewStyle;
|
|
19
19
|
inputWrapperStyle?: ViewStyle;
|
|
20
|
+
/** Use inside a Sheet/BottomSheet — swaps TextInput for BottomSheetTextInput to fix keyboard handling. */
|
|
21
|
+
sheetMode?: boolean;
|
|
20
22
|
}
|
|
21
|
-
declare function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type, containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }: InputProps): React.JSX.Element;
|
|
23
|
+
declare function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type, containerStyle, inputWrapperStyle, sheetMode, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }: InputProps): React.JSX.Element;
|
|
22
24
|
|
|
23
25
|
export { Input, type InputProps };
|
package/dist/Input.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var React3 = require('react');
|
|
4
4
|
var reactNative = require('react-native');
|
|
5
|
+
var bottomSheet = require('@gorhom/bottom-sheet');
|
|
5
6
|
var Animated = require('react-native-reanimated');
|
|
6
7
|
var vectorIcons = require('@expo/vector-icons');
|
|
7
8
|
var reactNativeSizeMatters = require('react-native-size-matters');
|
|
@@ -215,7 +216,7 @@ function useColorTransition(active, options = {}) {
|
|
|
215
216
|
|
|
216
217
|
// src/components/Input/Input.tsx
|
|
217
218
|
var webInputResetStyle = reactNative.Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
|
|
218
|
-
function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }) {
|
|
219
|
+
function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, sheetMode = false, style, onFocus, onBlur, secureTextEntry, editable, accessibilityLabel, ...props }) {
|
|
219
220
|
const { colors } = useTheme();
|
|
220
221
|
const [focused, setFocused] = React3.useState(false);
|
|
221
222
|
const [showPassword, setShowPassword] = React3.useState(false);
|
|
@@ -252,7 +253,31 @@ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suff
|
|
|
252
253
|
},
|
|
253
254
|
/* @__PURE__ */ React3__default.default.createElement(Animated__default.default.View, { style: [styles.borderOverlay, borderAnimStyle], pointerEvents: "none" }),
|
|
254
255
|
effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React3__default.default.createElement(reactNative.Text, { style: [styles.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React3__default.default.createElement(reactNative.View, { style: styles.prefixContainer }, effectivePrefix) : null,
|
|
255
|
-
/* @__PURE__ */ React3__default.default.createElement(
|
|
256
|
+
sheetMode ? /* @__PURE__ */ React3__default.default.createElement(
|
|
257
|
+
bottomSheet.BottomSheetTextInput,
|
|
258
|
+
{
|
|
259
|
+
style: [
|
|
260
|
+
styles.input,
|
|
261
|
+
{ color: colors.foreground },
|
|
262
|
+
webInputResetStyle,
|
|
263
|
+
style
|
|
264
|
+
],
|
|
265
|
+
onFocus: (e) => {
|
|
266
|
+
setFocused(true);
|
|
267
|
+
onFocus?.(e);
|
|
268
|
+
},
|
|
269
|
+
onBlur: (e) => {
|
|
270
|
+
setFocused(false);
|
|
271
|
+
onBlur?.(e);
|
|
272
|
+
},
|
|
273
|
+
placeholderTextColor: colors.foregroundMuted,
|
|
274
|
+
allowFontScaling: true,
|
|
275
|
+
secureTextEntry: effectiveSecure,
|
|
276
|
+
editable: isDisabled ? false : editable,
|
|
277
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
278
|
+
...props
|
|
279
|
+
}
|
|
280
|
+
) : /* @__PURE__ */ React3__default.default.createElement(
|
|
256
281
|
reactNative.TextInput,
|
|
257
282
|
{
|
|
258
283
|
style: [
|
package/dist/Input.mjs
CHANGED
package/dist/ListItem.d.mts
CHANGED
|
@@ -53,12 +53,14 @@ interface ListItemProps {
|
|
|
53
53
|
titleStyle?: TextStyle;
|
|
54
54
|
/** Style applied to the subtitle Text. */
|
|
55
55
|
subtitleStyle?: TextStyle;
|
|
56
|
+
/** Max lines for the subtitle. Defaults to 2. */
|
|
57
|
+
subtitleNumberOfLines?: number;
|
|
56
58
|
/** Style applied to the caption Text. */
|
|
57
59
|
captionStyle?: TextStyle;
|
|
58
60
|
/** Accessibility label override. Defaults to the title. */
|
|
59
61
|
accessibilityLabel?: string;
|
|
60
62
|
}
|
|
61
|
-
declare function ListItemBase({ leftRender, rightRender, trailing, icon, leftIcon, rightIcon, leftIconColor, rightIconColor, title, subtitle, caption, variant, showChevron, showSeparator, onPress, disabled, style, titleStyle, subtitleStyle, captionStyle, accessibilityLabel, }: ListItemProps): React.JSX.Element;
|
|
63
|
+
declare function ListItemBase({ leftRender, rightRender, trailing, icon, leftIcon, rightIcon, leftIconColor, rightIconColor, title, subtitle, caption, variant, showChevron, showSeparator, onPress, disabled, style, titleStyle, subtitleStyle, subtitleNumberOfLines, captionStyle, accessibilityLabel, }: ListItemProps): React.JSX.Element;
|
|
62
64
|
declare const ListItem: React.MemoExoticComponent<typeof ListItemBase>;
|
|
63
65
|
|
|
64
66
|
export { ListItem, type ListItemProps };
|
package/dist/ListItem.d.ts
CHANGED
|
@@ -53,12 +53,14 @@ interface ListItemProps {
|
|
|
53
53
|
titleStyle?: TextStyle;
|
|
54
54
|
/** Style applied to the subtitle Text. */
|
|
55
55
|
subtitleStyle?: TextStyle;
|
|
56
|
+
/** Max lines for the subtitle. Defaults to 2. */
|
|
57
|
+
subtitleNumberOfLines?: number;
|
|
56
58
|
/** Style applied to the caption Text. */
|
|
57
59
|
captionStyle?: TextStyle;
|
|
58
60
|
/** Accessibility label override. Defaults to the title. */
|
|
59
61
|
accessibilityLabel?: string;
|
|
60
62
|
}
|
|
61
|
-
declare function ListItemBase({ leftRender, rightRender, trailing, icon, leftIcon, rightIcon, leftIconColor, rightIconColor, title, subtitle, caption, variant, showChevron, showSeparator, onPress, disabled, style, titleStyle, subtitleStyle, captionStyle, accessibilityLabel, }: ListItemProps): React.JSX.Element;
|
|
63
|
+
declare function ListItemBase({ leftRender, rightRender, trailing, icon, leftIcon, rightIcon, leftIconColor, rightIconColor, title, subtitle, caption, variant, showChevron, showSeparator, onPress, disabled, style, titleStyle, subtitleStyle, subtitleNumberOfLines, captionStyle, accessibilityLabel, }: ListItemProps): React.JSX.Element;
|
|
62
64
|
declare const ListItem: React.MemoExoticComponent<typeof ListItemBase>;
|
|
63
65
|
|
|
64
66
|
export { ListItem, type ListItemProps };
|
package/dist/ListItem.js
CHANGED
|
@@ -313,6 +313,7 @@ function ListItemBase({
|
|
|
313
313
|
style,
|
|
314
314
|
titleStyle,
|
|
315
315
|
subtitleStyle,
|
|
316
|
+
subtitleNumberOfLines = 2,
|
|
316
317
|
captionStyle,
|
|
317
318
|
accessibilityLabel
|
|
318
319
|
}) {
|
|
@@ -347,7 +348,7 @@ function ListItemBase({
|
|
|
347
348
|
reactNative.Text,
|
|
348
349
|
{
|
|
349
350
|
style: [styles.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
|
|
350
|
-
numberOfLines:
|
|
351
|
+
numberOfLines: subtitleNumberOfLines,
|
|
351
352
|
allowFontScaling: true
|
|
352
353
|
},
|
|
353
354
|
subtitle
|
package/dist/ListItem.mjs
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ViewStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
interface SheetSelectOption {
|
|
5
|
+
label: string;
|
|
6
|
+
value: string | number;
|
|
7
|
+
iconName?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface SheetSelectProps {
|
|
11
|
+
options: SheetSelectOption[];
|
|
12
|
+
value?: string | number | (string | number)[];
|
|
13
|
+
onValueChange?: (value: string | number | (string | number)[]) => void;
|
|
14
|
+
/** Allow multiple simultaneous selections. Defaults to false (radio). */
|
|
15
|
+
multiSelect?: boolean;
|
|
16
|
+
label?: string;
|
|
17
|
+
error?: string;
|
|
18
|
+
/** Wrap chips into multiple rows instead of a single horizontal scroll. Defaults to false. */
|
|
19
|
+
wrap?: boolean;
|
|
20
|
+
style?: ViewStyle;
|
|
21
|
+
accessibilityLabel?: string;
|
|
22
|
+
}
|
|
23
|
+
declare function SheetSelect({ options, value, onValueChange, multiSelect, label, error, wrap, style, accessibilityLabel, }: SheetSelectProps): React.JSX.Element;
|
|
24
|
+
|
|
25
|
+
export { SheetSelect, type SheetSelectOption, type SheetSelectProps };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ViewStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
interface SheetSelectOption {
|
|
5
|
+
label: string;
|
|
6
|
+
value: string | number;
|
|
7
|
+
iconName?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface SheetSelectProps {
|
|
11
|
+
options: SheetSelectOption[];
|
|
12
|
+
value?: string | number | (string | number)[];
|
|
13
|
+
onValueChange?: (value: string | number | (string | number)[]) => void;
|
|
14
|
+
/** Allow multiple simultaneous selections. Defaults to false (radio). */
|
|
15
|
+
multiSelect?: boolean;
|
|
16
|
+
label?: string;
|
|
17
|
+
error?: string;
|
|
18
|
+
/** Wrap chips into multiple rows instead of a single horizontal scroll. Defaults to false. */
|
|
19
|
+
wrap?: boolean;
|
|
20
|
+
style?: ViewStyle;
|
|
21
|
+
accessibilityLabel?: string;
|
|
22
|
+
}
|
|
23
|
+
declare function SheetSelect({ options, value, onValueChange, multiSelect, label, error, wrap, style, accessibilityLabel, }: SheetSelectProps): React.JSX.Element;
|
|
24
|
+
|
|
25
|
+
export { SheetSelect, type SheetSelectOption, type SheetSelectProps };
|