@onlynative/components 0.1.0-alpha.2 → 0.1.0-alpha.3
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/dist/appbar/index.js +43 -23
- package/dist/button/index.js +24 -13
- package/dist/checkbox/index.js +23 -12
- package/dist/chip/index.js +26 -14
- package/dist/icon-button/index.js +23 -12
- package/dist/index.js +114 -83
- package/dist/switch/index.js +23 -12
- package/dist/text-field/index.js +24 -13
- package/dist/typography/index.js +9 -0
- package/package.json +2 -2
- package/src/button/Button.tsx +4 -1
- package/src/checkbox/Checkbox.tsx +5 -1
- package/src/chip/Chip.tsx +7 -1
- package/src/icon-button/IconButton.tsx +2 -1
- package/src/switch/Switch.tsx +4 -1
- package/src/text-field/TextField.tsx +4 -1
- package/src/typography/Typography.tsx +13 -1
- package/src/utils/icon.ts +30 -0
package/dist/switch/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
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
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/switch/index.ts
|
|
@@ -35,11 +25,31 @@ __export(switch_exports, {
|
|
|
35
25
|
module.exports = __toCommonJS(switch_exports);
|
|
36
26
|
|
|
37
27
|
// src/switch/Switch.tsx
|
|
38
|
-
var import_MaterialCommunityIcons = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
|
|
39
28
|
var import_react = require("react");
|
|
40
29
|
var import_react_native2 = require("react-native");
|
|
41
30
|
var import_core = require("@onlynative/core");
|
|
42
31
|
|
|
32
|
+
// src/utils/icon.ts
|
|
33
|
+
var _MCIcons = null;
|
|
34
|
+
var _resolved = false;
|
|
35
|
+
function getMaterialCommunityIcons() {
|
|
36
|
+
if (!_resolved) {
|
|
37
|
+
_resolved = true;
|
|
38
|
+
try {
|
|
39
|
+
const mod = require("@expo/vector-icons/MaterialCommunityIcons");
|
|
40
|
+
_MCIcons = mod.default || mod;
|
|
41
|
+
} catch {
|
|
42
|
+
_MCIcons = null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!_MCIcons) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"@expo/vector-icons is required for icon support. Install it with: npx expo install @expo/vector-icons"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return _MCIcons;
|
|
51
|
+
}
|
|
52
|
+
|
|
43
53
|
// src/switch/styles.ts
|
|
44
54
|
var import_react_native = require("react-native");
|
|
45
55
|
|
|
@@ -271,6 +281,7 @@ function Switch({
|
|
|
271
281
|
}
|
|
272
282
|
};
|
|
273
283
|
const iconName = isSelected ? selectedIcon : unselectedIcon;
|
|
284
|
+
const MaterialCommunityIcons = iconName ? getMaterialCommunityIcons() : null;
|
|
274
285
|
const iconSize = 16;
|
|
275
286
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
276
287
|
import_react_native2.Pressable,
|
|
@@ -297,7 +308,7 @@ function Switch({
|
|
|
297
308
|
{
|
|
298
309
|
style: [styles.thumb, isDisabled ? styles.disabledThumb : void 0],
|
|
299
310
|
children: iconName ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
300
|
-
|
|
311
|
+
MaterialCommunityIcons,
|
|
301
312
|
{
|
|
302
313
|
name: iconName,
|
|
303
314
|
size: iconSize,
|
package/dist/text-field/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
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
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/text-field/index.ts
|
|
@@ -35,11 +25,31 @@ __export(text_field_exports, {
|
|
|
35
25
|
module.exports = __toCommonJS(text_field_exports);
|
|
36
26
|
|
|
37
27
|
// src/text-field/TextField.tsx
|
|
38
|
-
var import_MaterialCommunityIcons = __toESM(require("@expo/vector-icons/MaterialCommunityIcons"));
|
|
39
28
|
var import_react = require("react");
|
|
40
29
|
var import_react_native3 = require("react-native");
|
|
41
30
|
var import_core = require("@onlynative/core");
|
|
42
31
|
|
|
32
|
+
// src/utils/icon.ts
|
|
33
|
+
var _MCIcons = null;
|
|
34
|
+
var _resolved = false;
|
|
35
|
+
function getMaterialCommunityIcons() {
|
|
36
|
+
if (!_resolved) {
|
|
37
|
+
_resolved = true;
|
|
38
|
+
try {
|
|
39
|
+
const mod = require("@expo/vector-icons/MaterialCommunityIcons");
|
|
40
|
+
_MCIcons = mod.default || mod;
|
|
41
|
+
} catch {
|
|
42
|
+
_MCIcons = null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!_MCIcons) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"@expo/vector-icons is required for icon support. Install it with: npx expo install @expo/vector-icons"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return _MCIcons;
|
|
51
|
+
}
|
|
52
|
+
|
|
43
53
|
// src/text-field/styles.ts
|
|
44
54
|
var import_react_native2 = require("react-native");
|
|
45
55
|
|
|
@@ -298,6 +308,7 @@ function TextField({
|
|
|
298
308
|
const isError = Boolean(error) || Boolean(errorText);
|
|
299
309
|
const isFilled = variant === "filled";
|
|
300
310
|
const hasLeadingIcon = Boolean(leadingIcon);
|
|
311
|
+
const MaterialCommunityIcons = leadingIcon || trailingIcon ? getMaterialCommunityIcons() : null;
|
|
301
312
|
const { colors, styles } = (0, import_react.useMemo)(
|
|
302
313
|
() => createStyles(theme, variant),
|
|
303
314
|
[theme, variant]
|
|
@@ -397,7 +408,7 @@ function TextField({
|
|
|
397
408
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native3.View, { style: [styles.root, style], children: [
|
|
398
409
|
/* @__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
410
|
leadingIcon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.View, { style: styles.leadingIcon, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
400
|
-
|
|
411
|
+
MaterialCommunityIcons,
|
|
401
412
|
{
|
|
402
413
|
name: leadingIcon,
|
|
403
414
|
size: ICON_SIZE2,
|
|
@@ -446,7 +457,7 @@ function TextField({
|
|
|
446
457
|
hitSlop: 12,
|
|
447
458
|
style: styles.trailingIconPressable,
|
|
448
459
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.View, { style: styles.trailingIcon, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
449
|
-
|
|
460
|
+
MaterialCommunityIcons,
|
|
450
461
|
{
|
|
451
462
|
name: trailingIcon,
|
|
452
463
|
size: ICON_SIZE2,
|
package/dist/typography/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(typography_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(typography_exports);
|
|
26
26
|
|
|
27
27
|
// src/typography/Typography.tsx
|
|
28
|
+
var import_react = require("react");
|
|
28
29
|
var import_react_native = require("react-native");
|
|
29
30
|
var import_core = require("@onlynative/core");
|
|
30
31
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -48,6 +49,13 @@ function Typography({
|
|
|
48
49
|
const theme = (0, import_core.useTheme)();
|
|
49
50
|
const typographyStyle = theme.typography[variant];
|
|
50
51
|
const resolvedRole = accessibilityRole != null ? accessibilityRole : HEADING_VARIANTS.has(variant) ? "header" : void 0;
|
|
52
|
+
const lineHeightFix = (0, import_react.useMemo)(() => {
|
|
53
|
+
if (!style) return void 0;
|
|
54
|
+
const flat = import_react_native.StyleSheet.flatten(style);
|
|
55
|
+
if (!(flat == null ? void 0 : flat.fontSize) || flat.lineHeight) return void 0;
|
|
56
|
+
const ratio = typographyStyle.lineHeight / typographyStyle.fontSize;
|
|
57
|
+
return { lineHeight: Math.ceil(flat.fontSize * ratio) };
|
|
58
|
+
}, [style, typographyStyle.fontSize, typographyStyle.lineHeight]);
|
|
51
59
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
52
60
|
Component,
|
|
53
61
|
{
|
|
@@ -57,6 +65,7 @@ function Typography({
|
|
|
57
65
|
{ color: theme.colors.onSurface },
|
|
58
66
|
typographyStyle,
|
|
59
67
|
style,
|
|
68
|
+
lineHeightFix,
|
|
60
69
|
color != null ? { color } : void 0
|
|
61
70
|
],
|
|
62
71
|
children
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlynative/components",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.3",
|
|
4
4
|
"description": "Material Design 3 UI components for React Native — Button, Card, Chip, TextField, and more.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"sideEffects": false,
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
},
|
|
147
147
|
"peerDependencies": {
|
|
148
148
|
"@expo/vector-icons": ">=14.0.0",
|
|
149
|
-
"@onlynative/core": ">=0.1.0-alpha.
|
|
149
|
+
"@onlynative/core": ">=0.1.0-alpha.3",
|
|
150
150
|
"react": ">=18.0.0",
|
|
151
151
|
"react-native": ">=0.72.0",
|
|
152
152
|
"react-native-safe-area-context": ">=4.0.0"
|
package/src/button/Button.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'
|
|
2
1
|
import { useMemo } from 'react'
|
|
3
2
|
import { Platform, Pressable } from 'react-native'
|
|
4
3
|
import { StyleSheet } from 'react-native'
|
|
@@ -6,6 +5,7 @@ import { Text } from 'react-native'
|
|
|
6
5
|
import type { StyleProp, ViewStyle } from 'react-native'
|
|
7
6
|
import { useTheme } from '@onlynative/core'
|
|
8
7
|
|
|
8
|
+
import { getMaterialCommunityIcons } from '../utils/icon'
|
|
9
9
|
import { createStyles } from './styles'
|
|
10
10
|
import type { ButtonProps } from './types'
|
|
11
11
|
|
|
@@ -75,6 +75,9 @@ export function Button({
|
|
|
75
75
|
[theme, variant, hasLeading, hasTrailing, containerColor, contentColor],
|
|
76
76
|
)
|
|
77
77
|
|
|
78
|
+
const MaterialCommunityIcons =
|
|
79
|
+
leadingIcon || trailingIcon ? getMaterialCommunityIcons() : null
|
|
80
|
+
|
|
78
81
|
const resolvedIconColor = useMemo(() => {
|
|
79
82
|
const base = StyleSheet.flatten([
|
|
80
83
|
styles.label,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'
|
|
2
1
|
import { useMemo } from 'react'
|
|
3
2
|
import { Platform, Pressable, StyleSheet, View } from 'react-native'
|
|
4
3
|
import type { StyleProp, ViewStyle } from 'react-native'
|
|
5
4
|
import { useTheme } from '@onlynative/core'
|
|
6
5
|
|
|
6
|
+
import { getMaterialCommunityIcons } from '../utils/icon'
|
|
7
7
|
import { createStyles } from './styles'
|
|
8
8
|
import type { CheckboxProps } from './types'
|
|
9
9
|
|
|
@@ -55,6 +55,10 @@ export function Checkbox({
|
|
|
55
55
|
const isDisabled = Boolean(disabled)
|
|
56
56
|
const isChecked = Boolean(value)
|
|
57
57
|
|
|
58
|
+
const MaterialCommunityIcons = isChecked
|
|
59
|
+
? getMaterialCommunityIcons()
|
|
60
|
+
: null
|
|
61
|
+
|
|
58
62
|
const theme = useTheme()
|
|
59
63
|
const styles = useMemo(
|
|
60
64
|
() => createStyles(theme, isChecked, containerColor, contentColor),
|
package/src/chip/Chip.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'
|
|
2
1
|
import { useMemo } from 'react'
|
|
3
2
|
import { Platform, Pressable, StyleSheet, Text, View } from 'react-native'
|
|
4
3
|
import type { StyleProp, ViewStyle } from 'react-native'
|
|
5
4
|
import { useTheme } from '@onlynative/core'
|
|
6
5
|
|
|
6
|
+
import { getMaterialCommunityIcons } from '../utils/icon'
|
|
7
7
|
import { createStyles } from './styles'
|
|
8
8
|
import type { ChipProps } from './types'
|
|
9
9
|
|
|
@@ -72,6 +72,12 @@ export function Chip({
|
|
|
72
72
|
(variant === 'filter' && isSelected),
|
|
73
73
|
)
|
|
74
74
|
|
|
75
|
+
const needsIcons =
|
|
76
|
+
Boolean(leadingIcon) || (variant === 'filter' && isSelected) || showCloseIcon
|
|
77
|
+
const MaterialCommunityIcons = needsIcons
|
|
78
|
+
? getMaterialCommunityIcons()
|
|
79
|
+
: null
|
|
80
|
+
|
|
75
81
|
const theme = useTheme()
|
|
76
82
|
const styles = useMemo(
|
|
77
83
|
() =>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'
|
|
2
1
|
import { useMemo } from 'react'
|
|
3
2
|
import { Pressable } from 'react-native'
|
|
4
3
|
import type { StyleProp, ViewStyle } from 'react-native'
|
|
5
4
|
import { useTheme } from '@onlynative/core'
|
|
6
5
|
|
|
6
|
+
import { getMaterialCommunityIcons } from '../utils/icon'
|
|
7
7
|
import { createStyles } from './styles'
|
|
8
8
|
import type {
|
|
9
9
|
IconButtonProps,
|
|
@@ -263,6 +263,7 @@ export function IconButton({
|
|
|
263
263
|
accessibilityLabel,
|
|
264
264
|
...props
|
|
265
265
|
}: IconButtonProps) {
|
|
266
|
+
const MaterialCommunityIcons = getMaterialCommunityIcons()
|
|
266
267
|
const theme = useTheme()
|
|
267
268
|
const styles = useMemo(() => createStyles(theme), [theme])
|
|
268
269
|
const isDisabled = Boolean(disabled)
|
package/src/switch/Switch.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'
|
|
2
1
|
import { useMemo } from 'react'
|
|
3
2
|
import { Platform, Pressable, StyleSheet, View } from 'react-native'
|
|
4
3
|
import type { StyleProp, ViewStyle } from 'react-native'
|
|
5
4
|
import { useTheme } from '@onlynative/core'
|
|
6
5
|
|
|
6
|
+
import { getMaterialCommunityIcons } from '../utils/icon'
|
|
7
7
|
import { createStyles } from './styles'
|
|
8
8
|
import type { SwitchProps } from './types'
|
|
9
9
|
|
|
@@ -80,6 +80,9 @@ export function Switch({
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
const iconName = isSelected ? selectedIcon : unselectedIcon
|
|
83
|
+
const MaterialCommunityIcons = iconName
|
|
84
|
+
? getMaterialCommunityIcons()
|
|
85
|
+
: null
|
|
83
86
|
const iconSize = 16
|
|
84
87
|
|
|
85
88
|
return (
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'
|
|
2
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
3
2
|
import {
|
|
4
3
|
Animated,
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
import type { NativeSyntheticEvent, TargetedEvent } from 'react-native'
|
|
12
11
|
import { useTheme } from '@onlynative/core'
|
|
13
12
|
|
|
13
|
+
import { getMaterialCommunityIcons } from '../utils/icon'
|
|
14
14
|
import { createStyles, labelPositions } from './styles'
|
|
15
15
|
import type { TextFieldProps } from './types'
|
|
16
16
|
|
|
@@ -46,6 +46,9 @@ export function TextField({
|
|
|
46
46
|
const isFilled = variant === 'filled'
|
|
47
47
|
const hasLeadingIcon = Boolean(leadingIcon)
|
|
48
48
|
|
|
49
|
+
const MaterialCommunityIcons =
|
|
50
|
+
leadingIcon || trailingIcon ? getMaterialCommunityIcons() : null
|
|
51
|
+
|
|
49
52
|
const { colors, styles } = useMemo(
|
|
50
53
|
() => createStyles(theme, variant),
|
|
51
54
|
[theme, variant],
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
1
2
|
import type { ComponentType, ReactNode } from 'react'
|
|
2
3
|
import type { StyleProp, TextProps, TextStyle } from 'react-native'
|
|
3
|
-
import { Text } from 'react-native'
|
|
4
|
+
import { StyleSheet, Text } from 'react-native'
|
|
4
5
|
import { useTheme } from '@onlynative/core'
|
|
5
6
|
import type { MaterialTheme } from '@onlynative/core'
|
|
6
7
|
|
|
@@ -48,6 +49,16 @@ export function Typography({
|
|
|
48
49
|
const resolvedRole =
|
|
49
50
|
accessibilityRole ?? (HEADING_VARIANTS.has(variant) ? 'header' : undefined)
|
|
50
51
|
|
|
52
|
+
// When the consumer overrides fontSize via style, auto-adjust lineHeight
|
|
53
|
+
// proportionally so text isn't clipped inside overflow:hidden containers.
|
|
54
|
+
const lineHeightFix = useMemo(() => {
|
|
55
|
+
if (!style) return undefined
|
|
56
|
+
const flat = StyleSheet.flatten(style)
|
|
57
|
+
if (!flat?.fontSize || flat.lineHeight) return undefined
|
|
58
|
+
const ratio = typographyStyle.lineHeight / typographyStyle.fontSize
|
|
59
|
+
return { lineHeight: Math.ceil(flat.fontSize * ratio) }
|
|
60
|
+
}, [style, typographyStyle.fontSize, typographyStyle.lineHeight])
|
|
61
|
+
|
|
51
62
|
return (
|
|
52
63
|
<Component
|
|
53
64
|
{...textProps}
|
|
@@ -56,6 +67,7 @@ export function Typography({
|
|
|
56
67
|
{ color: theme.colors.onSurface },
|
|
57
68
|
typographyStyle,
|
|
58
69
|
style,
|
|
70
|
+
lineHeightFix,
|
|
59
71
|
color != null ? { color } : undefined,
|
|
60
72
|
]}
|
|
61
73
|
>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
|
+
let _MCIcons: any = null
|
|
3
|
+
let _resolved = false
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Lazily resolves MaterialCommunityIcons from `@expo/vector-icons`.
|
|
7
|
+
*
|
|
8
|
+
* Called at render time (not module load) so that components can be
|
|
9
|
+
* imported without `@expo/vector-icons` installed — the error only
|
|
10
|
+
* fires when an icon is actually rendered.
|
|
11
|
+
*/
|
|
12
|
+
export function getMaterialCommunityIcons() {
|
|
13
|
+
if (!_resolved) {
|
|
14
|
+
_resolved = true
|
|
15
|
+
try {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
|
+
const mod = require('@expo/vector-icons/MaterialCommunityIcons')
|
|
18
|
+
_MCIcons = mod.default || mod
|
|
19
|
+
} catch {
|
|
20
|
+
_MCIcons = null
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (!_MCIcons) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
'@expo/vector-icons is required for icon support. ' +
|
|
26
|
+
'Install it with: npx expo install @expo/vector-icons',
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
return _MCIcons
|
|
30
|
+
}
|