@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.
- package/dist/accordion/index.cjs +29 -26
- package/dist/accordion/index.d.cts +48 -36
- package/dist/accordion/index.d.ts +48 -36
- package/dist/accordion/index.js +27 -24
- package/dist/alert/index.cjs +593 -0
- package/dist/alert/index.d.cts +90 -0
- package/dist/alert/index.d.ts +90 -0
- package/dist/alert/index.js +8 -0
- package/dist/autocomplete/index.cjs +6 -8
- package/dist/autocomplete/index.d.cts +22 -4
- package/dist/autocomplete/index.d.ts +22 -4
- package/dist/autocomplete/index.js +3 -2
- package/dist/avatar/index.cjs +355 -0
- package/dist/avatar/index.d.cts +123 -0
- package/dist/avatar/index.d.ts +123 -0
- package/dist/avatar/index.js +9 -0
- package/dist/badge/index.cjs +270 -0
- package/dist/badge/index.d.cts +94 -0
- package/dist/badge/index.d.ts +94 -0
- package/dist/badge/index.js +7 -0
- package/dist/button/index.cjs +4 -5
- package/dist/button/index.d.cts +17 -7
- package/dist/button/index.d.ts +17 -7
- package/dist/button/index.js +4 -5
- package/dist/chunk-4LFRYVSR.js +281 -0
- package/dist/chunk-OFYJYQ2M.js +358 -0
- package/dist/{chunk-7LXW4BXD.js → chunk-RE3CO277.js} +4 -166
- package/dist/chunk-SIXET7TJ.js +172 -0
- package/dist/{chunk-6HUSEZDJ.js → chunk-W7JJVPK5.js} +10 -10
- package/dist/chunk-XJKA22BK.js +197 -0
- package/dist/icon/index.js +4 -2
- package/dist/index.cjs +1194 -376
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +17 -2
- package/package.json +16 -1
|
@@ -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 };
|
|
@@ -1141,8 +1141,7 @@ var Autocomplete = ({
|
|
|
1141
1141
|
disableLocalFilter = false,
|
|
1142
1142
|
inputValue,
|
|
1143
1143
|
defaultInputValue,
|
|
1144
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
4
|
+
} from "../chunk-W7JJVPK5.js";
|
|
5
|
+
import "../chunk-RE3CO277.js";
|
|
5
6
|
import "../chunk-GBHQCAKW.js";
|
|
6
|
-
import "../chunk-
|
|
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
|
+
});
|