@xaui/native 0.0.31 → 0.0.32

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,282 @@
1
+ import "../chunk-DXXNBF5P.js";
2
+ import {
3
+ useBorderRadiusStyles,
4
+ useXUITheme
5
+ } from "../chunk-LTKYHG5V.js";
6
+
7
+ // src/components/snippet/snippet.tsx
8
+ import React from "react";
9
+ import { Pressable, Text, View, NativeModules } from "react-native";
10
+ import { CopyIcon } from "@xaui/icons";
11
+
12
+ // src/components/snippet/snippet.style.ts
13
+ import { StyleSheet } from "react-native";
14
+ var styles = StyleSheet.create({
15
+ container: {
16
+ flexShrink: 1,
17
+ flexBasis: "auto",
18
+ width: "100%"
19
+ },
20
+ noFullWidth: {
21
+ width: void 0,
22
+ alignSelf: "flex-start"
23
+ },
24
+ snippet: {
25
+ position: "relative",
26
+ borderWidth: 1,
27
+ overflow: "hidden"
28
+ },
29
+ content: {
30
+ minHeight: 64,
31
+ justifyContent: "center",
32
+ paddingHorizontal: 14,
33
+ paddingVertical: 12
34
+ },
35
+ text: {
36
+ fontSize: 14,
37
+ lineHeight: 20,
38
+ fontFamily: "monospace",
39
+ includeFontPadding: false
40
+ },
41
+ topInset: {
42
+ paddingTop: 44
43
+ },
44
+ bottomInset: {
45
+ paddingBottom: 44
46
+ },
47
+ copyButton: {
48
+ position: "absolute",
49
+ flexDirection: "row",
50
+ alignItems: "center",
51
+ gap: 6,
52
+ borderWidth: 1,
53
+ paddingHorizontal: 10,
54
+ paddingVertical: 6
55
+ },
56
+ top: {
57
+ top: 8
58
+ },
59
+ bottom: {
60
+ bottom: 8
61
+ },
62
+ left: {
63
+ left: 8
64
+ },
65
+ right: {
66
+ right: 8
67
+ },
68
+ copyButtonText: {
69
+ fontSize: 12,
70
+ fontWeight: "600",
71
+ includeFontPadding: false
72
+ },
73
+ disabled: {
74
+ opacity: 0.55
75
+ }
76
+ });
77
+
78
+ // src/components/snippet/snippet.hook.ts
79
+ import { useMemo } from "react";
80
+ import { getSafeThemeColor, withOpacity } from "@xaui/core";
81
+ var useSnippetColors = (themeColor, variant, isDisabled) => {
82
+ const theme = useXUITheme();
83
+ return useMemo(() => {
84
+ const safeThemeColor = getSafeThemeColor(themeColor);
85
+ const colorScheme = theme.colors[safeThemeColor];
86
+ const isDark = theme.mode === "dark";
87
+ const textColor = isDisabled ? withOpacity(theme.colors.foreground, 0.56) : theme.colors.foreground;
88
+ if (variant === "flat") {
89
+ return {
90
+ containerBackground: colorScheme.background,
91
+ containerBorder: "transparent",
92
+ text: textColor,
93
+ copyButtonBackground: withOpacity(colorScheme.main, isDark ? 0.2 : 0.14),
94
+ copyButtonBorder: "transparent",
95
+ copyButtonText: colorScheme.main
96
+ };
97
+ }
98
+ if (variant === "light") {
99
+ return {
100
+ containerBackground: withOpacity(colorScheme.main, isDark ? 0.12 : 0.08),
101
+ containerBorder: "transparent",
102
+ text: textColor,
103
+ copyButtonBackground: "transparent",
104
+ copyButtonBorder: "transparent",
105
+ copyButtonText: colorScheme.main
106
+ };
107
+ }
108
+ return {
109
+ containerBackground: theme.colors.background,
110
+ containerBorder: withOpacity(colorScheme.main, isDark ? 0.7 : 0.55),
111
+ text: textColor,
112
+ copyButtonBackground: withOpacity(colorScheme.main, isDark ? 0.16 : 0.08),
113
+ copyButtonBorder: withOpacity(colorScheme.main, isDark ? 0.48 : 0.32),
114
+ copyButtonText: colorScheme.main
115
+ };
116
+ }, [isDisabled, theme, themeColor, variant]);
117
+ };
118
+ var useCopyButtonPositionStyles = (position) => {
119
+ return useMemo(
120
+ () => ({
121
+ isTop: position.startsWith("top"),
122
+ isLeft: position.endsWith("left")
123
+ }),
124
+ [position]
125
+ );
126
+ };
127
+
128
+ // src/components/snippet/snippet.tsx
129
+ var copyText = async (text) => {
130
+ const runtime = globalThis;
131
+ const writeText = runtime.navigator?.clipboard?.writeText;
132
+ if (typeof writeText === "function") {
133
+ await writeText(text);
134
+ return true;
135
+ }
136
+ const modules = NativeModules;
137
+ const setString = modules.RNCClipboard?.setString ?? modules.Clipboard?.setString;
138
+ if (typeof setString === "function") {
139
+ setString(text);
140
+ return true;
141
+ }
142
+ return false;
143
+ };
144
+ var Snippet = ({
145
+ value,
146
+ themeColor = "primary",
147
+ variant = "outlined",
148
+ radius = "md",
149
+ copyButtonPosition = "top-right",
150
+ copyLabel = "Copy",
151
+ copiedLabel = "Copied",
152
+ copyResetDelay = 1500,
153
+ fullWidth = true,
154
+ isDisabled = false,
155
+ numberOfLines,
156
+ fontSize = 14,
157
+ fontWeight = "400",
158
+ onCopy,
159
+ customAppearance
160
+ }) => {
161
+ const [isCopied, setIsCopied] = React.useState(false);
162
+ const resetTimerRef = React.useRef(null);
163
+ const radiusStyles = useBorderRadiusStyles(radius);
164
+ const colors = useSnippetColors(themeColor, variant, isDisabled);
165
+ const { isTop, isLeft } = useCopyButtonPositionStyles(copyButtonPosition);
166
+ React.useEffect(() => {
167
+ return () => {
168
+ if (resetTimerRef.current) {
169
+ clearTimeout(resetTimerRef.current);
170
+ }
171
+ };
172
+ }, []);
173
+ const handleCopy = React.useCallback(async () => {
174
+ if (isDisabled) {
175
+ return;
176
+ }
177
+ let isSuccess = false;
178
+ try {
179
+ isSuccess = await copyText(value);
180
+ setIsCopied(isSuccess);
181
+ } catch {
182
+ setIsCopied(false);
183
+ }
184
+ onCopy?.(value, isSuccess);
185
+ if (!isSuccess) {
186
+ return;
187
+ }
188
+ if (resetTimerRef.current) {
189
+ clearTimeout(resetTimerRef.current);
190
+ }
191
+ resetTimerRef.current = setTimeout(() => {
192
+ setIsCopied(false);
193
+ }, copyResetDelay);
194
+ }, [copyResetDelay, isDisabled, onCopy, value]);
195
+ return /* @__PURE__ */ React.createElement(
196
+ View,
197
+ {
198
+ style: [
199
+ styles.container,
200
+ !fullWidth && styles.noFullWidth,
201
+ isDisabled && styles.disabled,
202
+ customAppearance?.container
203
+ ]
204
+ },
205
+ /* @__PURE__ */ React.createElement(
206
+ View,
207
+ {
208
+ style: [
209
+ styles.snippet,
210
+ radiusStyles,
211
+ {
212
+ backgroundColor: colors.containerBackground,
213
+ borderColor: colors.containerBorder
214
+ }
215
+ ]
216
+ },
217
+ /* @__PURE__ */ React.createElement(
218
+ Pressable,
219
+ {
220
+ onPress: handleCopy,
221
+ accessibilityRole: "button",
222
+ accessibilityLabel: isCopied ? copiedLabel : copyLabel,
223
+ disabled: isDisabled,
224
+ style: [
225
+ styles.copyButton,
226
+ radiusStyles,
227
+ isTop ? styles.top : styles.bottom,
228
+ isLeft ? styles.left : styles.right,
229
+ {
230
+ backgroundColor: colors.copyButtonBackground,
231
+ borderColor: colors.copyButtonBorder
232
+ },
233
+ customAppearance?.copyButton
234
+ ]
235
+ },
236
+ /* @__PURE__ */ React.createElement(CopyIcon, { size: 14, color: colors.copyButtonText }),
237
+ /* @__PURE__ */ React.createElement(
238
+ Text,
239
+ {
240
+ style: [
241
+ styles.copyButtonText,
242
+ { color: colors.copyButtonText },
243
+ customAppearance?.copyButtonText
244
+ ]
245
+ },
246
+ isCopied ? copiedLabel : copyLabel
247
+ )
248
+ ),
249
+ /* @__PURE__ */ React.createElement(
250
+ View,
251
+ {
252
+ style: [
253
+ styles.content,
254
+ isTop ? styles.topInset : styles.bottomInset,
255
+ customAppearance?.content
256
+ ]
257
+ },
258
+ /* @__PURE__ */ React.createElement(
259
+ Text,
260
+ {
261
+ selectable: true,
262
+ numberOfLines,
263
+ style: [
264
+ styles.text,
265
+ {
266
+ color: colors.text,
267
+ fontSize,
268
+ lineHeight: Math.round(fontSize * 1.45),
269
+ fontWeight
270
+ },
271
+ customAppearance?.text
272
+ ]
273
+ },
274
+ value
275
+ )
276
+ )
277
+ )
278
+ );
279
+ };
280
+ export {
281
+ Snippet
282
+ };
@@ -18,24 +18,24 @@ var _reactnativereanimated = require('react-native-reanimated'); var _reactnativ
18
18
  var _core = require('@xaui/core');
