@onlynative/components 0.1.0-alpha.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.
Files changed (87) hide show
  1. package/README.md +99 -0
  2. package/dist/appbar/index.d.ts +71 -0
  3. package/dist/appbar/index.js +952 -0
  4. package/dist/button/index.d.ts +41 -0
  5. package/dist/button/index.js +454 -0
  6. package/dist/card/index.d.ts +31 -0
  7. package/dist/card/index.js +264 -0
  8. package/dist/checkbox/index.d.ts +25 -0
  9. package/dist/checkbox/index.js +291 -0
  10. package/dist/chip/index.d.ts +62 -0
  11. package/dist/chip/index.js +452 -0
  12. package/dist/icon-button/index.d.ts +10 -0
  13. package/dist/icon-button/index.js +575 -0
  14. package/dist/index.d.ts +19 -0
  15. package/dist/index.js +3374 -0
  16. package/dist/layout/index.d.ts +98 -0
  17. package/dist/layout/index.js +282 -0
  18. package/dist/list/index.d.ts +60 -0
  19. package/dist/list/index.js +300 -0
  20. package/dist/radio/index.d.ts +25 -0
  21. package/dist/radio/index.js +250 -0
  22. package/dist/switch/index.d.ts +37 -0
  23. package/dist/switch/index.js +315 -0
  24. package/dist/text-field/index.d.ts +52 -0
  25. package/dist/text-field/index.js +496 -0
  26. package/dist/types-D3hlyvz-.d.ts +51 -0
  27. package/dist/typography/index.d.ts +28 -0
  28. package/dist/typography/index.js +69 -0
  29. package/package.json +166 -0
  30. package/src/appbar/AppBar.tsx +302 -0
  31. package/src/appbar/index.ts +2 -0
  32. package/src/appbar/styles.ts +92 -0
  33. package/src/appbar/types.ts +67 -0
  34. package/src/button/Button.tsx +130 -0
  35. package/src/button/index.ts +2 -0
  36. package/src/button/styles.ts +288 -0
  37. package/src/button/types.ts +42 -0
  38. package/src/card/Card.tsx +69 -0
  39. package/src/card/index.ts +2 -0
  40. package/src/card/styles.ts +151 -0
  41. package/src/card/types.ts +27 -0
  42. package/src/checkbox/Checkbox.tsx +109 -0
  43. package/src/checkbox/index.ts +2 -0
  44. package/src/checkbox/styles.ts +155 -0
  45. package/src/checkbox/types.ts +20 -0
  46. package/src/chip/Chip.tsx +182 -0
  47. package/src/chip/index.ts +2 -0
  48. package/src/chip/styles.ts +240 -0
  49. package/src/chip/types.ts +58 -0
  50. package/src/icon-button/IconButton.tsx +358 -0
  51. package/src/icon-button/index.ts +6 -0
  52. package/src/icon-button/styles.ts +259 -0
  53. package/src/icon-button/types.ts +55 -0
  54. package/src/index.ts +51 -0
  55. package/src/layout/Box.tsx +99 -0
  56. package/src/layout/Column.tsx +16 -0
  57. package/src/layout/Grid.tsx +49 -0
  58. package/src/layout/Layout.tsx +81 -0
  59. package/src/layout/Row.tsx +22 -0
  60. package/src/layout/index.ts +13 -0
  61. package/src/layout/resolveSpacing.ts +11 -0
  62. package/src/layout/types.ts +82 -0
  63. package/src/list/List.tsx +17 -0
  64. package/src/list/ListDivider.tsx +20 -0
  65. package/src/list/ListItem.tsx +128 -0
  66. package/src/list/index.ts +9 -0
  67. package/src/list/styles.ts +132 -0
  68. package/src/list/types.ts +54 -0
  69. package/src/radio/Radio.tsx +103 -0
  70. package/src/radio/index.ts +2 -0
  71. package/src/radio/styles.ts +139 -0
  72. package/src/radio/types.ts +20 -0
  73. package/src/switch/Switch.tsx +118 -0
  74. package/src/switch/index.ts +2 -0
  75. package/src/switch/styles.ts +172 -0
  76. package/src/switch/types.ts +32 -0
  77. package/src/test-utils/render-with-theme.tsx +13 -0
  78. package/src/text-field/TextField.tsx +298 -0
  79. package/src/text-field/index.ts +2 -0
  80. package/src/text-field/styles.ts +240 -0
  81. package/src/text-field/types.ts +49 -0
  82. package/src/typography/Typography.tsx +65 -0
  83. package/src/typography/index.ts +3 -0
  84. package/src/typography/types.ts +17 -0
  85. package/src/utils/color.ts +64 -0
  86. package/src/utils/elevation.ts +33 -0
  87. package/src/utils/rtl.ts +19 -0
