@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.
- package/README.md +99 -0
- package/dist/appbar/index.d.ts +71 -0
- package/dist/appbar/index.js +952 -0
- package/dist/button/index.d.ts +41 -0
- package/dist/button/index.js +454 -0
- package/dist/card/index.d.ts +31 -0
- package/dist/card/index.js +264 -0
- package/dist/checkbox/index.d.ts +25 -0
- package/dist/checkbox/index.js +291 -0
- package/dist/chip/index.d.ts +62 -0
- package/dist/chip/index.js +452 -0
- package/dist/icon-button/index.d.ts +10 -0
- package/dist/icon-button/index.js +575 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +3374 -0
- package/dist/layout/index.d.ts +98 -0
- package/dist/layout/index.js +282 -0
- package/dist/list/index.d.ts +60 -0
- package/dist/list/index.js +300 -0
- package/dist/radio/index.d.ts +25 -0
- package/dist/radio/index.js +250 -0
- package/dist/switch/index.d.ts +37 -0
- package/dist/switch/index.js +315 -0
- package/dist/text-field/index.d.ts +52 -0
- package/dist/text-field/index.js +496 -0
- package/dist/types-D3hlyvz-.d.ts +51 -0
- package/dist/typography/index.d.ts +28 -0
- package/dist/typography/index.js +69 -0
- package/package.json +166 -0
- package/src/appbar/AppBar.tsx +302 -0
- package/src/appbar/index.ts +2 -0
- package/src/appbar/styles.ts +92 -0
- package/src/appbar/types.ts +67 -0
- package/src/button/Button.tsx +130 -0
- package/src/button/index.ts +2 -0
- package/src/button/styles.ts +288 -0
- package/src/button/types.ts +42 -0
- package/src/card/Card.tsx +69 -0
- package/src/card/index.ts +2 -0
- package/src/card/styles.ts +151 -0
- package/src/card/types.ts +27 -0
- package/src/checkbox/Checkbox.tsx +109 -0
- package/src/checkbox/index.ts +2 -0
- package/src/checkbox/styles.ts +155 -0
- package/src/checkbox/types.ts +20 -0
- package/src/chip/Chip.tsx +182 -0
- package/src/chip/index.ts +2 -0
- package/src/chip/styles.ts +240 -0
- package/src/chip/types.ts +58 -0
- package/src/icon-button/IconButton.tsx +358 -0
- package/src/icon-button/index.ts +6 -0
- package/src/icon-button/styles.ts +259 -0
- package/src/icon-button/types.ts +55 -0
- package/src/index.ts +51 -0
- package/src/layout/Box.tsx +99 -0
- package/src/layout/Column.tsx +16 -0
- package/src/layout/Grid.tsx +49 -0
- package/src/layout/Layout.tsx +81 -0
- package/src/layout/Row.tsx +22 -0
- package/src/layout/index.ts +13 -0
- package/src/layout/resolveSpacing.ts +11 -0
- package/src/layout/types.ts +82 -0
- package/src/list/List.tsx +17 -0
- package/src/list/ListDivider.tsx +20 -0
- package/src/list/ListItem.tsx +128 -0
- package/src/list/index.ts +9 -0
- package/src/list/styles.ts +132 -0
- package/src/list/types.ts +54 -0
- package/src/radio/Radio.tsx +103 -0
- package/src/radio/index.ts +2 -0
- package/src/radio/styles.ts +139 -0
- package/src/radio/types.ts +20 -0
- package/src/switch/Switch.tsx +118 -0
- package/src/switch/index.ts +2 -0
- package/src/switch/styles.ts +172 -0
- package/src/switch/types.ts +32 -0
- package/src/test-utils/render-with-theme.tsx +13 -0
- package/src/text-field/TextField.tsx +298 -0
- package/src/text-field/index.ts +2 -0
- package/src/text-field/styles.ts +240 -0
- package/src/text-field/types.ts +49 -0
- package/src/typography/Typography.tsx +65 -0
- package/src/typography/index.ts +3 -0
- package/src/typography/types.ts +17 -0
- package/src/utils/color.ts +64 -0
- package/src/utils/elevation.ts +33 -0
- 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
|
+
});
|