@proulr/sdui-components 0.1.0

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.
Files changed (57) hide show
  1. package/README.md +29 -0
  2. package/package.json +60 -0
  3. package/src/bdc/compile-bdc-to-wire.ts +123 -0
  4. package/src/bdc/components/discover.tsx +55 -0
  5. package/src/bdc/components/forms.tsx +20 -0
  6. package/src/bdc/components/native-blocks.tsx +35 -0
  7. package/src/bdc/components/social.tsx +27 -0
  8. package/src/bdc/components/ui.tsx +114 -0
  9. package/src/bdc/index.ts +41 -0
  10. package/src/bdc/jsx-runtime.ts +49 -0
  11. package/src/catalog/block-types.ts +18 -0
  12. package/src/catalog/style-tokens.ts +48 -0
  13. package/src/global.d.ts +1 -0
  14. package/src/renderer/SduiScreenRenderer.tsx +28 -0
  15. package/src/renderer/ads/native-ad-catalog.ts +23 -0
  16. package/src/renderer/blocks/SduiDiscoverBlocks.tsx +470 -0
  17. package/src/renderer/blocks/SduiLayoutBlocks.tsx +177 -0
  18. package/src/renderer/blocks/SduiNativeAdBlock.tsx +201 -0
  19. package/src/renderer/blocks/SduiNativeAdBlock.web.tsx +6 -0
  20. package/src/renderer/blocks/SduiNativeDomainBlocks.tsx +141 -0
  21. package/src/renderer/blocks/SduiPrimitiveBlocks.tsx +158 -0
  22. package/src/renderer/blocks/SduiSocialBlocks.tsx +64 -0
  23. package/src/renderer/index.ts +45 -0
  24. package/src/renderer/lib/brazilian-date-input.ts +22 -0
  25. package/src/renderer/lib/discover-profile-formatters.ts +75 -0
  26. package/src/renderer/lib/resolve-data-ref.ts +21 -0
  27. package/src/renderer/sdui-chrome-scroll-context.tsx +40 -0
  28. package/src/renderer/sdui-component-registry.tsx +129 -0
  29. package/src/renderer/sdui-hybrid-renderer-context.tsx +91 -0
  30. package/src/renderer/sdui-layout-debug.tsx +107 -0
  31. package/src/renderer/theme/proulr-theme.ts +164 -0
  32. package/src/renderer/theme/resolve-style-props.ts +85 -0
  33. package/src/renderer/ui/AppButton.tsx +71 -0
  34. package/src/renderer/ui/AppLoadingSpinner.tsx +38 -0
  35. package/src/renderer/ui/AuthStepShell.tsx +128 -0
  36. package/src/renderer/ui/Card.tsx +13 -0
  37. package/src/renderer/ui/DateField.tsx +36 -0
  38. package/src/renderer/ui/InfoBanner.tsx +51 -0
  39. package/src/renderer/ui/TextField.tsx +81 -0
  40. package/src/renderer/ui/compose-audience-pill.tsx +47 -0
  41. package/src/renderer/ui/compose-glyphs.tsx +400 -0
  42. package/src/renderer/ui/compose-media-carousel.tsx +116 -0
  43. package/src/renderer/ui/compose-media-shortcut.tsx +80 -0
  44. package/src/renderer/ui/compose-recent-media-grid.tsx +268 -0
  45. package/src/renderer/ui/compose-reply-audience-sheet.tsx +155 -0
  46. package/src/renderer/ui/compose-screen-header.tsx +115 -0
  47. package/src/renderer/ui/compose-text-area.tsx +94 -0
  48. package/src/renderer/ui/compose-toolbar-icon.tsx +45 -0
  49. package/src/renderer/ui/compose-toolbar.tsx +57 -0
  50. package/src/renderer/ui/compose-visibility-row.tsx +51 -0
  51. package/src/renderer/ui/floating-create-menu.tsx +165 -0
  52. package/src/renderer/ui/index.ts +44 -0
  53. package/src/renderer/ui/story-compose-header.tsx +72 -0
  54. package/src/renderer/ui/story-create-shortcut-row.tsx +89 -0
  55. package/src/renderer/ui/story-editor-chrome.tsx +231 -0
  56. package/src/renderer/ui/story-glyphs.tsx +144 -0
  57. package/src/renderer/ui/story-surface-picker.tsx +124 -0
