@xaui/native 0.0.9 → 0.0.11

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.
@@ -0,0 +1,90 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { ViewStyle, TextStyle } from 'react-native';
3
+ import { T as ThemeColor } from '../index-BOw6tbkc.js';
4
+
5
+ type AlertVariant = 'solid' | 'bordered' | 'flat' | 'faded';
6
+ type AlertRadius = 'none' | 'sm' | 'md' | 'lg' | 'full';
7
+ type AlertEvents = {
8
+ /**
9
+ * Callback fired when the alert is closed.
10
+ */
11
+ onClose?: () => void;
12
+ /**
13
+ * Callback fired when the alert visibility changes.
14
+ */
15
+ onVisibleChange?: (isVisible: boolean) => void;
16
+ };
17
+ type AlertCustomAppearance = {
18
+ /**
19
+ * Custom style for the alert container.
20
+ */
21
+ container?: ViewStyle;
22
+ /**
23
+ * Custom style for the alert title.
24
+ */
25
+ title?: TextStyle;
26
+ /**
27
+ * Custom style for the alert description.
28
+ */
29
+ description?: TextStyle;
30
+ };
31
+ type AlertProps = {
32
+ /**
33
+ * The title of the alert.
34
+ */
35
+ title?: ReactNode;
36
+ /**
37
+ * The description content of the alert.
38
+ */
39
+ description?: ReactNode;
40
+ /**
41
+ * Custom icon to display inside the alert.
42
+ */
43
+ icon?: ReactNode;
44
+ /**
45
+ * The theme color of the alert.
46
+ * @default 'default'
47
+ */
48
+ themeColor?: ThemeColor;
49
+ /**
50
+ * The variant of the alert.
51
+ * @default 'flat'
52
+ */
53
+ variant?: AlertVariant;
54
+ /**
55
+ * The border radius of the alert.
56
+ * @default 'md'
57
+ */
58
+ radius?: AlertRadius;
59
+ /**
60
+ * Whether the alert can be closed with a close button.
61
+ * @default false
62
+ */
63
+ isClosable?: boolean;
64
+ /**
65
+ * Whether to hide the icon.
66
+ * @default false
67
+ */
68
+ hideIcon?: boolean;
69
+ /**
70
+ * Custom close button element.
71
+ */
72
+ closeButton?: ReactNode;
73
+ /**
74
+ * Whether the alert is visible.
75
+ * @default true
76
+ */
77
+ isVisible?: boolean;
78
+ /**
79
+ * Custom appearance styles for all alert parts
80
+ */
81
+ customAppearance?: AlertCustomAppearance;
82
+ /**
83
+ * Additional content rendered below the description.
84
+ */
85
+ children?: ReactNode;
86
+ } & AlertEvents;
87
+
88
+ declare const Alert: React.FC<AlertProps>;
89
+
90
+ export { Alert, type AlertProps, type AlertVariant };
@@ -0,0 +1,8 @@
1
+ import {
2
+ Alert
3
+ } from "../chunk-OFYJYQ2M.js";
4
+ import "../chunk-SIXET7TJ.js";
5
+ import "../chunk-NBRASCX4.js";
6
+ export {
7
+ Alert
8
+ };
@@ -1141,8 +1141,7 @@ var Autocomplete = ({
1141
1141
  disableLocalFilter = false,
1142
1142
  inputValue,
1143
1143
  defaultInputValue,
1144
- style,
1145
- textStyle,
1144
+ customAppearance,
1146
1145
  onClose,
1147
1146
  onOpenChange,
1148
1147
  onSelectionChange,
@@ -1298,8 +1297,8 @@ var Autocomplete = ({
1298
1297
  labelText: typeof label === "string" ? label : void 0,
1299
1298
  isLabelInside,
1300
1299
  clearIcon,
1301
- style,
1302
- textStyle,
1300
+ style: customAppearance?.container,
1301
+ textStyle: customAppearance?.text,
1303
1302
  onPress: handleTriggerPress,
1304
1303
  onClear: handleClear,
1305
1304
  onLayout: handleTriggerLayout
@@ -1441,8 +1440,7 @@ var AutocompleteItem = ({
1441
1440
  isDisabled = false,
1442
1441
  isSelected = false,
1443
1442
  isReadOnly = false,
1444
- style,
1445
- textStyle,
1443
+ customAppearance,
1446
1444
  onSelected
1447
1445
  }) => {
1448
1446
  const context = (0, import_react20.useContext)(AutocompleteContext);
@@ -1469,7 +1467,7 @@ var AutocompleteItem = ({
1469
1467
  backgroundColor
1470
1468
  },
1471
1469
  isItemDisabled && styles3.disabled,
1472
- style
1470
+ customAppearance?.container
1473
1471
  ]
1474
1472
  },
1475
1473
  startContent,
@@ -1479,7 +1477,7 @@ var AutocompleteItem = ({
1479
1477
  style: [
1480
1478
  styles3.title,
1481
1479
  { fontSize: sizeStyles.titleSize, color: labelColor },
1482
- textStyle
1480
+ customAppearance?.text
1483
1481
  ]
1484
1482
  },
1485
1483
  label
@@ -5,6 +5,26 @@ import { T as ThemeColor, S as Size, R as Radius } from '../index-BOw6tbkc.cjs';
5
5
  type AutocompleteVariant = 'outlined' | 'flat' | 'light' | 'faded' | 'underlined';
6
6
  type AutocompleteLabelPlacement = 'inside' | 'outside' | 'outside-left' | 'outside-top';
7
7
  type AutocompleteMenuTrigger = 'focus' | 'input' | 'manual';
8
+ type AutocompleteCustomAppearance = {
9
+ /**
10
+ * Custom styles for the container
11
+ */
12
+ container?: ViewStyle;
13
+ /**
14
+ * Custom styles for the text
15
+ */
16
+ text?: TextStyle;
17
+ };
18
+ type AutocompleteItemCustomAppearance = {
19
+ /**
20
+ * Custom styles for the container
21
+ */
22
+ container?: ViewStyle;
23
+ /**
24
+ * Custom styles for the text
25
+ */
26
+ text?: TextStyle;
27
+ };
8
28
  type AutocompleteProps = {
9
29
  children: ReactNode;
10
30
  variant?: AutocompleteVariant;
@@ -33,8 +53,7 @@ type AutocompleteProps = {
33
53
  inputValue?: string;
34
54
  defaultInputValue?: string;
35
55
  menuTrigger?: AutocompleteMenuTrigger;
36
- style?: ViewStyle;
37
- textStyle?: TextStyle;
56
+ customAppearance?: AutocompleteCustomAppearance;
38
57
  } & AutocompletePrivateProps & AutocompleteEvents;
39
58
  type AutocompletePrivateProps = {
40
59
  _isRequired?: boolean;
@@ -58,8 +77,7 @@ type AutocompleteItemProps = {
58
77
  isDisabled?: boolean;
59
78
  isSelected?: boolean;
60
79
  isReadOnly?: boolean;
61
- style?: ViewStyle;
62
- textStyle?: TextStyle;
80
+ customAppearance?: AutocompleteItemCustomAppearance;
63
81
  onSelected?: () => void;
64
82
  };
65
83
 
@@ -5,6 +5,26 @@ import { T as ThemeColor, S as Size, R as Radius } from '../index-BOw6tbkc.js';
5
5
  type AutocompleteVariant = 'outlined' | 'flat' | 'light' | 'faded' | 'underlined';
6
6
  type AutocompleteLabelPlacement = 'inside' | 'outside' | 'outside-left' | 'outside-top';
7
7
  type AutocompleteMenuTrigger = 'focus' | 'input' | 'manual';
8
+ type AutocompleteCustomAppearance = {
9
+ /**
10
+ * Custom styles for the container
11
+ */
12
+ container?: ViewStyle;
13
+ /**
14
+ * Custom styles for the text
15
+ */
16
+ text?: TextStyle;
17
+ };
18
+ type AutocompleteItemCustomAppearance = {
19
+ /**
20
+ * Custom styles for the container
21
+ */
22
+ container?: ViewStyle;
23
+ /**
24
+ * Custom styles for the text
25
+ */
26
+ text?: TextStyle;
27
+ };
8
28
  type AutocompleteProps = {
9
29
  children: ReactNode;
10
30
  variant?: AutocompleteVariant;
@@ -33,8 +53,7 @@ type AutocompleteProps = {
33
53
  inputValue?: string;
34
54
  defaultInputValue?: string;
35
55
  menuTrigger?: AutocompleteMenuTrigger;
36
- style?: ViewStyle;
37
- textStyle?: TextStyle;
56
+ customAppearance?: AutocompleteCustomAppearance;
38
57
  } & AutocompletePrivateProps & AutocompleteEvents;
39
58
  type AutocompletePrivateProps = {
40
59
  _isRequired?: boolean;
@@ -58,8 +77,7 @@ type AutocompleteItemProps = {
58
77
  isDisabled?: boolean;
59
78
  isSelected?: boolean;
60
79
  isReadOnly?: boolean;
61
- style?: ViewStyle;
62
- textStyle?: TextStyle;
80
+ customAppearance?: AutocompleteItemCustomAppearance;
63
81
  onSelected?: () => void;
64
82
  };
65
83
 
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  Autocomplete,
3
3
  AutocompleteItem
4
- } from "../chunk-6HUSEZDJ.js";
4
+ } from "../chunk-W7JJVPK5.js";
5
+ import "../chunk-RE3CO277.js";
5
6
  import "../chunk-GBHQCAKW.js";
6
- import "../chunk-7LXW4BXD.js";
7
+ import "../chunk-SIXET7TJ.js";
7
8
  import "../chunk-NBRASCX4.js";
8
9
  export {
9
10
  Autocomplete,
@@ -0,0 +1,355 @@
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/components/avatar/index.ts
31
+ var avatar_exports = {};
32
+ __export(avatar_exports, {
33
+ Avatar: () => Avatar,
34
+ AvatarGroup: () => AvatarGroup
35
+ });
36
+ module.exports = __toCommonJS(avatar_exports);
37
+
38
+ // src/components/avatar/avatar.tsx
39
+ var import_react7 = __toESM(require("react"), 1);
40
+ var import_react_native5 = require("react-native");
41
+
42
+ // src/components/avatar/avatar.style.ts
43
+ var import_react_native = require("react-native");
44
+ var styles = import_react_native.StyleSheet.create({
45
+ container: {
46
+ overflow: "hidden",
47
+ alignItems: "center",
48
+ justifyContent: "center"
49
+ },
50
+ image: {
51
+ width: "100%",
52
+ height: "100%"
53
+ },
54
+ fallback: {
55
+ alignItems: "center",
56
+ justifyContent: "center"
57
+ },
58
+ group: {
59
+ flexDirection: "row",
60
+ alignItems: "center"
61
+ },
62
+ grid: {
63
+ flexDirection: "row",
64
+ flexWrap: "wrap",
65
+ alignItems: "flex-start"
66
+ }
67
+ });
68
+
69
+ // src/components/avatar/avatar.hook.ts
70
+ var import_react6 = require("react");
71
+ var import_core = require("@xaui/core");
72
+
73
+ // src/core/theme-context.tsx
74
+ var import_react4 = __toESM(require("react"), 1);
75
+ var import_react_native3 = require("react-native");
76
+ var import_theme = require("@xaui/core/theme");
77
+ var import_palette = require("@xaui/core/palette");
78
+
79
+ // src/core/portal/portal.tsx
80
+ var import_react2 = require("react");
81
+
82
+ // src/core/portal/portal-context.ts
83
+ var import_react = require("react");
84
+ var PortalContext = (0, import_react.createContext)(null);
85
+
86
+ // src/core/portal/portal-host.tsx
87
+ var import_react3 = __toESM(require("react"), 1);
88
+ var import_react_native2 = require("react-native");
89
+ var hostStyles = import_react_native2.StyleSheet.create({
90
+ container: {
91
+ flex: 1
92
+ }
93
+ });
94
+
95
+ // src/core/theme-context.tsx
96
+ var XUIThemeContext = (0, import_react4.createContext)(null);
97
+
98
+ // src/core/theme-hooks.ts
99
+ var import_react5 = require("react");
100
+ var import_react_native4 = require("react-native");
101
+ function useXUITheme() {
102
+ const theme = (0, import_react5.useContext)(XUIThemeContext);
103
+ if (!theme) {
104
+ throw new Error("useXUITheme must be used within XUIProvider");
105
+ }
106
+ return theme;
107
+ }
108
+
109
+ // src/core/index.ts
110
+ var import_theme2 = require("@xaui/core/theme");
111
+
112
+ // src/components/avatar/avatar.hook.ts
113
+ var sizeMap = {
114
+ xs: 24,
115
+ sm: 32,
116
+ md: 40,
117
+ lg: 48
118
+ };
119
+ function resolveAvatarSize(size) {
120
+ if (typeof size === "number") {
121
+ return size;
122
+ }
123
+ return sizeMap[size];
124
+ }
125
+ function useAvatarSizeStyles(size) {
126
+ const theme = useXUITheme();
127
+ const resolvedSize = (0, import_react6.useMemo)(() => resolveAvatarSize(size), [size]);
128
+ const fontSize = (0, import_react6.useMemo)(() => {
129
+ if (typeof size === "number") {
130
+ return Math.max(10, Math.round(size * 0.4));
131
+ }
132
+ return theme.fontSizes[size];
133
+ }, [size, theme]);
134
+ return {
135
+ size: resolvedSize,
136
+ fontSize
137
+ };
138
+ }
139
+ function useAvatarRadiusStyles(radius, size) {
140
+ const theme = useXUITheme();
141
+ return (0, import_react6.useMemo)(() => {
142
+ if (radius === "full") {
143
+ return { borderRadius: size / 2 };
144
+ }
145
+ const radii = {
146
+ none: theme.borderRadius.none,
147
+ sm: theme.borderRadius.sm,
148
+ md: theme.borderRadius.md,
149
+ lg: theme.borderRadius.lg,
150
+ full: theme.borderRadius.full
151
+ };
152
+ return { borderRadius: radii[radius] };
153
+ }, [radius, size, theme]);
154
+ }
155
+ function useAvatarColors(themeColor, isDisabled) {
156
+ const theme = useXUITheme();
157
+ const safeThemeColor = (0, import_core.getSafeThemeColor)(themeColor);
158
+ const colorScheme = theme.colors[safeThemeColor];
159
+ const backgroundColor = (0, import_react6.useMemo)(() => {
160
+ if (isDisabled) {
161
+ return theme.colors.background;
162
+ }
163
+ return colorScheme.background;
164
+ }, [colorScheme.background, isDisabled, theme.colors.background]);
165
+ const textColor = (0, import_react6.useMemo)(() => {
166
+ if (safeThemeColor === "default") {
167
+ return theme.colors.foreground;
168
+ }
169
+ return colorScheme.main;
170
+ }, [safeThemeColor, colorScheme.main, theme.colors.foreground]);
171
+ return {
172
+ backgroundColor,
173
+ textColor,
174
+ borderColor: colorScheme.main
175
+ };
176
+ }
177
+ function getDefaultInitials(name) {
178
+ const trimmed = name.trim();
179
+ if (!trimmed) {
180
+ return "";
181
+ }
182
+ const parts = trimmed.split(/\s+/);
183
+ if (parts.length === 1) {
184
+ return parts[0].slice(0, 2).toUpperCase();
185
+ }
186
+ return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
187
+ }
188
+
189
+ // src/components/avatar/avatar.tsx
190
+ var Avatar = ({
191
+ src,
192
+ name,
193
+ icon,
194
+ fallback,
195
+ size = "md",
196
+ radius = "full",
197
+ themeColor = "default",
198
+ isBordered = false,
199
+ isDisabled = false,
200
+ showFallback = false,
201
+ getInitials,
202
+ customAppearance
203
+ }) => {
204
+ const [isError, setIsError] = import_react7.default.useState(false);
205
+ const { size: resolvedSize, fontSize } = useAvatarSizeStyles(size);
206
+ const radiusStyles = useAvatarRadiusStyles(radius, resolvedSize);
207
+ const { backgroundColor, textColor, borderColor } = useAvatarColors(
208
+ themeColor,
209
+ isDisabled
210
+ );
211
+ const accessibilityLabel = name ?? "Avatar";
212
+ const shouldShowFallback = showFallback || !src || isError;
213
+ const initials = name ? (getInitials ?? getDefaultInitials)(name) : "";
214
+ return /* @__PURE__ */ import_react7.default.createElement(
215
+ import_react_native5.View,
216
+ {
217
+ style: [
218
+ styles.container,
219
+ {
220
+ width: resolvedSize,
221
+ height: resolvedSize,
222
+ backgroundColor,
223
+ opacity: isDisabled ? 0.6 : 1,
224
+ borderWidth: isBordered ? 1 : 0,
225
+ borderColor: isBordered ? borderColor : "transparent"
226
+ },
227
+ radiusStyles,
228
+ customAppearance?.container
229
+ ],
230
+ accessible: true,
231
+ accessibilityRole: "image",
232
+ accessibilityLabel
233
+ },
234
+ !shouldShowFallback && src ? /* @__PURE__ */ import_react7.default.createElement(
235
+ import_react_native5.Image,
236
+ {
237
+ source: { uri: src },
238
+ style: [styles.image, radiusStyles, customAppearance?.image],
239
+ accessibilityLabel,
240
+ onError: () => setIsError(true)
241
+ }
242
+ ) : /* @__PURE__ */ import_react7.default.createElement(import_react_native5.View, { style: [styles.fallback, { width: "100%", height: "100%" }] }, fallback ?? icon ?? /* @__PURE__ */ import_react7.default.createElement(
243
+ import_react_native5.Text,
244
+ {
245
+ style: [
246
+ {
247
+ color: textColor,
248
+ fontSize,
249
+ fontWeight: "600"
250
+ },
251
+ customAppearance?.text
252
+ ]
253
+ },
254
+ initials
255
+ ))
256
+ );
257
+ };
258
+
259
+ // src/components/avatar/avatar-group.tsx
260
+ var import_react8 = __toESM(require("react"), 1);
261
+ var import_react_native6 = require("react-native");
262
+ var AvatarGroup = ({
263
+ children,
264
+ max,
265
+ total,
266
+ size = "md",
267
+ radius = "full",
268
+ themeColor = "default",
269
+ isBordered = false,
270
+ isDisabled = false,
271
+ isGrid = false,
272
+ renderCount,
273
+ customAppearance
274
+ }) => {
275
+ const theme = useXUITheme();
276
+ const resolvedSize = resolveAvatarSize(size);
277
+ const spacing = theme.spacing.xs;
278
+ const overlap = Math.round(resolvedSize * 0.28);
279
+ const allChildren = import_react8.default.Children.toArray(children).filter(
280
+ (child) => import_react8.default.isValidElement(child)
281
+ );
282
+ const totalCount = total ?? allChildren.length;
283
+ const maxCount = max ?? totalCount;
284
+ const visibleChildren = allChildren.slice(0, maxCount);
285
+ const remaining = Math.max(0, totalCount - maxCount);
286
+ const enhanced = visibleChildren.map((child, index) => {
287
+ const childProps = child.props;
288
+ return /* @__PURE__ */ import_react8.default.createElement(
289
+ import_react_native6.View,
290
+ {
291
+ key: child.key ?? index,
292
+ style: isGrid ? { marginRight: spacing, marginBottom: spacing } : { marginLeft: index === 0 ? 0 : -overlap, zIndex: index }
293
+ },
294
+ import_react8.default.cloneElement(child, {
295
+ size: childProps.size ?? size,
296
+ radius: childProps.radius ?? radius,
297
+ themeColor: childProps.themeColor ?? themeColor,
298
+ isBordered: childProps.isBordered ?? isBordered,
299
+ isDisabled: childProps.isDisabled ?? isDisabled
300
+ })
301
+ );
302
+ });
303
+ const countNode = remaining > 0 ? renderCount?.(remaining) ?? /* @__PURE__ */ import_react8.default.createElement(
304
+ Avatar,
305
+ {
306
+ name: `+${remaining}`,
307
+ showFallback: true,
308
+ size,
309
+ radius,
310
+ themeColor,
311
+ isBordered,
312
+ isDisabled,
313
+ fallback: /* @__PURE__ */ import_react8.default.createElement(
314
+ import_react_native6.Text,
315
+ {
316
+ style: {
317
+ color: theme.colors.foreground,
318
+ fontSize: Math.max(10, Math.round(resolvedSize * 0.35)),
319
+ fontWeight: "600"
320
+ }
321
+ },
322
+ "+",
323
+ remaining
324
+ )
325
+ }
326
+ ) : null;
327
+ if (countNode) {
328
+ enhanced.push(
329
+ /* @__PURE__ */ import_react8.default.createElement(
330
+ import_react_native6.View,
331
+ {
332
+ key: "avatar-count",
333
+ style: isGrid ? { marginRight: spacing, marginBottom: spacing } : {
334
+ marginLeft: enhanced.length === 0 ? 0 : -overlap,
335
+ zIndex: enhanced.length
336
+ }
337
+ },
338
+ countNode
339
+ )
340
+ );
341
+ }
342
+ return /* @__PURE__ */ import_react8.default.createElement(
343
+ import_react_native6.View,
344
+ {
345
+ style: [isGrid ? styles.grid : styles.group, customAppearance?.container],
346
+ accessible: true
347
+ },
348
+ enhanced
349
+ );
350
+ };
351
+ // Annotate the CommonJS export names for ESM import in node:
352
+ 0 && (module.exports = {
353
+ Avatar,
354
+ AvatarGroup
355
+ });