@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.
@@ -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
- import_MaterialCommunityIcons.default,
311
+ MaterialCommunityIcons,
301
312
  {
302
313
  name: iconName,
303
314
  size: iconSize,
@@ -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
- import_MaterialCommunityIcons.default,
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
- import_MaterialCommunityIcons.default,
460
+ MaterialCommunityIcons,
450
461
  {
451
462
  name: trailingIcon,
452
463
  size: ICON_SIZE2,
@@ -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.2",
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.2",
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"
@@ -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)
@@ -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
+ }