@@ -0,0 +1,85 @@
1
+ import type { StyleProp, TextStyle, ViewStyle } from 'react-native';
2
+ import type { ColorToken, ShapeToken, SpacingToken, StyleWire, TypeToken } from '@proulr/sdui-contract';
3
+ import { m3Colors, m3Shape, m3Type, spacing } from './proulr-theme';
4
+
5
+ function resolveColor(token: ColorToken | undefined): string | undefined {
6
+ if (!token) return undefined;
7
+ return m3Colors[token as keyof typeof m3Colors];
8
+ }
9
+
10
+ function resolveSpacing(token: SpacingToken | number | undefined): number | undefined {
11
+ if (token == null) return undefined;
12
+ if (typeof token === 'number') return token;
13
+ return spacing[token];
14
+ }
15
+
16
+ function resolveShape(token: ShapeToken | number | undefined): number | undefined {
17
+ if (token == null) return undefined;
18
+ if (typeof token === 'number') return token;
19
+ return m3Shape[token];
20
+ }
21
+
22
+ function resolveTypography(token: TypeToken | undefined): TextStyle | undefined {
23
+ if (!token) return undefined;
24
+ return m3Type[token];
25
+ }
26
+
27
+ function snakeToCamel(key: string): string {
28
+ return key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());
29
+ }
30
+
31
+ function normalizeStyleWire(style: StyleWire | Record<string, unknown> | undefined): StyleWire {
32
+ if (!style) return {};
33
+ const normalized: StyleWire = {};
34
+ for (const [key, value] of Object.entries(style)) {
35
+ const camelKey = snakeToCamel(key) as keyof StyleWire;
36
+ (normalized as Record<string, unknown>)[camelKey] = value;
37
+ }
38
+ return normalized;
39
+ }
40
+
41
+ export function resolveViewStyleProps(
42
+ styleWire: StyleWire | Record<string, unknown> | undefined,
43
+ ): StyleProp<ViewStyle> {
44
+ const style = normalizeStyleWire(styleWire);
45
+ return {
46
+ backgroundColor: resolveColor(style.background_color),
47
+ padding: resolveSpacing(style.padding),
48
+ paddingHorizontal: resolveSpacing(style.padding_horizontal),
49
+ paddingVertical: resolveSpacing(style.padding_vertical),
50
+ marginTop: resolveSpacing(style.margin_top),
51
+ gap: resolveSpacing(style.gap),
52
+ borderRadius: resolveShape(style.border_radius),
53
+ borderWidth: style.border_width,
54
+ borderColor: resolveColor(style.border_color),
55
+ opacity: style.opacity,
56
+ flex: style.flex,
57
+ alignItems: style.align_items,
58
+ };
59
+ }
60
+
61
+ export function resolveTextStyleProps(
62
+ styleWire: StyleWire | Record<string, unknown> | undefined,
63
+ variant?: string,
64
+ ): StyleProp<TextStyle> {
65
+ const style = normalizeStyleWire(styleWire);
66
+ const variantType = (style.typography ?? variant) as TypeToken | undefined;
67
+ return {
68
+ ...resolveTypography(variantType),
69
+ color: resolveColor(style.color),
70
+ marginTop: resolveSpacing(style.margin_top),
71
+ opacity: style.opacity,
72
+ };
73
+ }
74
+
75
+ export function resolveGapProp(gap: unknown, fallback: number): number {
76
+ if (typeof gap === 'number') return gap;
77
+ if (typeof gap === 'string' && gap in spacing) return spacing[gap as SpacingToken];
78
+ return fallback;
79
+ }
80
+
81
+ export function resolvePaddingProp(padding: unknown, fallback = 0): number {
82
+ if (typeof padding === 'number') return padding;
83
+ if (typeof padding === 'string' && padding in spacing) return spacing[padding as SpacingToken];
84
+ return fallback;
85
+ }
@@ -0,0 +1,71 @@
1
+ import { Pressable, StyleSheet, Text } from 'react-native';
2
+ import { fonts, m3Colors, m3Elevation, m3Shape, spacing } from '../theme/proulr-theme';
3
+ import { AppLoadingSpinner } from './AppLoadingSpinner';
4
+
5
+ export function AppButton({
6
+ label,
7
+ onPress,
8
+ variant = 'primary',
9
+ disabled,
10
+ loading,
11
+ compact,
12
+ }: {
13
+ label: string;
14
+ onPress: () => void;
15
+ variant?: 'primary' | 'secondary' | 'ghost' | 'outline' | 'danger';
16
+ disabled?: boolean;
17
+ loading?: boolean;
18
+ compact?: boolean;
19
+ }) {
20
+ const isPrimary = variant === 'primary';
21
+ const isSecondary = variant === 'secondary';
22
+ const isOutline = variant === 'outline';
23
+ const isDanger = variant === 'danger';
24
+ const labelColor =
25
+ isPrimary || isDanger || isSecondary
26
+ ? m3Colors.onPrimary
27
+ : isOutline || variant === 'ghost'
28
+ ? m3Colors.primary
29
+ : m3Colors.onPrimary;
30
+
31
+ return (
32
+ <Pressable
33
+ onPress={onPress}
34
+ disabled={disabled || loading}
35
+ style={({ pressed }) => [
36
+ styles.btn,
37
+ compact && styles.btnCompact,
38
+ isPrimary && { backgroundColor: m3Colors.primary },
39
+ isSecondary && { backgroundColor: m3Colors.surfaceContainerHigh },
40
+ isDanger && { backgroundColor: m3Colors.error },
41
+ isOutline && {
42
+ backgroundColor: 'transparent',
43
+ borderWidth: 1,
44
+ borderColor: m3Colors.outline,
45
+ },
46
+ variant === 'ghost' && { backgroundColor: 'transparent' },
47
+ (disabled || loading) && { opacity: 0.38 },
48
+ pressed && { opacity: 0.85 },
49
+ (isPrimary || isSecondary) && m3Elevation.level1,
50
+ ]}
51
+ >
52
+ {loading ? (
53
+ <AppLoadingSpinner color={labelColor} />
54
+ ) : (
55
+ <Text style={[styles.btnText, { color: labelColor }]}>{label}</Text>
56
+ )}
57
+ </Pressable>
58
+ );
59
+ }
60
+
61
+ const styles = StyleSheet.create({
62
+ btn: {
63
+ height: 48,
64
+ borderRadius: m3Shape.cornerFull,
65
+ alignItems: 'center',
66
+ justifyContent: 'center',
67
+ paddingHorizontal: spacing.xl,
68
+ },
69
+ btnCompact: { height: 40, paddingHorizontal: spacing.sm },
70
+ btnText: { fontSize: 14, fontFamily: fonts.medium, letterSpacing: 0.1 },
71
+ });
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import { ActivityIndicator, StyleSheet, View, ViewStyle } from 'react-native';
3
+ import { m3Colors } from '../theme/proulr-theme';
4
+
5
+ export const loadingIndicatorSize = 'large' as const;
6
+ export const loadingIndicatorColor = m3Colors.primary;
7
+
8
+ type LoadingIndicatorProps = {
9
+ fullScreen?: boolean;
10
+ color?: string;
11
+ style?: ViewStyle;
12
+ };
13
+
14
+ export function AppLoadingSpinner({
15
+ fullScreen = false,
16
+ color = loadingIndicatorColor,
17
+ style,
18
+ }: LoadingIndicatorProps) {
19
+ const spinner = <ActivityIndicator color={color} size={loadingIndicatorSize} />;
20
+
21
+ if (fullScreen) {
22
+ return <View style={[styles.fullScreen, style]}>{spinner}</View>;
23
+ }
24
+
25
+ if (style) {
26
+ return <View style={style}>{spinner}</View>;
27
+ }
28
+
29
+ return spinner;
30
+ }
31
+
32
+ const styles = StyleSheet.create({
33
+ fullScreen: {
34
+ flex: 1,
35
+ alignItems: 'center',
36
+ justifyContent: 'center',
37
+ },
38
+ });
@@ -0,0 +1,128 @@
1
+ import React from 'react';
2
+ import {
3
+ KeyboardAvoidingView,
4
+ Platform,
5
+ Pressable,
6
+ ScrollView,
7
+ StyleSheet,
8
+ Text,
9
+ View,
10
+ type ViewStyle,
11
+ } from 'react-native';
12
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
13
+ import { colors, fonts, m3Colors, m3Type, spacing } from '../theme/proulr-theme';
14
+
15
+ type AuthStepShellProps = {
16
+ title: string;
17
+ subtitle?: string;
18
+ onBack?: () => void;
19
+ backLabel?: string;
20
+ headerSlot?: React.ReactNode;
21
+ children: React.ReactNode;
22
+ contentStyle?: ViewStyle;
23
+ };
24
+
25
+ /** Shell de auth/onboarding — título inline, sem chrome pill. */
26
+ export function AuthStepShell({
27
+ title,
28
+ subtitle,
29
+ onBack,
30
+ backLabel = 'Voltar',
31
+ headerSlot,
32
+ children,
33
+ contentStyle,
34
+ }: AuthStepShellProps) {
35
+ const insets = useSafeAreaInsets();
36
+
37
+ return (
38
+ <KeyboardAvoidingView
39
+ style={styles.root}
40
+ behavior={Platform.OS === 'ios' ? 'padding' : undefined}
41
+ >
42
+ <View style={[styles.inner, { paddingTop: insets.top + spacing.md }]}>
43
+ {onBack ? (
44
+ <Pressable
45
+ accessibilityRole="button"
46
+ onPress={onBack}
47
+ style={({ pressed }) => [styles.backBtn, pressed && styles.pressed]}
48
+ >
49
+ <Text style={styles.backGlyph}>{'\u2039'}</Text>
50
+ <Text style={styles.backLabel}>{backLabel}</Text>
51
+ </Pressable>
52
+ ) : null}
53
+
54
+ {headerSlot ? <View style={styles.headerSlot}>{headerSlot}</View> : null}
55
+
56
+ <Text style={styles.title}>{title}</Text>
57
+ {subtitle ? <Text style={styles.subtitle}>{subtitle}</Text> : null}
58
+
59
+ <ScrollView
60
+ style={styles.scroll}
61
+ contentContainerStyle={[
62
+ styles.scrollContent,
63
+ { paddingBottom: insets.bottom + spacing.xxl },
64
+ contentStyle,
65
+ ]}
66
+ keyboardShouldPersistTaps="handled"
67
+ showsVerticalScrollIndicator={false}
68
+ >
69
+ {children}
70
+ </ScrollView>
71
+ </View>
72
+ </KeyboardAvoidingView>
73
+ );
74
+ }
75
+
76
+ const styles = StyleSheet.create({
77
+ root: {
78
+ flex: 1,
79
+ backgroundColor: m3Colors.surface,
80
+ },
81
+ inner: {
82
+ flex: 1,
83
+ paddingHorizontal: spacing.xl,
84
+ },
85
+ backBtn: {
86
+ flexDirection: 'row',
87
+ alignItems: 'center',
88
+ alignSelf: 'flex-start',
89
+ gap: spacing.xs,
90
+ marginBottom: spacing.md,
91
+ paddingVertical: spacing.xs,
92
+ },
93
+ backGlyph: {
94
+ color: m3Colors.onSurface,
95
+ fontSize: 24,
96
+ fontFamily: fonts.bold,
97
+ marginTop: -2,
98
+ },
99
+ backLabel: {
100
+ color: colors.textMuted,
101
+ fontSize: 14,
102
+ fontFamily: fonts.medium,
103
+ },
104
+ pressed: {
105
+ opacity: 0.6,
106
+ },
107
+ headerSlot: {
108
+ alignItems: 'center',
109
+ marginBottom: spacing.lg,
110
+ },
111
+ title: {
112
+ ...m3Type.headline,
113
+ fontFamily: fonts.extrabold,
114
+ color: m3Colors.onSurface,
115
+ },
116
+ subtitle: {
117
+ ...m3Type.body,
118
+ color: m3Colors.onSurfaceVariant,
119
+ marginTop: spacing.sm,
120
+ },
121
+ scroll: {
122
+ flex: 1,
123
+ marginTop: spacing.xl,
124
+ },
125
+ scrollContent: {
126
+ gap: spacing.sm,
127
+ },
128
+ });
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { StyleSheet, View, ViewStyle } from 'react-native';
3
+ import { cardStyle } from '../theme/proulr-theme';
4
+
5
+ export function Card({ children, style }: { children: React.ReactNode; style?: ViewStyle }) {
6
+ return <View style={[styles.card, style]}>{children}</View>;
7
+ }
8
+
9
+ const styles = StyleSheet.create({
10
+ card: {
11
+ ...cardStyle,
12
+ },
13
+ });
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import { TextInput, TextInputProps, ViewStyle } from 'react-native';
3
+ import { maskDateBR } from '../lib/brazilian-date-input';
4
+ import { TextField } from './TextField';
5
+
6
+ export function DateField({
7
+ value,
8
+ onChange,
9
+ placeholder = 'DD/MM/AAAA',
10
+ containerStyle,
11
+ inputRef,
12
+ returnKeyType,
13
+ onSubmitEditing,
14
+ }: {
15
+ value: string;
16
+ onChange: (masked: string) => void;
17
+ placeholder?: string;
18
+ containerStyle?: ViewStyle;
19
+ inputRef?: React.Ref<TextInput>;
20
+ returnKeyType?: TextInputProps['returnKeyType'];
21
+ onSubmitEditing?: TextInputProps['onSubmitEditing'];
22
+ }) {
23
+ return (
24
+ <TextField
25
+ inputRef={inputRef}
26
+ placeholder={placeholder}
27
+ keyboardType="number-pad"
28
+ maxLength={10}
29
+ value={value}
30
+ returnKeyType={returnKeyType}
31
+ onSubmitEditing={onSubmitEditing}
32
+ onChangeText={(t) => onChange(maskDateBR(t))}
33
+ containerStyle={containerStyle}
34
+ />
35
+ );
36
+ }
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+ import { Pressable, StyleSheet, Text, View } from 'react-native';
3
+ import { colors, fonts, radius, spacing } from '../theme/proulr-theme';
4
+
5
+ export function InfoBanner({
6
+ message,
7
+ icon = 'ℹ',
8
+ onDismiss,
9
+ }: {
10
+ message: string;
11
+ icon?: string;
12
+ onDismiss?: () => void;
13
+ }) {
14
+ return (
15
+ <View style={styles.infoBanner}>
16
+ <View style={styles.infoIconWrap}>
17
+ <Text style={styles.infoIcon}>{icon}</Text>
18
+ </View>
19
+ <Text style={styles.infoText}>{message}</Text>
20
+ {onDismiss && (
21
+ <Pressable onPress={onDismiss} hitSlop={8}>
22
+ <Text style={styles.infoDismiss}>✕</Text>
23
+ </Pressable>
24
+ )}
25
+ </View>
26
+ );
27
+ }
28
+
29
+ const styles = StyleSheet.create({
30
+ infoBanner: {
31
+ flexDirection: 'row',
32
+ alignItems: 'center',
33
+ gap: spacing.md,
34
+ backgroundColor: colors.accentSoft,
35
+ borderRadius: radius.lg,
36
+ padding: spacing.md,
37
+ borderWidth: 1,
38
+ borderColor: colors.border,
39
+ },
40
+ infoIconWrap: {
41
+ width: 36,
42
+ height: 36,
43
+ borderRadius: 18,
44
+ backgroundColor: colors.surface2,
45
+ alignItems: 'center',
46
+ justifyContent: 'center',
47
+ },
48
+ infoIcon: { fontSize: 16, color: colors.accentText },
49
+ infoText: { flex: 1, color: colors.textSecondary, fontSize: 13, lineHeight: 18, fontFamily: fonts.medium },
50
+ infoDismiss: { color: colors.textMuted, fontSize: 16 },
51
+ });
@@ -0,0 +1,81 @@
1
+ import React, { useState } from 'react';
2
+ import { Pressable, StyleSheet, Text, TextInput, TextInputProps, View, ViewStyle } from 'react-native';
3
+ import { fonts, m3Colors, m3Shape, spacing } from '../theme/proulr-theme';
4
+
5
+ export function TextField(
6
+ props: TextInputProps & {
7
+ containerStyle?: ViewStyle;
8
+ focused?: boolean;
9
+ inputRef?: React.Ref<TextInput>;
10
+ },
11
+ ) {
12
+ const { containerStyle, focused, inputRef, ...rest } = props;
13
+ return (
14
+ <View
15
+ style={[
16
+ styles.field,
17
+ focused && { borderColor: m3Colors.primary, borderWidth: 2 },
18
+ containerStyle,
19
+ ]}
20
+ >
21
+ <TextInput
22
+ ref={inputRef}
23
+ placeholderTextColor={m3Colors.onSurfaceVariant}
24
+ style={styles.fieldInput}
25
+ {...rest}
26
+ />
27
+ </View>
28
+ );
29
+ }
30
+
31
+ export function PasswordField(
32
+ props: TextInputProps & {
33
+ containerStyle?: ViewStyle;
34
+ inputRef?: React.Ref<TextInput>;
35
+ },
36
+ ) {
37
+ const { containerStyle, inputRef, ...rest } = props;
38
+ const [visible, setVisible] = useState(false);
39
+
40
+ return (
41
+ <View style={[styles.field, styles.passwordField, containerStyle]}>
42
+ <TextInput
43
+ ref={inputRef}
44
+ placeholderTextColor={m3Colors.onSurfaceVariant}
45
+ style={[styles.fieldInput, styles.passwordInput]}
46
+ secureTextEntry={!visible}
47
+ {...rest}
48
+ />
49
+ <Pressable
50
+ onPress={() => setVisible((v) => !v)}
51
+ hitSlop={8}
52
+ style={styles.passwordToggle}
53
+ accessibilityLabel={visible ? 'Ocultar senha' : 'Mostrar senha'}
54
+ >
55
+ <Text style={styles.passwordToggleIcon}>{visible ? '🙈' : '👁'}</Text>
56
+ </Pressable>
57
+ </View>
58
+ );
59
+ }
60
+
61
+ const styles = StyleSheet.create({
62
+ field: {
63
+ minHeight: 56,
64
+ borderRadius: m3Shape.cornerExtraSmall,
65
+ backgroundColor: 'transparent',
66
+ borderWidth: 1,
67
+ borderColor: m3Colors.outline,
68
+ paddingHorizontal: spacing.sm,
69
+ justifyContent: 'center',
70
+ },
71
+ fieldInput: { color: m3Colors.onSurface, fontSize: 16, fontFamily: fonts.regular },
72
+ passwordField: { flexDirection: 'row', alignItems: 'center', paddingRight: spacing.sm },
73
+ passwordInput: { flex: 1 },
74
+ passwordToggle: {
75
+ width: 40,
76
+ height: 40,
77
+ alignItems: 'center',
78
+ justifyContent: 'center',
79
+ },
80
+ passwordToggleIcon: { fontSize: 18 },
81
+ });
@@ -0,0 +1,47 @@
1
+ import { Pressable, StyleSheet, Text } from 'react-native';
2
+ import { fonts, m3Colors, m3Shape, spacing } from '../theme/proulr-theme';
3
+
4
+ export function ComposeAudiencePill({
5
+ label,
6
+ onPress,
7
+ }: {
8
+ label: string;
9
+ onPress?: () => void;
10
+ }) {
11
+ return (
12
+ <Pressable
13
+ onPress={onPress}
14
+ disabled={!onPress}
15
+ accessibilityRole="button"
16
+ accessibilityLabel={label}
17
+ style={({ pressed }) => [styles.pill, pressed && onPress && { opacity: 0.82 }]}
18
+ >
19
+ <Text style={styles.label}>{label}</Text>
20
+ <Text style={styles.chevron}>{'\u25BE'}</Text>
21
+ </Pressable>
22
+ );
23
+ }
24
+
25
+ const styles = StyleSheet.create({
26
+ pill: {
27
+ flexDirection: 'row',
28
+ alignItems: 'center',
29
+ gap: spacing.xs,
30
+ paddingHorizontal: spacing.sm,
31
+ paddingVertical: spacing.xs,
32
+ borderRadius: m3Shape.cornerFull,
33
+ borderWidth: 1,
34
+ borderColor: m3Colors.primary,
35
+ backgroundColor: m3Colors.primaryContainer,
36
+ },
37
+ label: {
38
+ color: m3Colors.onPrimaryContainer,
39
+ fontFamily: fonts.medium,
40
+ fontSize: 13,
41
+ },
42
+ chevron: {
43
+ color: m3Colors.onPrimaryContainer,
44
+ fontSize: 14,
45
+ marginTop: 1,
46
+ },
47
+ });