19
19
  var variantMap = {
20
20
  floating: {
21
- containerHeight: 72,
21
+ containerHeight: 68,
22
22
  containerWidth: "auto",
23
23
  iconSize: 26,
24
24
  actionSize: 40,
25
25
  borderRadius: 56,
26
26
  paddingHorizontal: 16,
27
- paddingVertical: 16,
27
+ paddingVertical: 14,
28
28
  gap: 0,
29
29
  isElevated: true
30
30
  },
31
31
  docked: {
32
- containerHeight: 72,
32
+ containerHeight: 68,
33
33
  containerWidth: "auto",
34
34
  iconSize: 26,
35
35
  actionSize: 40,
36
36
  borderRadius: 0,
37
37
  paddingHorizontal: 16,
38
- paddingVertical: 16,
38
+ paddingVertical: 14,
39
39
  gap: 0,
40
40
  isElevated: false
41
41
  },
@@ -46,7 +46,7 @@ var variantMap = {
46
46
  actionSize: 40,
47
47
  borderRadius: 0,
48
48
  paddingHorizontal: 16,
49
- paddingVertical: 16,
49
+ paddingVertical: 14,
50
50
  gap: 0,
51
51
  isElevated: false
52
52
  }
@@ -177,18 +177,25 @@ var Toolbar = ({
177
177
  );
178
178
  const opacityValue = _reactnativereanimated.useSharedValue.call(void 0, isVisible ? 1 : 0);
179
179
  _react.useEffect.call(void 0, () => {
180
+ const nextTranslate = isVisible ? 0 : getInitialTranslate(position);
180
181
  if (isVisible) {
181
- translateValue.value = _reactnativereanimated.withSpring.call(void 0, 0, {
182
- damping: 20,
183
- stiffness: 300
182
+ translateValue.value = _reactnativereanimated.withTiming.call(void 0, nextTranslate, {
183
+ duration: 220,
184
+ easing: _reactnativereanimated.Easing.out(_reactnativereanimated.Easing.cubic)
185
+ });
186
+ opacityValue.value = _reactnativereanimated.withTiming.call(void 0, 1, {
187
+ duration: 200,
188
+ easing: _reactnativereanimated.Easing.out(_reactnativereanimated.Easing.quad)
184
189
  });
185
- opacityValue.value = _reactnativereanimated.withTiming.call(void 0, 1, { duration: 200 });
186
190
  } else {
187
- translateValue.value = _reactnativereanimated.withSpring.call(void 0, getInitialTranslate(position), {
188
- damping: 20,
189
- stiffness: 300
191
+ translateValue.value = _reactnativereanimated.withTiming.call(void 0, nextTranslate, {
192
+ duration: 180,
193
+ easing: _reactnativereanimated.Easing.in(_reactnativereanimated.Easing.cubic)
194
+ });
195
+ opacityValue.value = _reactnativereanimated.withTiming.call(void 0, 0, {
196
+ duration: 150,
197
+ easing: _reactnativereanimated.Easing.in(_reactnativereanimated.Easing.quad)
190
198
  });
191
- opacityValue.value = _reactnativereanimated.withTiming.call(void 0, 0, { duration: 200 });
192
199
  }
193
200
  }, [isVisible, position, translateValue, opacityValue]);
194
201
  const animatedStyle = _reactnativereanimated.useAnimatedStyle.call(void 0, () => {
@@ -269,13 +276,13 @@ var Toolbar = ({
269
276
  function getInitialTranslate(position) {
270
277
  switch (position) {
271
278
  case "top":
272
- return -100;
279
+ return -24;
273
280
  case "bottom":
274
- return 100;
281
+ return 24;
275
282
  case "left":
276
- return -100;
283
+ return -24;
277
284
  case "right":
278
- return 100;
285
+ return 24;
279
286
  default:
280
287
  return 0;
281
288
  }
@@ -7,9 +7,9 @@ import {
7
7
  import React, { useEffect } from "react";
8
8
  import { View } from "react-native";
9
9
  import Animated, {
10
+ Easing,
10
11
  useAnimatedStyle,
11
12
  useSharedValue,
12
- withSpring,
13
13
  withTiming
14
14
  } from "react-native-reanimated";
15
15
 
@@ -18,24 +18,24 @@ import { useMemo } from "react";
18
18
  import { getSafeThemeColor, withOpacity } from "@xaui/core";
19
19
  var variantMap = {
20
20
  floating: {
21
- containerHeight: 72,
21
+ containerHeight: 68,
22
22
  containerWidth: "auto",
23
23
  iconSize: 26,
24
24
  actionSize: 40,
25
25
  borderRadius: 56,
26
26
  paddingHorizontal: 16,
27
- paddingVertical: 16,
27
+ paddingVertical: 14,
28
28
  gap: 0,
29
29
  isElevated: true
30
30
  },
31
31
  docked: {
32
- containerHeight: 72,
32
+ containerHeight: 68,
33
33
  containerWidth: "auto",
34
34
  iconSize: 26,
35
35
  actionSize: 40,
36
36
  borderRadius: 0,
37
37
  paddingHorizontal: 16,
38
- paddingVertical: 16,
38
+ paddingVertical: 14,
39
39
  gap: 0,
40
40
  isElevated: false
41
41
  },
@@ -46,7 +46,7 @@ var variantMap = {
46
46
  actionSize: 40,
47
47
  borderRadius: 0,
48
48
  paddingHorizontal: 16,
49
- paddingVertical: 16,
49
+ paddingVertical: 14,
50
50
  gap: 0,
51
51
  isElevated: false
52
52
  }
@@ -177,18 +177,25 @@ var Toolbar = ({
177
177
  );
178
178
  const opacityValue = useSharedValue(isVisible ? 1 : 0);
179
179
  useEffect(() => {
180
+ const nextTranslate = isVisible ? 0 : getInitialTranslate(position);
180
181
  if (isVisible) {
181
- translateValue.value = withSpring(0, {
182
- damping: 20,
183
- stiffness: 300
182
+ translateValue.value = withTiming(nextTranslate, {
183
+ duration: 220,
184
+ easing: Easing.out(Easing.cubic)
185
+ });
186
+ opacityValue.value = withTiming(1, {
187
+ duration: 200,
188
+ easing: Easing.out(Easing.quad)
184
189
  });
185
- opacityValue.value = withTiming(1, { duration: 200 });
186
190
  } else {
187
- translateValue.value = withSpring(getInitialTranslate(position), {
188
- damping: 20,
189
- stiffness: 300
191
+ translateValue.value = withTiming(nextTranslate, {
192
+ duration: 180,
193
+ easing: Easing.in(Easing.cubic)
194
+ });
195
+ opacityValue.value = withTiming(0, {
196
+ duration: 150,
197
+ easing: Easing.in(Easing.quad)
190
198
  });
191
- opacityValue.value = withTiming(0, { duration: 200 });
192
199
  }
193
200
  }, [isVisible, position, translateValue, opacityValue]);
194
201
  const animatedStyle = useAnimatedStyle(() => {
@@ -269,13 +276,13 @@ var Toolbar = ({
269
276
  function getInitialTranslate(position) {
270
277
  switch (position) {
271
278
  case "top":
272
- return -100;
279
+ return -24;
273
280
  case "bottom":
274
- return 100;
281
+ return 24;
275
282
  case "left":
276
- return -100;
283
+ return -24;
277
284
  case "right":
278
- return 100;
285
+ return 24;
279
286
  default:
280
287
  return 0;
281
288
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaui/native",
3
- "version": "0.0.31",
3
+ "version": "0.0.32",
4
4
  "description": "Flutter-inspired React Native UI components with native animations powered by React Native Reanimated",
5
5
  "keywords": [
6
6
  "react-native",
@@ -67,6 +67,11 @@
67
67
  "import": "./dist/select/index.js",
68
68
  "require": "./dist/select/index.js"
69
69
  },
70
+ "./dialog": {
71
+ "types": "./dist/dialog/index.d.ts",
72
+ "import": "./dist/dialog/index.js",
73
+ "require": "./dist/dialog/index.js"
74
+ },
70
75
  "./divider": {
71
76
  "types": "./dist/divider/index.d.ts",
72
77
  "import": "./dist/divider/index.js",
@@ -226,6 +231,11 @@
226
231
  "types": "./dist/snackbar/index.d.ts",
227
232
  "import": "./dist/snackbar/index.js",
228
233
  "require": "./dist/snackbar/index.js"
234
+ },
235
+ "./snippet": {
236
+ "types": "./dist/snippet/index.d.ts",
237
+ "import": "./dist/snippet/index.js",
238
+ "require": "./dist/snippet/index.js"
229
239
  }
230
240
  },
231
241
  "files": [