@streamplace/components 0.7.26 → 0.7.29
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/components/chat/chat-box.js +2 -2
- package/dist/components/chat/chat.js +1 -1
- package/dist/components/mobile-player/ui/autoplay-button.js +1 -0
- package/dist/components/mobile-player/ui/viewer-context-menu.js +1 -1
- package/dist/components/mobile-player/ui/viewer-loading-overlay.js +2 -2
- package/dist/components/mobile-player/use-webrtc.js +37 -1
- package/dist/components/mobile-player/video.native.js +10 -1
- package/dist/components/ui/button.js +107 -155
- package/dist/components/ui/dialog.js +83 -116
- package/dist/components/ui/dropdown.js +41 -18
- package/dist/components/ui/input.js +53 -128
- package/dist/components/ui/primitives/button.js +0 -2
- package/dist/components/ui/primitives/modal.js +2 -2
- package/dist/components/ui/primitives/text.js +48 -8
- package/dist/components/ui/text.js +37 -66
- package/dist/components/ui/toast.js +78 -40
- package/dist/components/ui/view.js +28 -41
- package/dist/crypto-polyfill.js +0 -0
- package/dist/crypto-polyfill.native.js +24 -0
- package/dist/index.js +1 -0
- package/dist/lib/theme/index.js +1 -2
- package/dist/lib/theme/theme.js +106 -54
- package/dist/lib/theme/tokens.js +94 -1
- package/dist/livestream-store/chat.js +0 -2
- package/dist/livestream-store/stream-key.js +1 -1
- package/dist/player-store/player-provider.js +10 -2
- package/dist/player-store/single-player-provider.js +1 -1
- package/dist/streamplace-store/stream.js +1 -1
- package/dist/ui/index.js +2 -3
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/package.json +3 -2
- package/src/components/chat/chat-box.tsx +6 -3
- package/src/components/chat/chat.tsx +1 -0
- package/src/components/mobile-player/ui/autoplay-button.tsx +1 -0
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +2 -2
- package/src/components/mobile-player/ui/viewer-loading-overlay.tsx +2 -2
- package/src/components/mobile-player/use-webrtc.tsx +41 -1
- package/src/components/mobile-player/video.native.tsx +19 -4
- package/src/components/ui/button.tsx +110 -172
- package/src/components/ui/dialog.tsx +96 -138
- package/src/components/ui/dropdown.tsx +60 -22
- package/src/components/ui/input.tsx +57 -144
- package/src/components/ui/primitives/button.tsx +0 -2
- package/src/components/ui/primitives/modal.tsx +0 -2
- package/src/components/ui/primitives/text.tsx +51 -8
- package/src/components/ui/text.tsx +42 -67
- package/src/components/ui/toast.tsx +108 -90
- package/src/components/ui/view.tsx +27 -41
- package/src/crypto-polyfill.native.tsx +24 -0
- package/src/crypto-polyfill.tsx +0 -0
- package/src/index.tsx +2 -0
- package/src/lib/theme/index.ts +0 -2
- package/src/lib/theme/theme.tsx +179 -72
- package/src/lib/theme/tokens.ts +97 -0
- package/src/livestream-store/chat.tsx +0 -3
- package/src/livestream-store/stream-key.tsx +1 -1
- package/src/player-store/player-provider.tsx +13 -1
- package/src/player-store/single-player-provider.tsx +1 -1
- package/src/streamplace-store/stream.tsx +1 -1
- package/src/ui/index.ts +0 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useRootContext } from "@rn-primitives/dropdown-menu";
|
|
2
|
-
import {
|
|
2
|
+
import { Menu } from "lucide-react-native";
|
|
3
3
|
import { Platform, View } from "react-native";
|
|
4
4
|
import { colors } from "../../../lib/theme";
|
|
5
5
|
import { useLivestreamStore } from "../../../livestream-store";
|
|
@@ -57,7 +57,7 @@ export function ContextMenu({
|
|
|
57
57
|
return (
|
|
58
58
|
<DropdownMenu>
|
|
59
59
|
<DropdownMenuTrigger>
|
|
60
|
-
<
|
|
60
|
+
<Menu color={colors.gray[200]} />
|
|
61
61
|
</DropdownMenuTrigger>
|
|
62
62
|
<Portal container={dropdownPortalContainer}>
|
|
63
63
|
<DropdownMenuContent side="top" align="end">
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
|
|
16
16
|
export function ViewerLoadingOverlay() {
|
|
17
17
|
const status = usePlayerStore((x) => x.status);
|
|
18
|
-
const theme = useTheme();
|
|
18
|
+
const { theme, zero: zt } = useTheme();
|
|
19
19
|
const opacity = useSharedValue(0);
|
|
20
20
|
|
|
21
21
|
useEffect(() => {
|
|
@@ -42,7 +42,7 @@ export function ViewerLoadingOverlay() {
|
|
|
42
42
|
|
|
43
43
|
let spinner = <Loader size="large" />;
|
|
44
44
|
if (status === PlayerStatus.PAUSE) {
|
|
45
|
-
spinner = <Play size="$12" color={theme.
|
|
45
|
+
spinner = <Play size="$12" color={theme.colors.foreground} />;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
return (
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import * as sdpTransform from "sdp-transform";
|
|
2
3
|
import { PlayerStatus, usePlayerStore, useStreamKey } from "../..";
|
|
3
4
|
import { RTCPeerConnection, RTCSessionDescription } from "./webrtc-primitives";
|
|
4
5
|
|
|
@@ -107,6 +108,13 @@ export async function negotiateConnectionWithClientOffer(
|
|
|
107
108
|
offerToReceiveAudio: true,
|
|
108
109
|
offerToReceiveVideo: true,
|
|
109
110
|
});
|
|
111
|
+
if (!offer.sdp) {
|
|
112
|
+
throw Error("no SDP in offer");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const newSDP = forceStereoAudio(offer.sdp);
|
|
116
|
+
|
|
117
|
+
offer.sdp = newSDP;
|
|
110
118
|
/** https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription */
|
|
111
119
|
await peerConnection.setLocalDescription(offer);
|
|
112
120
|
|
|
@@ -205,6 +213,11 @@ export function useWebRTCIngest({
|
|
|
205
213
|
(x) => x.setIngestConnectionState,
|
|
206
214
|
);
|
|
207
215
|
const storedKey = useStreamKey();
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
if (storedKey?.error) {
|
|
218
|
+
console.error("error creating stream key", storedKey.error);
|
|
219
|
+
}
|
|
220
|
+
}, [storedKey?.error]);
|
|
208
221
|
const [peerConnection, setPeerConnection] =
|
|
209
222
|
useState<RTCPeerConnection | null>(null);
|
|
210
223
|
|
|
@@ -249,7 +262,11 @@ export function useWebRTCIngest({
|
|
|
249
262
|
});
|
|
250
263
|
|
|
251
264
|
peerConnection.addEventListener("track", (ev) => {
|
|
252
|
-
console.log(
|
|
265
|
+
console.log(
|
|
266
|
+
`got peerconnection track with ${ev.track.kind}`,
|
|
267
|
+
ev.track.id,
|
|
268
|
+
);
|
|
269
|
+
// console.log(ev);
|
|
253
270
|
});
|
|
254
271
|
|
|
255
272
|
setPeerConnection(peerConnection);
|
|
@@ -288,3 +305,26 @@ export function useWebRTCIngest({
|
|
|
288
305
|
|
|
289
306
|
return [mediaStream, setMediaStream];
|
|
290
307
|
}
|
|
308
|
+
|
|
309
|
+
export function forceStereoAudio(sdp: string): string {
|
|
310
|
+
const parsedSDP = sdpTransform.parse(sdp);
|
|
311
|
+
const audioMedia = parsedSDP.media.find((m) => m.type === "audio");
|
|
312
|
+
if (!audioMedia) {
|
|
313
|
+
throw Error("no audio media in SDP");
|
|
314
|
+
}
|
|
315
|
+
const opusCodec = audioMedia.rtp.find((c) => c.codec === "opus");
|
|
316
|
+
if (!opusCodec) {
|
|
317
|
+
throw Error("no opus codec in SDP");
|
|
318
|
+
}
|
|
319
|
+
const opusFMTP = audioMedia.fmtp.find((c) => c.payload === opusCodec.payload);
|
|
320
|
+
if (!opusFMTP) {
|
|
321
|
+
throw Error("no opus fmtp in SDP");
|
|
322
|
+
}
|
|
323
|
+
const opusParams = sdpTransform.parseParams(opusFMTP.config);
|
|
324
|
+
opusParams.stereo = 1;
|
|
325
|
+
const newParams = Object.entries(opusParams)
|
|
326
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
327
|
+
.join(";");
|
|
328
|
+
opusFMTP.config = newParams;
|
|
329
|
+
return sdpTransform.write(parsedSDP);
|
|
330
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
-
import { View } from "react-native";
|
|
2
|
+
import { Text, View } from "react-native";
|
|
3
3
|
import { VideoNativeProps } from "./props";
|
|
4
4
|
|
|
5
5
|
let importPromise: Promise<typeof import("./video-async.native")> | null = null;
|
|
@@ -13,12 +13,27 @@ export default function VideoNative(props: VideoNativeProps) {
|
|
|
13
13
|
typeof import("./video-async.native") | null
|
|
14
14
|
>(null);
|
|
15
15
|
|
|
16
|
+
const [error, setError] = useState<string | null>(null);
|
|
17
|
+
|
|
16
18
|
useEffect(() => {
|
|
17
|
-
importPromise
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
importPromise
|
|
20
|
+
?.then((module) => {
|
|
21
|
+
setVideoNativeModule(module);
|
|
22
|
+
})
|
|
23
|
+
.catch((err) => {
|
|
24
|
+
setError(err.message);
|
|
25
|
+
});
|
|
20
26
|
}, []);
|
|
21
27
|
|
|
28
|
+
if (error) {
|
|
29
|
+
console.error(error);
|
|
30
|
+
return (
|
|
31
|
+
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
|
|
32
|
+
<Text>{error}</Text>
|
|
33
|
+
</View>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
22
37
|
if (!videoNativeModule) {
|
|
23
38
|
return <View></View>;
|
|
24
39
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
2
|
import React, { forwardRef, useMemo } from "react";
|
|
3
|
-
import { ActivityIndicator
|
|
3
|
+
import { ActivityIndicator } from "react-native";
|
|
4
4
|
import { useTheme } from "../../lib/theme/theme";
|
|
5
|
-
import * as
|
|
5
|
+
import * as zero from "../../ui";
|
|
6
6
|
import { ButtonPrimitive, ButtonPrimitiveProps } from "./primitives/button";
|
|
7
7
|
import { TextPrimitive } from "./primitives/text";
|
|
8
8
|
|
|
@@ -57,44 +57,117 @@ export const Button = forwardRef<any, ButtonProps>(
|
|
|
57
57
|
},
|
|
58
58
|
ref,
|
|
59
59
|
) => {
|
|
60
|
-
const {
|
|
60
|
+
const { zero: zt, icons } = useTheme();
|
|
61
61
|
|
|
62
|
-
//
|
|
63
|
-
const styles = useMemo(() => createStyles(theme), [theme]);
|
|
64
|
-
|
|
65
|
-
// Get variant styles
|
|
62
|
+
// Get variant styles using theme.zero
|
|
66
63
|
const buttonStyle = useMemo(() => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
switch (variant) {
|
|
65
|
+
case "primary":
|
|
66
|
+
return zt.button.primary;
|
|
67
|
+
case "secondary":
|
|
68
|
+
return zt.button.secondary;
|
|
69
|
+
case "outline":
|
|
70
|
+
return zt.button.outline;
|
|
71
|
+
case "ghost":
|
|
72
|
+
return zt.button.ghost;
|
|
73
|
+
case "destructive":
|
|
74
|
+
return [zt.bg.destructive, zero.shadows.sm];
|
|
75
|
+
case "success":
|
|
76
|
+
return [zt.bg.success, zero.shadows.sm];
|
|
77
|
+
default:
|
|
78
|
+
return zt.button.primary;
|
|
79
|
+
}
|
|
80
|
+
}, [variant, zt]);
|
|
71
81
|
|
|
72
|
-
// Get
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
// Get text styles using theme.zero
|
|
83
|
+
const textStyle = useMemo(() => {
|
|
84
|
+
switch (variant) {
|
|
85
|
+
case "primary":
|
|
86
|
+
return [zt.text.primaryForeground, { fontWeight: "600" }];
|
|
87
|
+
case "secondary":
|
|
88
|
+
return [zt.text.secondaryForeground, { fontWeight: "500" }];
|
|
89
|
+
case "outline":
|
|
90
|
+
case "ghost":
|
|
91
|
+
return [zt.text.foreground, { fontWeight: "500" }];
|
|
92
|
+
case "destructive":
|
|
93
|
+
return [zt.text.destructiveForeground, { fontWeight: "600" }];
|
|
94
|
+
case "success":
|
|
95
|
+
return [zt.text.successForeground, { fontWeight: "600" }];
|
|
96
|
+
default:
|
|
97
|
+
return [zt.text.primaryForeground, { fontWeight: "600" }];
|
|
98
|
+
}
|
|
99
|
+
}, [variant, zt]);
|
|
78
100
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
// Size styles using theme.zero
|
|
102
|
+
const sizeStyles = useMemo(() => {
|
|
103
|
+
switch (size) {
|
|
104
|
+
case "sm":
|
|
105
|
+
return {
|
|
106
|
+
button: [
|
|
107
|
+
zero.px[3],
|
|
108
|
+
zero.py[2],
|
|
109
|
+
{ borderRadius: zero.borderRadius.md },
|
|
110
|
+
],
|
|
111
|
+
inner: { gap: 4 },
|
|
112
|
+
text: zt.text.sm,
|
|
113
|
+
};
|
|
114
|
+
case "lg":
|
|
115
|
+
return {
|
|
116
|
+
button: [
|
|
117
|
+
zero.px[6],
|
|
118
|
+
zero.py[3],
|
|
119
|
+
{ borderRadius: zero.borderRadius.md },
|
|
120
|
+
],
|
|
121
|
+
inner: { gap: 8 },
|
|
122
|
+
text: zt.text.lg,
|
|
123
|
+
};
|
|
124
|
+
case "xl":
|
|
125
|
+
return {
|
|
126
|
+
button: [
|
|
127
|
+
zero.px[8],
|
|
128
|
+
zero.py[4],
|
|
129
|
+
{ borderRadius: zero.borderRadius.lg },
|
|
130
|
+
],
|
|
131
|
+
inner: { gap: 12 },
|
|
132
|
+
text: zt.text.xl,
|
|
133
|
+
};
|
|
134
|
+
case "pill":
|
|
135
|
+
return {
|
|
136
|
+
button: [
|
|
137
|
+
zero.px[4],
|
|
138
|
+
zero.py[2],
|
|
139
|
+
{ borderRadius: zero.borderRadius.full },
|
|
140
|
+
],
|
|
141
|
+
inner: { gap: 4 },
|
|
142
|
+
text: zt.text.sm,
|
|
143
|
+
};
|
|
144
|
+
case "md":
|
|
145
|
+
default:
|
|
146
|
+
return {
|
|
147
|
+
button: [
|
|
148
|
+
zero.px[4],
|
|
149
|
+
zero.py[2],
|
|
150
|
+
{ borderRadius: zero.borderRadius.md },
|
|
151
|
+
],
|
|
152
|
+
inner: { gap: 6 },
|
|
153
|
+
text: zt.text.md,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}, [size, zt]);
|
|
84
157
|
|
|
85
158
|
const iconSize = React.useMemo(() => {
|
|
86
159
|
switch (size) {
|
|
87
160
|
case "sm":
|
|
88
|
-
return
|
|
161
|
+
return icons.size.sm;
|
|
89
162
|
case "lg":
|
|
90
|
-
return
|
|
163
|
+
return icons.size.lg;
|
|
91
164
|
case "xl":
|
|
92
|
-
return
|
|
165
|
+
return icons.size.xl;
|
|
93
166
|
case "md":
|
|
94
167
|
default:
|
|
95
|
-
return
|
|
168
|
+
return icons.size.md;
|
|
96
169
|
}
|
|
97
|
-
}, [size]);
|
|
170
|
+
}, [size, icons]);
|
|
98
171
|
|
|
99
172
|
const spinnerSize = useMemo(() => {
|
|
100
173
|
switch (size) {
|
|
@@ -113,24 +186,26 @@ export const Button = forwardRef<any, ButtonProps>(
|
|
|
113
186
|
switch (variant) {
|
|
114
187
|
case "outline":
|
|
115
188
|
case "ghost":
|
|
116
|
-
return
|
|
189
|
+
return icons.color.primary;
|
|
117
190
|
case "secondary":
|
|
118
|
-
return
|
|
191
|
+
return icons.color.secondary;
|
|
119
192
|
case "destructive":
|
|
120
|
-
return
|
|
193
|
+
return icons.color.destructive;
|
|
194
|
+
case "success":
|
|
195
|
+
return icons.color.success;
|
|
121
196
|
default:
|
|
122
|
-
return
|
|
197
|
+
return icons.color.default;
|
|
123
198
|
}
|
|
124
|
-
}, [variant,
|
|
199
|
+
}, [variant, icons]);
|
|
125
200
|
|
|
126
201
|
return (
|
|
127
202
|
<ButtonPrimitive.Root
|
|
128
203
|
ref={ref}
|
|
129
204
|
disabled={disabled || loading}
|
|
130
|
-
style={[buttonStyle, style]}
|
|
205
|
+
style={[buttonStyle, sizeStyles.button, style]}
|
|
131
206
|
{...props}
|
|
132
207
|
>
|
|
133
|
-
<ButtonPrimitive.Content style={
|
|
208
|
+
<ButtonPrimitive.Content style={sizeStyles.inner}>
|
|
134
209
|
{loading && !leftIcon ? (
|
|
135
210
|
<ButtonPrimitive.Icon position="left">
|
|
136
211
|
<ActivityIndicator size={spinnerSize} color={spinnerColor} />
|
|
@@ -144,7 +219,7 @@ export const Button = forwardRef<any, ButtonProps>(
|
|
|
144
219
|
</ButtonPrimitive.Icon>
|
|
145
220
|
) : null}
|
|
146
221
|
|
|
147
|
-
<TextPrimitive.Root style={textStyle}>
|
|
222
|
+
<TextPrimitive.Root style={[textStyle, sizeStyles.text]}>
|
|
148
223
|
{loading && loadingText ? loadingText : children}
|
|
149
224
|
</TextPrimitive.Root>
|
|
150
225
|
|
|
@@ -168,142 +243,5 @@ export const Button = forwardRef<any, ButtonProps>(
|
|
|
168
243
|
|
|
169
244
|
Button.displayName = "Button";
|
|
170
245
|
|
|
171
|
-
// Create theme-based styles
|
|
172
|
-
function createStyles(theme: any) {
|
|
173
|
-
return StyleSheet.create({
|
|
174
|
-
// Variant styles
|
|
175
|
-
primaryButton: {
|
|
176
|
-
backgroundColor: theme.colors.primary,
|
|
177
|
-
borderWidth: 0,
|
|
178
|
-
...theme.shadows.sm,
|
|
179
|
-
},
|
|
180
|
-
primaryText: {
|
|
181
|
-
color: theme.colors.primaryForeground,
|
|
182
|
-
fontWeight: "600",
|
|
183
|
-
},
|
|
184
|
-
|
|
185
|
-
secondaryButton: {
|
|
186
|
-
backgroundColor: theme.colors.secondary,
|
|
187
|
-
borderWidth: 0,
|
|
188
|
-
},
|
|
189
|
-
secondaryText: {
|
|
190
|
-
color: theme.colors.secondaryForeground,
|
|
191
|
-
fontWeight: "500",
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
outlineButton: {
|
|
195
|
-
backgroundColor: "transparent",
|
|
196
|
-
borderWidth: 1,
|
|
197
|
-
borderColor: theme.colors.border,
|
|
198
|
-
},
|
|
199
|
-
outlineText: {
|
|
200
|
-
color: theme.colors.foreground,
|
|
201
|
-
fontWeight: "500",
|
|
202
|
-
},
|
|
203
|
-
|
|
204
|
-
ghostButton: {
|
|
205
|
-
backgroundColor: "transparent",
|
|
206
|
-
borderWidth: 0,
|
|
207
|
-
},
|
|
208
|
-
ghostText: {
|
|
209
|
-
color: theme.colors.foreground,
|
|
210
|
-
fontWeight: "500",
|
|
211
|
-
},
|
|
212
|
-
|
|
213
|
-
destructiveButton: {
|
|
214
|
-
backgroundColor: theme.colors.destructive,
|
|
215
|
-
borderWidth: 0,
|
|
216
|
-
...theme.shadows.sm,
|
|
217
|
-
},
|
|
218
|
-
destructiveText: {
|
|
219
|
-
color: theme.colors.destructiveForeground,
|
|
220
|
-
fontWeight: "600",
|
|
221
|
-
},
|
|
222
|
-
|
|
223
|
-
successButton: {
|
|
224
|
-
backgroundColor: theme.colors.success,
|
|
225
|
-
borderWidth: 0,
|
|
226
|
-
...theme.shadows.sm,
|
|
227
|
-
},
|
|
228
|
-
successText: {
|
|
229
|
-
color: theme.colors.successForeground,
|
|
230
|
-
fontWeight: "600",
|
|
231
|
-
},
|
|
232
|
-
|
|
233
|
-
pillButton: {
|
|
234
|
-
paddingHorizontal: theme.spacing[2],
|
|
235
|
-
paddingVertical: theme.spacing[1],
|
|
236
|
-
borderRadius: tokens.borderRadius.full,
|
|
237
|
-
minHeight: tokens.touchTargets.minimum / 2,
|
|
238
|
-
},
|
|
239
|
-
|
|
240
|
-
pillText: {
|
|
241
|
-
color: theme.colors.primaryForeground,
|
|
242
|
-
fontWeight: "400",
|
|
243
|
-
},
|
|
244
|
-
|
|
245
|
-
// Size styles
|
|
246
|
-
smButton: {
|
|
247
|
-
paddingHorizontal: theme.spacing[3],
|
|
248
|
-
paddingVertical: theme.spacing[2],
|
|
249
|
-
borderRadius: tokens.borderRadius.md,
|
|
250
|
-
minHeight: tokens.touchTargets.minimum,
|
|
251
|
-
gap: theme.spacing[1],
|
|
252
|
-
},
|
|
253
|
-
smButtonInner: {
|
|
254
|
-
gap: theme.spacing[1],
|
|
255
|
-
},
|
|
256
|
-
smText: {
|
|
257
|
-
fontSize: 14,
|
|
258
|
-
lineHeight: 16,
|
|
259
|
-
},
|
|
260
|
-
|
|
261
|
-
mdButton: {
|
|
262
|
-
paddingHorizontal: theme.spacing[4],
|
|
263
|
-
paddingVertical: theme.spacing[3],
|
|
264
|
-
borderRadius: tokens.borderRadius.md,
|
|
265
|
-
minHeight: tokens.touchTargets.minimum,
|
|
266
|
-
gap: theme.spacing[2],
|
|
267
|
-
},
|
|
268
|
-
mdButtonInner: {
|
|
269
|
-
gap: theme.spacing[2],
|
|
270
|
-
},
|
|
271
|
-
mdText: {
|
|
272
|
-
fontSize: 16,
|
|
273
|
-
lineHeight: 18,
|
|
274
|
-
},
|
|
275
|
-
|
|
276
|
-
lgButton: {
|
|
277
|
-
paddingHorizontal: theme.spacing[6],
|
|
278
|
-
paddingVertical: theme.spacing[4],
|
|
279
|
-
borderRadius: tokens.borderRadius.md,
|
|
280
|
-
minHeight: tokens.touchTargets.comfortable,
|
|
281
|
-
gap: theme.spacing[3],
|
|
282
|
-
},
|
|
283
|
-
lgButtonInner: {
|
|
284
|
-
gap: theme.spacing[3],
|
|
285
|
-
},
|
|
286
|
-
lgText: {
|
|
287
|
-
fontSize: 18,
|
|
288
|
-
lineHeight: 20,
|
|
289
|
-
},
|
|
290
|
-
|
|
291
|
-
xlButton: {
|
|
292
|
-
paddingHorizontal: theme.spacing[8],
|
|
293
|
-
paddingVertical: theme.spacing[5],
|
|
294
|
-
borderRadius: tokens.borderRadius.lg,
|
|
295
|
-
minHeight: tokens.touchTargets.large,
|
|
296
|
-
gap: theme.spacing[4],
|
|
297
|
-
},
|
|
298
|
-
xlButtonInner: {
|
|
299
|
-
gap: theme.spacing[4],
|
|
300
|
-
},
|
|
301
|
-
xlText: {
|
|
302
|
-
fontSize: 20,
|
|
303
|
-
lineHeight: 24,
|
|
304
|
-
},
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
|
|
308
246
|
// Export button variants for external use
|
|
309
247
|
export { buttonVariants };
|