@@ -0,0 +1,496 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/text-field/index.ts
31
+ var text_field_exports = {};
32
+ __export(text_field_exports, {
33
+ TextField: () => TextField
34
+ });
35
+ module.exports = __toCommonJS(text_field_exports);
36
+
37
+ // src/text-field/TextField.tsx
38
+ var import_MaterialCommunityIcons = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
39
+ var import_react = require("react");
40
+ var import_react_native3 = require("react-native");
41
+ var import_core = require("@onlynative/core");
42
+
43
+ // src/text-field/styles.ts
44
+ var import_react_native2 = require("react-native");
45
+
46
+ // src/utils/color.ts
47
+ function parseHexColor(color) {
48
+ const normalized = color.replace("#", "");
49
+ if (normalized.length !== 6 && normalized.length !== 8) {
50
+ return null;
51
+ }
52
+ const r = Number.parseInt(normalized.slice(0, 2), 16);
53
+ const g = Number.parseInt(normalized.slice(2, 4), 16);
54
+ const b = Number.parseInt(normalized.slice(4, 6), 16);
55
+ if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) {
56
+ return null;
57
+ }
58
+ return { r, g, b };
59
+ }
60
+ function clampAlpha(alpha) {
61
+ return Math.max(0, Math.min(1, alpha));
62
+ }
63
+ function alphaColor(color, alpha) {
64
+ const channels = parseHexColor(color);
65
+ const boundedAlpha = clampAlpha(alpha);
66
+ if (!channels) {
67
+ return color;
68
+ }
69
+ return `rgba(${channels.r}, ${channels.g}, ${channels.b}, ${boundedAlpha})`;
70
+ }
71
+
72
+ // src/utils/rtl.ts
73
+ var import_react_native = require("react-native");
74
+ function transformOrigin(vertical = "top") {
75
+ return import_react_native.I18nManager.isRTL ? `right ${vertical}` : `left ${vertical}`;
76
+ }
77
+
78
+ // src/text-field/styles.ts
79
+ var CONTAINER_HEIGHT = 56;
80
+ var ICON_SIZE = 24;
81
+ var LABEL_FLOATED_LINE_HEIGHT = 16;
82
+ var FILLED_LABEL_RESTING_TOP = 16;
83
+ var FILLED_LABEL_FLOATED_TOP = 8;
84
+ var FILLED_INPUT_TOP = 24;
85
+ var FILLED_INPUT_BOTTOM = 8;
86
+ var OUTLINED_INPUT_VERTICAL = 16;
87
+ var OUTLINED_LABEL_RESTING_TOP = 16;
88
+ var OUTLINED_LABEL_FLOATED_TOP = -(LABEL_FLOATED_LINE_HEIGHT / 2);
89
+ var labelPositions = {
90
+ filledRestingTop: FILLED_LABEL_RESTING_TOP,
91
+ filledFloatedTop: FILLED_LABEL_FLOATED_TOP,
92
+ outlinedRestingTop: OUTLINED_LABEL_RESTING_TOP,
93
+ outlinedFloatedTop: OUTLINED_LABEL_FLOATED_TOP
94
+ };
95
+ function getVariantColors(theme, variant) {
96
+ const disabledOpacity = theme.stateLayer.disabledOpacity;
97
+ const common = {
98
+ focusedBorderColor: theme.colors.primary,
99
+ errorBorderColor: theme.colors.error,
100
+ focusedLabelColor: theme.colors.primary,
101
+ errorLabelColor: theme.colors.error,
102
+ textColor: theme.colors.onSurface,
103
+ disabledTextColor: alphaColor(theme.colors.onSurface, disabledOpacity),
104
+ disabledLabelColor: alphaColor(theme.colors.onSurface, disabledOpacity),
105
+ disabledBorderColor: alphaColor(theme.colors.onSurface, 0.12),
106
+ placeholderColor: theme.colors.onSurfaceVariant,
107
+ supportingTextColor: theme.colors.onSurfaceVariant,
108
+ errorSupportingTextColor: theme.colors.error,
109
+ iconColor: theme.colors.onSurfaceVariant,
110
+ errorIconColor: theme.colors.error,
111
+ disabledIconColor: alphaColor(theme.colors.onSurface, disabledOpacity)
112
+ };
113
+ if (variant === "outlined") {
114
+ return {
115
+ ...common,
116
+ backgroundColor: "transparent",
117
+ borderColor: theme.colors.outline,
118
+ disabledBackgroundColor: "transparent",
119
+ labelColor: theme.colors.onSurfaceVariant
120
+ };
121
+ }
122
+ return {
123
+ ...common,
124
+ backgroundColor: theme.colors.surfaceContainerHighest,
125
+ borderColor: theme.colors.onSurfaceVariant,
126
+ disabledBackgroundColor: alphaColor(theme.colors.onSurface, 0.04),
127
+ labelColor: theme.colors.onSurfaceVariant
128
+ };
129
+ }
130
+ function createStyles(theme, variant) {
131
+ const colors = getVariantColors(theme, variant);
132
+ const bodyLarge = theme.typography.bodyLarge;
133
+ const bodySmall = theme.typography.bodySmall;
134
+ const isFilled = variant === "filled";
135
+ return {
136
+ colors,
137
+ styles: import_react_native2.StyleSheet.create({
138
+ root: {
139
+ alignSelf: "stretch"
140
+ },
141
+ container: {
142
+ minHeight: CONTAINER_HEIGHT,
143
+ flexDirection: "row",
144
+ alignItems: "stretch",
145
+ backgroundColor: colors.backgroundColor,
146
+ paddingHorizontal: theme.spacing.md,
147
+ ...isFilled ? {
148
+ borderTopStartRadius: theme.shape.cornerExtraSmall,
149
+ borderTopEndRadius: theme.shape.cornerExtraSmall
150
+ } : {
151
+ borderRadius: theme.shape.cornerExtraSmall,
152
+ borderWidth: 1,
153
+ borderColor: colors.borderColor
154
+ }
155
+ },
156
+ containerFocused: isFilled ? {} : {
157
+ borderWidth: 2,
158
+ borderColor: colors.focusedBorderColor,
159
+ paddingHorizontal: theme.spacing.md - 1
160
+ },
161
+ containerError: isFilled ? {} : {
162
+ borderWidth: 2,
163
+ borderColor: colors.errorBorderColor,
164
+ paddingHorizontal: theme.spacing.md - 1
165
+ },
166
+ containerDisabled: isFilled ? { backgroundColor: colors.disabledBackgroundColor } : {
167
+ borderColor: colors.disabledBorderColor
168
+ },
169
+ indicator: {
170
+ position: "absolute",
171
+ start: 0,
172
+ end: 0,
173
+ bottom: 0,
174
+ height: 1,
175
+ backgroundColor: colors.borderColor
176
+ },
177
+ indicatorFocused: {
178
+ height: 2,
179
+ backgroundColor: colors.focusedBorderColor
180
+ },
181
+ indicatorError: {
182
+ height: 2,
183
+ backgroundColor: colors.errorBorderColor
184
+ },
185
+ indicatorDisabled: {
186
+ backgroundColor: colors.disabledBorderColor
187
+ },
188
+ inputWrapper: {
189
+ flex: 1,
190
+ justifyContent: "center"
191
+ },
192
+ // When label is present, use explicit padding so the input position
193
+ // matches the label resting top exactly.
194
+ inputWrapperWithLabel: {
195
+ justifyContent: "flex-start",
196
+ paddingTop: isFilled ? FILLED_INPUT_TOP : OUTLINED_INPUT_VERTICAL,
197
+ paddingBottom: isFilled ? FILLED_INPUT_BOTTOM : OUTLINED_INPUT_VERTICAL
198
+ },
199
+ label: {
200
+ position: "absolute",
201
+ zIndex: 1,
202
+ fontFamily: bodySmall.fontFamily,
203
+ fontSize: bodySmall.fontSize,
204
+ lineHeight: bodySmall.lineHeight,
205
+ fontWeight: bodySmall.fontWeight,
206
+ letterSpacing: bodySmall.letterSpacing,
207
+ color: colors.labelColor,
208
+ transformOrigin: transformOrigin("top")
209
+ },
210
+ labelNotch: {
211
+ paddingHorizontal: 4
212
+ },
213
+ input: {
214
+ fontFamily: bodyLarge.fontFamily,
215
+ fontSize: bodyLarge.fontSize,
216
+ lineHeight: bodyLarge.lineHeight,
217
+ fontWeight: bodyLarge.fontWeight,
218
+ letterSpacing: bodyLarge.letterSpacing,
219
+ color: colors.textColor,
220
+ paddingVertical: 0,
221
+ paddingHorizontal: 0,
222
+ margin: 0,
223
+ includeFontPadding: false
224
+ },
225
+ inputDisabled: {
226
+ color: colors.disabledTextColor
227
+ },
228
+ leadingIcon: {
229
+ alignSelf: "center",
230
+ marginStart: -4,
231
+ // 16dp container padding → 12dp icon inset per M3
232
+ marginEnd: theme.spacing.md,
233
+ width: ICON_SIZE,
234
+ height: ICON_SIZE,
235
+ alignItems: "center",
236
+ justifyContent: "center"
237
+ },
238
+ trailingIcon: {
239
+ alignSelf: "center",
240
+ marginStart: theme.spacing.md,
241
+ marginEnd: -4,
242
+ // 16dp container padding → 12dp icon inset per M3
243
+ width: ICON_SIZE,
244
+ height: ICON_SIZE,
245
+ alignItems: "center",
246
+ justifyContent: "center"
247
+ },
248
+ trailingIconPressable: {
249
+ alignSelf: "center"
250
+ },
251
+ supportingTextRow: {
252
+ paddingHorizontal: theme.spacing.md,
253
+ paddingTop: theme.spacing.xs
254
+ },
255
+ supportingText: {
256
+ fontFamily: bodySmall.fontFamily,
257
+ fontSize: bodySmall.fontSize,
258
+ lineHeight: bodySmall.lineHeight,
259
+ fontWeight: bodySmall.fontWeight,
260
+ letterSpacing: bodySmall.letterSpacing,
261
+ color: colors.supportingTextColor
262
+ },
263
+ errorSupportingText: {
264
+ color: colors.errorSupportingTextColor
265
+ }
266
+ })
267
+ };
268
+ }
269
+
270
+ // src/text-field/TextField.tsx
271
+ var import_jsx_runtime = require("react/jsx-runtime");
272
+ var ICON_SIZE2 = 24;
273
+ var ICON_WITH_GAP = 12 + 24 + 16;
274
+ function TextField({
275
+ value,
276
+ onChangeText,
277
+ label,
278
+ placeholder,
279
+ variant = "filled",
280
+ supportingText,
281
+ errorText,
282
+ error = false,
283
+ disabled = false,
284
+ leadingIcon,
285
+ trailingIcon,
286
+ onTrailingIconPress,
287
+ multiline = false,
288
+ onFocus,
289
+ onBlur,
290
+ style,
291
+ containerColor,
292
+ contentColor,
293
+ inputStyle,
294
+ ...textInputProps
295
+ }) {
296
+ const theme = (0, import_core.useTheme)();
297
+ const isDisabled = Boolean(disabled);
298
+ const isError = Boolean(error) || Boolean(errorText);
299
+ const isFilled = variant === "filled";
300
+ const hasLeadingIcon = Boolean(leadingIcon);
301
+ const { colors, styles } = (0, import_react.useMemo)(
302
+ () => createStyles(theme, variant),
303
+ [theme, variant]
304
+ );
305
+ const [isFocused, setIsFocused] = (0, import_react.useState)(false);
306
+ const [internalHasText, setInternalHasText] = (0, import_react.useState)(
307
+ () => value !== void 0 && value !== ""
308
+ );
309
+ const inputRef = (0, import_react.useRef)(null);
310
+ const isControlled = value !== void 0;
311
+ const hasValue = isControlled ? value !== "" : internalHasText;
312
+ const isLabelFloated = isFocused || hasValue;
313
+ const labelAnimRef = (0, import_react.useRef)(new import_react_native3.Animated.Value(isLabelFloated ? 1 : 0));
314
+ const labelAnim = labelAnimRef.current;
315
+ (0, import_react.useEffect)(() => {
316
+ import_react_native3.Animated.timing(labelAnim, {
317
+ toValue: isLabelFloated ? 1 : 0,
318
+ duration: 150,
319
+ useNativeDriver: import_react_native3.Platform.OS !== "web"
320
+ }).start();
321
+ }, [isLabelFloated, labelAnim]);
322
+ const labelScale = (0, import_react.useMemo)(() => {
323
+ const restingScale = theme.typography.bodyLarge.fontSize / theme.typography.bodySmall.fontSize;
324
+ return labelAnim.interpolate({
325
+ inputRange: [0, 1],
326
+ outputRange: [restingScale, 1]
327
+ });
328
+ }, [
329
+ labelAnim,
330
+ theme.typography.bodyLarge.fontSize,
331
+ theme.typography.bodySmall.fontSize
332
+ ]);
333
+ const labelTranslateY = (0, import_react.useMemo)(() => {
334
+ const restingTop = isFilled ? labelPositions.filledRestingTop : labelPositions.outlinedRestingTop;
335
+ const floatedTop = isFilled ? labelPositions.filledFloatedTop : labelPositions.outlinedFloatedTop;
336
+ const restingOffset = restingTop - floatedTop;
337
+ return labelAnim.interpolate({
338
+ inputRange: [0, 1],
339
+ outputRange: [restingOffset, 0]
340
+ });
341
+ }, [isFilled, labelAnim]);
342
+ const labelStart = theme.spacing.md + (hasLeadingIcon ? ICON_WITH_GAP - theme.spacing.md : 0);
343
+ const labelStaticTop = isFilled ? labelPositions.filledFloatedTop : labelPositions.outlinedFloatedTop;
344
+ const handleChangeText = (0, import_react.useCallback)(
345
+ (text) => {
346
+ if (!isControlled) {
347
+ setInternalHasText(text !== "");
348
+ }
349
+ onChangeText == null ? void 0 : onChangeText(text);
350
+ },
351
+ [isControlled, onChangeText]
352
+ );
353
+ const handleFocus = (0, import_react.useCallback)(
354
+ (event) => {
355
+ if (isDisabled) return;
356
+ setIsFocused(true);
357
+ onFocus == null ? void 0 : onFocus(event);
358
+ },
359
+ [isDisabled, onFocus]
360
+ );
361
+ const handleBlur = (0, import_react.useCallback)(
362
+ (event) => {
363
+ setIsFocused(false);
364
+ onBlur == null ? void 0 : onBlur(event);
365
+ },
366
+ [onBlur]
367
+ );
368
+ const handleContainerPress = (0, import_react.useCallback)(() => {
369
+ var _a;
370
+ if (!isDisabled) {
371
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
372
+ }
373
+ }, [isDisabled]);
374
+ const labelColor = isDisabled ? colors.disabledLabelColor : isError ? colors.errorLabelColor : isFocused ? colors.focusedLabelColor : colors.labelColor;
375
+ const labelBackgroundColor = variant === "outlined" && isLabelFloated ? theme.colors.surface : "transparent";
376
+ const iconColor = isDisabled ? colors.disabledIconColor : isError ? colors.errorIconColor : contentColor != null ? contentColor : colors.iconColor;
377
+ const containerStyle = (0, import_react.useMemo)(
378
+ () => [
379
+ styles.container,
380
+ containerColor && !isDisabled ? { backgroundColor: containerColor } : void 0,
381
+ isFocused && styles.containerFocused,
382
+ isError && !isFocused && styles.containerError,
383
+ isDisabled && styles.containerDisabled
384
+ ],
385
+ [styles, isFocused, isError, isDisabled, containerColor]
386
+ );
387
+ const indicatorStyle = (0, import_react.useMemo)(
388
+ () => [
389
+ styles.indicator,
390
+ isFocused && styles.indicatorFocused,
391
+ isError && !isFocused && styles.indicatorError,
392
+ isDisabled && styles.indicatorDisabled
393
+ ],
394
+ [styles, isFocused, isError, isDisabled]
395
+ );
396
+ const displaySupportingText = isError ? errorText : supportingText;
397
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native3.View, { style: [styles.root, style], children: [
398
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.Pressable, { onPress: handleContainerPress, disabled: isDisabled, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native3.View, { style: containerStyle, children: [
399
+ leadingIcon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.View, { style: styles.leadingIcon, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
400
+ import_MaterialCommunityIcons.default,
401
+ {
402
+ name: leadingIcon,
403
+ size: ICON_SIZE2,
404
+ color: iconColor
405
+ }
406
+ ) }) : null,
407
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
408
+ import_react_native3.View,
409
+ {
410
+ style: [
411
+ styles.inputWrapper,
412
+ label ? styles.inputWrapperWithLabel : void 0
413
+ ],
414
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
415
+ import_react_native3.TextInput,
416
+ {
417
+ ref: inputRef,
418
+ ...textInputProps,
419
+ value,
420
+ onChangeText: handleChangeText,
421
+ editable: !isDisabled,
422
+ onFocus: handleFocus,
423
+ onBlur: handleBlur,
424
+ placeholder: isLabelFloated || !label ? placeholder : void 0,
425
+ placeholderTextColor: colors.placeholderColor,
426
+ multiline,
427
+ style: [
428
+ styles.input,
429
+ isDisabled ? styles.inputDisabled : void 0,
430
+ contentColor && !isDisabled ? { color: contentColor } : void 0,
431
+ inputStyle
432
+ ],
433
+ accessibilityLabel: label || void 0,
434
+ accessibilityState: { disabled: isDisabled },
435
+ accessibilityHint: isError && errorText ? errorText : void 0
436
+ }
437
+ )
438
+ }
439
+ ),
440
+ trailingIcon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
441
+ import_react_native3.Pressable,
442
+ {
443
+ onPress: onTrailingIconPress,
444
+ disabled: isDisabled || !onTrailingIconPress,
445
+ accessibilityRole: "button",
446
+ hitSlop: 12,
447
+ style: styles.trailingIconPressable,
448
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.View, { style: styles.trailingIcon, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
449
+ import_MaterialCommunityIcons.default,
450
+ {
451
+ name: trailingIcon,
452
+ size: ICON_SIZE2,
453
+ color: iconColor
454
+ }
455
+ ) })
456
+ }
457
+ ) : null,
458
+ label ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
459
+ import_react_native3.Animated.Text,
460
+ {
461
+ numberOfLines: 1,
462
+ style: [
463
+ styles.label,
464
+ {
465
+ top: labelStaticTop,
466
+ start: labelStart,
467
+ color: labelColor,
468
+ backgroundColor: labelBackgroundColor,
469
+ transform: [
470
+ { translateY: labelTranslateY },
471
+ { scale: labelScale }
472
+ ]
473
+ },
474
+ variant === "outlined" && isLabelFloated ? styles.labelNotch : void 0
475
+ ],
476
+ children: label
477
+ }
478
+ ) : null,
479
+ isFilled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.View, { style: indicatorStyle }) : null
480
+ ] }) }),
481
+ displaySupportingText ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.View, { style: styles.supportingTextRow, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
482
+ import_react_native3.Text,
483
+ {
484
+ style: [
485
+ styles.supportingText,
486
+ isError ? styles.errorSupportingText : void 0
487
+ ],
488
+ children: displaySupportingText
489
+ }
490
+ ) }) : null
491
+ ] });
492
+ }
493
+ // Annotate the CommonJS export names for ESM import in node:
494
+ 0 && (module.exports = {
495
+ TextField
496
+ });
@@ -0,0 +1,51 @@
1
+ import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
2
+ import { ComponentProps } from 'react';
3
+ import { PressableProps } from 'react-native';
4
+
5
+ /** Visual fill style of the icon button. */
6
+ type IconButtonVariant = 'filled' | 'tonal' | 'outlined' | 'standard';
7
+ /** Touch target size of the icon button. */
8
+ type IconButtonSize = 'small' | 'medium' | 'large';
9
+ interface IconButtonProps extends Omit<PressableProps, 'children' | 'onPress' | 'style' | 'accessibilityLabel'> {
10
+ /** MaterialCommunityIcons icon name to display. */
11
+ icon: ComponentProps<typeof MaterialCommunityIcons>['name'];
12
+ /** Icon to display when `selected` is `true` (toggle mode). */
13
+ selectedIcon?: ComponentProps<typeof MaterialCommunityIcons>['name'];
14
+ /** Overrides the automatic icon color derived from the variant and state. */
15
+ iconColor?: string;
16
+ /**
17
+ * Override the content (icon) color.
18
+ * Takes precedence over `iconColor` when both are provided.
19
+ */
20
+ contentColor?: string;
21
+ /**
22
+ * Override the container (background) color.
23
+ * State-layer colors (hover, press) are derived automatically.
24
+ */
25
+ containerColor?: string;
26
+ /** Custom style applied to the root container. */
27
+ style?: PressableProps['style'];
28
+ /** Called when the button is pressed. */
29
+ onPress?: () => void;
30
+ /**
31
+ * Disables the button.
32
+ * @default false
33
+ */
34
+ disabled?: boolean;
35
+ /**
36
+ * Visual style variant.
37
+ * @default 'filled'
38
+ */
39
+ variant?: IconButtonVariant;
40
+ /** Enables toggle mode. The button changes appearance based on selected/unselected state. */
41
+ selected?: boolean;
42
+ /**
43
+ * Physical size of the touch target and icon container.
44
+ * @default 'medium'
45
+ */
46
+ size?: IconButtonSize;
47
+ /** Required — icon-only buttons must have a label for screen readers. */
48
+ accessibilityLabel: string;
49
+ }
50
+
51
+ export type { IconButtonProps as I, IconButtonSize as a, IconButtonVariant as b };
@@ -0,0 +1,28 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode, ComponentType } from 'react';
3
+ import { TextProps, StyleProp, TextStyle } from 'react-native';
4
+
5
+ /** Material Design 3 type scale role. */
6
+ type TypographyVariant = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall' | 'labelLarge' | 'labelMedium' | 'labelSmall';
7
+
8
+ interface TypographyProps extends Omit<TextProps, 'children' | 'style'> {
9
+ /** Content to display. Accepts strings, numbers, or nested elements. */
10
+ children: ReactNode;
11
+ /**
12
+ * MD3 type scale role. Controls font size, weight, line height, and letter spacing.
13
+ * @default 'bodyMedium'
14
+ */
15
+ variant?: TypographyVariant;
16
+ /** Override the text color. Defaults to the theme's `onSurface` color. */
17
+ color?: string;
18
+ /** Additional text styles merged after the theme typography styles. */
19
+ style?: StyleProp<TextStyle>;
20
+ /**
21
+ * Override the underlying text component (e.g. Animated.Text).
22
+ * @default Text
23
+ */
24
+ as?: ComponentType<TextProps>;
25
+ }
26
+ declare function Typography({ children, variant, color, style, as: Component, accessibilityRole, ...textProps }: TypographyProps): react_jsx_runtime.JSX.Element;
27
+
28
+ export { Typography, type TypographyProps, type TypographyVariant };
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/typography/index.ts
21
+ var typography_exports = {};
22
+ __export(typography_exports, {
23
+ Typography: () => Typography
24
+ });
25
+ module.exports = __toCommonJS(typography_exports);
26
+
27
+ // src/typography/Typography.tsx
28
+ var import_react = require("react");
29
+ var import_react_native = require("react-native");
30
+ var import_core = require("@onlynative/core");
31
+ var import_jsx_runtime = require("react/jsx-runtime");
32
+ var HEADING_VARIANTS = /* @__PURE__ */ new Set([
33
+ "displayLarge",
34
+ "displayMedium",
35
+ "displaySmall",
36
+ "headlineLarge",
37
+ "headlineMedium",
38
+ "headlineSmall"
39
+ ]);
40
+ function Typography({
41
+ children,
42
+ variant = "bodyMedium",
43
+ color,
44
+ style,
45
+ as: Component = import_react_native.Text,
46
+ accessibilityRole,
47
+ ...textProps
48
+ }) {
49
+ const theme = (0, import_core.useTheme)();
50
+ const typographyStyle = theme.typography[variant];
51
+ const colorStyle = (0, import_react.useMemo)(
52
+ () => ({ color: color != null ? color : theme.colors.onSurface }),
53
+ [color, theme.colors.onSurface]
54
+ );
55
+ const resolvedRole = accessibilityRole != null ? accessibilityRole : HEADING_VARIANTS.has(variant) ? "header" : void 0;
56
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
57
+ Component,
58
+ {
59
+ ...textProps,
60
+ accessibilityRole: resolvedRole,
61
+ style: [typographyStyle, colorStyle, style],
62
+ children
63
+ }
64
+ );
65
+ }
66
+ // Annotate the CommonJS export names for ESM import in node:
67
+ 0 && (module.exports = {
68
+ Typography
69
+ });