@retray-dev/ui-kit 12.1.0 → 12.2.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.
- package/COMPONENTS.md +98 -4
- package/README.md +4 -4
- package/dist/Accordion.d.mts +6 -0
- package/dist/Accordion.d.ts +6 -0
- package/dist/Accordion.js +16 -0
- package/dist/Accordion.mjs +2 -2
- package/dist/AlertBanner.js +2 -0
- package/dist/AlertBanner.mjs +2 -2
- package/dist/AppHeader.js +2 -0
- package/dist/AppHeader.mjs +3 -3
- package/dist/Avatar.js +2 -0
- package/dist/Avatar.mjs +2 -2
- package/dist/Badge.js +2 -0
- package/dist/Badge.mjs +2 -2
- package/dist/Button.js +17 -17
- package/dist/Button.mjs +2 -2
- package/dist/Card.js +2 -0
- package/dist/Card.mjs +2 -2
- package/dist/CategoryStrip.js +2 -0
- package/dist/CategoryStrip.mjs +2 -2
- package/dist/Checkbox.js +2 -0
- package/dist/Checkbox.mjs +2 -2
- package/dist/Chip.js +2 -0
- package/dist/Chip.mjs +2 -2
- package/dist/ConfirmDialog.js +26 -20
- package/dist/ConfirmDialog.mjs +3 -3
- package/dist/CurrencyDisplay.js +2 -0
- package/dist/CurrencyDisplay.mjs +2 -2
- package/dist/CurrencyInput.js +2 -0
- package/dist/CurrencyInput.mjs +3 -3
- package/dist/DetailRow.js +2 -0
- package/dist/DetailRow.mjs +2 -2
- package/dist/EmptyState.js +17 -17
- package/dist/EmptyState.mjs +3 -3
- package/dist/ErrorBoundary.js +2 -0
- package/dist/ErrorBoundary.mjs +2 -2
- package/dist/Form.js +2 -0
- package/dist/Form.mjs +2 -2
- package/dist/IconButton.js +2 -0
- package/dist/IconButton.mjs +2 -2
- package/dist/IconPicker.js +2 -0
- package/dist/IconPicker.mjs +3 -3
- package/dist/ImageUpload.d.mts +3 -1
- package/dist/ImageUpload.d.ts +3 -1
- package/dist/ImageUpload.js +10 -3
- package/dist/ImageUpload.mjs +3 -3
- package/dist/ImageViewer.js +2 -0
- package/dist/ImageViewer.mjs +4 -4
- package/dist/Input.js +2 -0
- package/dist/Input.mjs +2 -2
- package/dist/LabelValue.js +2 -0
- package/dist/LabelValue.mjs +2 -2
- package/dist/ListGroup.js +2 -0
- package/dist/ListGroup.mjs +2 -2
- package/dist/ListItem.js +2 -0
- package/dist/ListItem.mjs +2 -2
- package/dist/MediaCard.js +2 -0
- package/dist/MediaCard.mjs +2 -2
- package/dist/MenuGroup.js +2 -0
- package/dist/MenuGroup.mjs +2 -2
- package/dist/MenuItem.js +2 -0
- package/dist/MenuItem.mjs +2 -2
- package/dist/MonthPicker.js +2 -0
- package/dist/MonthPicker.mjs +2 -2
- package/dist/NumberStepper.js +2 -0
- package/dist/NumberStepper.mjs +2 -2
- package/dist/PagerDots.js +2 -0
- package/dist/PagerDots.mjs +2 -2
- package/dist/PricingCard.js +17 -17
- package/dist/PricingCard.mjs +4 -4
- package/dist/Progress.js +2 -0
- package/dist/Progress.mjs +2 -2
- package/dist/RadioGroup.js +2 -0
- package/dist/RadioGroup.mjs +2 -2
- package/dist/RetrayProvider.d.mts +1 -1
- package/dist/RetrayProvider.d.ts +1 -1
- package/dist/RetrayProvider.js +2 -0
- package/dist/RetrayProvider.mjs +3 -3
- package/dist/Select.js +2 -0
- package/dist/Select.mjs +2 -2
- package/dist/SelectableCard.d.mts +27 -0
- package/dist/SelectableCard.d.ts +27 -0
- package/dist/SelectableCard.js +511 -0
- package/dist/SelectableCard.mjs +8 -0
- package/dist/SelectableGrid.js +2 -0
- package/dist/SelectableGrid.mjs +2 -2
- package/dist/Separator.js +2 -0
- package/dist/Separator.mjs +2 -2
- package/dist/Sheet.js +11 -3
- package/dist/Sheet.mjs +2 -2
- package/dist/SheetSelect.js +2 -0
- package/dist/SheetSelect.mjs +2 -2
- package/dist/Skeleton.d.mts +3 -1
- package/dist/Skeleton.d.ts +3 -1
- package/dist/Skeleton.js +5 -2
- package/dist/Skeleton.mjs +2 -2
- package/dist/Slider.js +2 -0
- package/dist/Slider.mjs +2 -2
- package/dist/Spinner.js +2 -0
- package/dist/Spinner.mjs +2 -2
- package/dist/Stats.d.mts +4 -1
- package/dist/Stats.d.ts +4 -1
- package/dist/Stats.js +27 -3
- package/dist/Stats.mjs +2 -2
- package/dist/Switch.js +2 -0
- package/dist/Switch.mjs +2 -2
- package/dist/TabBar.js +2 -0
- package/dist/TabBar.mjs +2 -2
- package/dist/Tabs.js +2 -0
- package/dist/Tabs.mjs +2 -2
- package/dist/Text.js +2 -0
- package/dist/Text.mjs +2 -2
- package/dist/Textarea.js +2 -0
- package/dist/Textarea.mjs +2 -2
- package/dist/Toast.js +2 -0
- package/dist/Toast.mjs +2 -2
- package/dist/Toggle.js +2 -0
- package/dist/Toggle.mjs +2 -2
- package/dist/{chunk-JNVAIDLK.mjs → chunk-2BA3JMKK.mjs} +1 -1
- package/dist/{chunk-X26S5EVZ.mjs → chunk-2HFD4IHU.mjs} +1 -1
- package/dist/{chunk-ZHMSAYLT.mjs → chunk-2LG326TT.mjs} +1 -1
- package/dist/chunk-2P2CB235.mjs +236 -0
- package/dist/{chunk-MYZ2EDYU.mjs → chunk-3XCFYSX4.mjs} +1 -1
- package/dist/{chunk-DOGIPOF5.mjs → chunk-4J2PXL36.mjs} +16 -18
- package/dist/{chunk-V6NFJXKO.mjs → chunk-4OORJ2DY.mjs} +1 -1
- package/dist/{chunk-5OLNXP3S.mjs → chunk-4XOB5TTD.mjs} +26 -4
- package/dist/{chunk-P64WHW4A.mjs → chunk-57V2LXCK.mjs} +1 -1
- package/dist/{chunk-HJ46DTJE.mjs → chunk-7AFZWSCI.mjs} +1 -1
- package/dist/{chunk-AQEVCEXV.mjs → chunk-7ELGZ66G.mjs} +1 -1
- package/dist/{chunk-I4V5XZPS.mjs → chunk-AENAVIKT.mjs} +1 -1
- package/dist/{chunk-2CBQKU7H.mjs → chunk-BXF4AMHY.mjs} +1 -1
- package/dist/{chunk-JULSIZDM.mjs → chunk-C43HRKXH.mjs} +1 -1
- package/dist/{chunk-GK4VRMNE.mjs → chunk-CF27NBXO.mjs} +11 -6
- package/dist/{chunk-PGERH3P7.mjs → chunk-DF7JA72E.mjs} +1 -1
- package/dist/{chunk-F4V6XLP4.mjs → chunk-E5UKLSJZ.mjs} +3 -3
- package/dist/{chunk-FUVYSVGR.mjs → chunk-EDLCGYIO.mjs} +1 -1
- package/dist/{chunk-N4ZPVCJH.mjs → chunk-ELGEOM7I.mjs} +1 -1
- package/dist/{chunk-FA2KMTH5.mjs → chunk-F3YTWO3T.mjs} +1 -1
- package/dist/{chunk-3UYAZ7I4.mjs → chunk-GH67YXG6.mjs} +1 -1
- package/dist/{chunk-357YO24D.mjs → chunk-GUTDFUNF.mjs} +1 -1
- package/dist/{chunk-7HSILTC4.mjs → chunk-HC4VVCWY.mjs} +2 -2
- package/dist/{chunk-WOEWGSTU.mjs → chunk-HEDQPK4I.mjs} +1 -1
- package/dist/{chunk-3GEYJ7I5.mjs → chunk-IVSRW4HS.mjs} +1 -1
- package/dist/{chunk-P73V2EKS.mjs → chunk-KSUWPU2F.mjs} +1 -1
- package/dist/{chunk-BCWEHE34.mjs → chunk-LIS6I5UP.mjs} +1 -1
- package/dist/{chunk-J6Q2YJEV.mjs → chunk-LNPKGWBG.mjs} +1 -1
- package/dist/{chunk-DF6DU42P.mjs → chunk-LOBLCFMN.mjs} +1 -1
- package/dist/{chunk-2A2LEFZG.mjs → chunk-LPV4NJJK.mjs} +2 -2
- package/dist/{chunk-FFTYLPSB.mjs → chunk-M3C7XM2M.mjs} +11 -5
- package/dist/{chunk-BQZE3HAW.mjs → chunk-MEPSKGBO.mjs} +1 -1
- package/dist/{chunk-ISY26JQJ.mjs → chunk-MVMGPZN6.mjs} +2 -2
- package/dist/{chunk-265G6A46.mjs → chunk-NHDI3VQB.mjs} +15 -1
- package/dist/{chunk-D3Y2T42P.mjs → chunk-NJG7DHVF.mjs} +1 -1
- package/dist/{chunk-LRM4AVYY.mjs → chunk-NLZY4TXU.mjs} +1 -1
- package/dist/{chunk-OULVKTWL.mjs → chunk-OLVJFKXS.mjs} +1 -1
- package/dist/{chunk-BOVUP27T.mjs → chunk-QDAZGZUF.mjs} +4 -3
- package/dist/{chunk-S3KJCPEJ.mjs → chunk-QOLWA2PW.mjs} +1 -1
- package/dist/{chunk-JCZQOY4O.mjs → chunk-QXDGGOLC.mjs} +12 -6
- package/dist/{chunk-4WFMPFZB.mjs → chunk-RJNLAH76.mjs} +1 -1
- package/dist/{chunk-HLMPMUK2.mjs → chunk-RMRS44MQ.mjs} +1 -1
- package/dist/{chunk-KHYX4IOM.mjs → chunk-SAWUXP3A.mjs} +2 -2
- package/dist/{chunk-2I2AYECM.mjs → chunk-TS7DGUIR.mjs} +1 -1
- package/dist/{chunk-3N2M3WZL.mjs → chunk-UBUXUMER.mjs} +1 -1
- package/dist/{chunk-AKM4EPOT.mjs → chunk-ULGNQPNE.mjs} +1 -1
- package/dist/{chunk-FVTVCJAH.mjs → chunk-UNNRUJTM.mjs} +1 -1
- package/dist/{chunk-DI7CBDL6.mjs → chunk-UQ4742ET.mjs} +1 -1
- package/dist/{chunk-EFLFRAHD.mjs → chunk-VJBUCITV.mjs} +1 -1
- package/dist/{chunk-QSFV2P7O.mjs → chunk-YMYIEVZP.mjs} +1 -1
- package/dist/{chunk-EMUWGDWC.mjs → chunk-YTXRIXNZ.mjs} +2 -0
- package/dist/{chunk-XBAGGKLW.mjs → chunk-ZIMY2QUM.mjs} +2 -2
- package/dist/{chunk-NXI4YDZ2.mjs → chunk-ZR6HSEAB.mjs} +1 -1
- package/dist/{index-wt-orHUi.d.ts → index-CY34hxPN.d.mts} +1 -0
- package/dist/{index-wt-orHUi.d.mts → index-CY34hxPN.d.ts} +1 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +733 -453
- package/dist/index.mjs +53 -52
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.tsx +20 -0
- package/src/components/Button/Button.tsx +29 -26
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +10 -3
- package/src/components/ImageUpload/ImageUpload.tsx +10 -3
- package/src/components/SelectableCard/SelectableCard.tsx +304 -0
- package/src/components/SelectableCard/index.ts +1 -0
- package/src/components/Sheet/Sheet.tsx +10 -3
- package/src/components/Skeleton/Skeleton.tsx +5 -2
- package/src/components/Stats/Stats.tsx +35 -7
- package/src/index.ts +1 -0
- package/src/theme/colors.ts +7 -0
- package/src/theme/types.ts +4 -1
|
@@ -99,14 +99,21 @@ export function Sheet({
|
|
|
99
99
|
const insets = useSafeAreaInsets()
|
|
100
100
|
const ref = useRef<BottomSheetModal>(null)
|
|
101
101
|
const wasOpened = useRef(false)
|
|
102
|
+
const isPresentedRef = useRef(false)
|
|
102
103
|
const name = useId()
|
|
103
104
|
|
|
105
|
+
const handleDismiss = useCallback(() => {
|
|
106
|
+
isPresentedRef.current = false
|
|
107
|
+
onClose?.()
|
|
108
|
+
}, [onClose])
|
|
109
|
+
|
|
104
110
|
useEffect(() => {
|
|
105
|
-
if (open) {
|
|
111
|
+
if (open && !isPresentedRef.current) {
|
|
106
112
|
impactMedium()
|
|
107
113
|
ref.current?.present()
|
|
108
114
|
wasOpened.current = true
|
|
109
|
-
|
|
115
|
+
isPresentedRef.current = true
|
|
116
|
+
} else if (!open && wasOpened.current && isPresentedRef.current) {
|
|
110
117
|
ref.current?.dismiss()
|
|
111
118
|
}
|
|
112
119
|
}, [open])
|
|
@@ -188,7 +195,7 @@ export function Sheet({
|
|
|
188
195
|
<BottomSheetModal
|
|
189
196
|
ref={ref}
|
|
190
197
|
name={name}
|
|
191
|
-
onDismiss={
|
|
198
|
+
onDismiss={handleDismiss}
|
|
192
199
|
enableDynamicSizing={useDynamicSizing}
|
|
193
200
|
snapPoints={snapPoints}
|
|
194
201
|
maxDynamicContentSize={useDynamicSizing && maxHeight ? maxHeight : undefined}
|
|
@@ -24,6 +24,8 @@ export interface SkeletonProps {
|
|
|
24
24
|
preset?: SkeletonPreset
|
|
25
25
|
/** Only used with `preset='circle'` — overrides the diameter. Defaults to 40. */
|
|
26
26
|
diameter?: number
|
|
27
|
+
/** Override the skeleton background color. Defaults to `colors.skeleton`. */
|
|
28
|
+
backgroundColor?: string
|
|
27
29
|
style?: ViewStyle
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -33,6 +35,7 @@ export function Skeleton({
|
|
|
33
35
|
borderRadius = 6,
|
|
34
36
|
preset = 'base',
|
|
35
37
|
diameter = 40,
|
|
38
|
+
backgroundColor,
|
|
36
39
|
style,
|
|
37
40
|
}: SkeletonProps) {
|
|
38
41
|
const { colors, colorScheme } = useTheme()
|
|
@@ -40,7 +43,7 @@ export function Skeleton({
|
|
|
40
43
|
const [containerWidth, setContainerWidth] = useState(300)
|
|
41
44
|
|
|
42
45
|
const shimmerHighlight =
|
|
43
|
-
colorScheme === 'dark' ? 'rgba(255,255,255,0.08)' : 'rgba(
|
|
46
|
+
colorScheme === 'dark' ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.07)'
|
|
44
47
|
|
|
45
48
|
useEffect(() => {
|
|
46
49
|
// Repeats indefinitely on the UI thread — zero JS bridge cost per frame.
|
|
@@ -75,7 +78,7 @@ export function Skeleton({
|
|
|
75
78
|
<View
|
|
76
79
|
style={[
|
|
77
80
|
styles.base,
|
|
78
|
-
{ width: resolvedWidth as number | `${number}%`, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.
|
|
81
|
+
{ width: resolvedWidth as number | `${number}%`, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: backgroundColor ?? colors.skeleton },
|
|
79
82
|
style,
|
|
80
83
|
]}
|
|
81
84
|
onLayout={(e) => setContainerWidth(e.nativeEvent.layout.width)}
|
|
@@ -8,6 +8,7 @@ import { renderIcon } from '../../utils/icons'
|
|
|
8
8
|
import { PressableCard } from '../../utils/pressable'
|
|
9
9
|
|
|
10
10
|
export type StatsVariant = 'elevated' | 'outlined' | 'filled'
|
|
11
|
+
export type StatsSize = 'default' | 'compact'
|
|
11
12
|
|
|
12
13
|
export interface StatsProps {
|
|
13
14
|
value: string
|
|
@@ -17,6 +18,8 @@ export interface StatsProps {
|
|
|
17
18
|
iconName?: string
|
|
18
19
|
iconColor?: string
|
|
19
20
|
variant?: StatsVariant
|
|
21
|
+
/** `'compact'` reduces everything proportionally for tight grids. */
|
|
22
|
+
size?: StatsSize
|
|
20
23
|
onPress?: () => void
|
|
21
24
|
style?: ViewStyle
|
|
22
25
|
accessibilityLabel?: string
|
|
@@ -38,6 +41,7 @@ function StatsComponent({
|
|
|
38
41
|
iconName,
|
|
39
42
|
iconColor,
|
|
40
43
|
variant = 'elevated',
|
|
44
|
+
size = 'default',
|
|
41
45
|
onPress,
|
|
42
46
|
style,
|
|
43
47
|
accessibilityLabel,
|
|
@@ -60,6 +64,30 @@ function StatsComponent({
|
|
|
60
64
|
|
|
61
65
|
const isCompact = containerWidth > 0 && containerWidth < COMPACT_THRESHOLD && !!(icon ?? iconName)
|
|
62
66
|
|
|
67
|
+
const sizeStyles = size === 'compact'
|
|
68
|
+
? {
|
|
69
|
+
valueFontFamily: 'Sohne-SemiBold' as const,
|
|
70
|
+
valueFontSize: ms(16),
|
|
71
|
+
valueLineHeight: mvs(20),
|
|
72
|
+
labelFontSize: ms(11),
|
|
73
|
+
labelLineHeight: mvs(14),
|
|
74
|
+
descriptionFontSize: ms(10),
|
|
75
|
+
descriptionLineHeight: mvs(14),
|
|
76
|
+
iconSize: ms(18),
|
|
77
|
+
padding: s(12),
|
|
78
|
+
}
|
|
79
|
+
: {
|
|
80
|
+
valueFontFamily: 'Sohne-Bold' as const,
|
|
81
|
+
valueFontSize: ms(21),
|
|
82
|
+
valueLineHeight: mvs(25),
|
|
83
|
+
labelFontSize: ms(13),
|
|
84
|
+
labelLineHeight: mvs(18),
|
|
85
|
+
descriptionFontSize: ms(12),
|
|
86
|
+
descriptionLineHeight: mvs(16),
|
|
87
|
+
iconSize: ms(20),
|
|
88
|
+
padding: s(16),
|
|
89
|
+
}
|
|
90
|
+
|
|
63
91
|
const variantStyle: ViewStyle = {
|
|
64
92
|
elevated: {
|
|
65
93
|
backgroundColor: colors.card,
|
|
@@ -86,29 +114,29 @@ function StatsComponent({
|
|
|
86
114
|
|
|
87
115
|
const iconColorResolved = iconColor ?? colors.primary
|
|
88
116
|
|
|
89
|
-
const resolvedIcon = iconName ? renderIcon(iconName,
|
|
117
|
+
const resolvedIcon = iconName ? renderIcon(iconName, sizeStyles.iconSize, iconColorResolved) : icon
|
|
90
118
|
|
|
91
119
|
const iconElement = resolvedIcon ? (
|
|
92
120
|
<View style={styles.iconWrapper}>{resolvedIcon}</View>
|
|
93
121
|
) : null
|
|
94
122
|
|
|
95
123
|
const valueElement = (
|
|
96
|
-
<Text style={[styles.value, { color: colors.foreground }]} allowFontScaling={true}>
|
|
124
|
+
<Text style={[styles.value, { color: colors.foreground, fontFamily: sizeStyles.valueFontFamily, fontSize: sizeStyles.valueFontSize, lineHeight: sizeStyles.valueLineHeight }]} allowFontScaling={true}>
|
|
97
125
|
{value}
|
|
98
126
|
</Text>
|
|
99
127
|
)
|
|
100
128
|
|
|
101
129
|
const cardContent = (
|
|
102
|
-
<View style={[styles.card, variantStyle, style]} onLayout={handleLayout}>
|
|
130
|
+
<View style={[styles.card, variantStyle, { padding: sizeStyles.padding }, style]} onLayout={handleLayout}>
|
|
103
131
|
{isCompact ? (
|
|
104
132
|
<>
|
|
105
133
|
{iconElement}
|
|
106
134
|
<View style={styles.compactValue}>{valueElement}</View>
|
|
107
|
-
<Text style={[styles.label, { color: colors.foregroundSubtle }]} allowFontScaling={true}>
|
|
135
|
+
<Text style={[styles.label, { color: colors.foregroundSubtle, fontSize: sizeStyles.labelFontSize, lineHeight: sizeStyles.labelLineHeight }]} allowFontScaling={true}>
|
|
108
136
|
{label}
|
|
109
137
|
</Text>
|
|
110
138
|
{description ? (
|
|
111
|
-
<Text style={[styles.description, { color: colors.foregroundMuted }]} allowFontScaling={true}>
|
|
139
|
+
<Text style={[styles.description, { color: colors.foregroundMuted, fontSize: sizeStyles.descriptionFontSize, lineHeight: sizeStyles.descriptionLineHeight }]} allowFontScaling={true}>
|
|
112
140
|
{description}
|
|
113
141
|
</Text>
|
|
114
142
|
) : null}
|
|
@@ -119,11 +147,11 @@ function StatsComponent({
|
|
|
119
147
|
{iconElement}
|
|
120
148
|
{valueElement}
|
|
121
149
|
</View>
|
|
122
|
-
<Text style={[styles.label, { color: colors.foregroundSubtle }]} allowFontScaling={true}>
|
|
150
|
+
<Text style={[styles.label, { color: colors.foregroundSubtle, fontSize: sizeStyles.labelFontSize, lineHeight: sizeStyles.labelLineHeight }]} allowFontScaling={true}>
|
|
123
151
|
{label}
|
|
124
152
|
</Text>
|
|
125
153
|
{description ? (
|
|
126
|
-
<Text style={[styles.description, { color: colors.foregroundMuted }]} allowFontScaling={true}>
|
|
154
|
+
<Text style={[styles.description, { color: colors.foregroundMuted, fontSize: sizeStyles.descriptionFontSize, lineHeight: sizeStyles.descriptionLineHeight }]} allowFontScaling={true}>
|
|
127
155
|
{description}
|
|
128
156
|
</Text>
|
|
129
157
|
) : null}
|
package/src/index.ts
CHANGED
|
@@ -50,6 +50,7 @@ export * from './components/ErrorBoundary'
|
|
|
50
50
|
export * from './components/PagerDots'
|
|
51
51
|
export * from './components/AppHeader'
|
|
52
52
|
export * from './components/SelectableGrid'
|
|
53
|
+
export * from './components/SelectableCard'
|
|
53
54
|
export * from './components/PricingCard'
|
|
54
55
|
export * from './components/TabBar'
|
|
55
56
|
export * from './components/ImageViewer'
|
package/src/theme/colors.ts
CHANGED
|
@@ -69,6 +69,12 @@ export function deriveColors(t: ThemeColors, scheme: 'light' | 'dark'): Resolved
|
|
|
69
69
|
? lighten(bg, -0.12)
|
|
70
70
|
: darken(bg, 0.08)
|
|
71
71
|
|
|
72
|
+
// Skeleton needs higher contrast than surface to be visible.
|
|
73
|
+
// Light: 10% darken (was 4% via surface — invisible). Dark: 10% lighten.
|
|
74
|
+
const skeleton = dark
|
|
75
|
+
? lighten(bg, -0.10)
|
|
76
|
+
: darken(bg, 0.10)
|
|
77
|
+
|
|
72
78
|
const destructiveTint = dark
|
|
73
79
|
? withAlphaOnDark(t.destructive, 0.15, bg)
|
|
74
80
|
: withAlphaOnWhite(t.destructive, 0.08)
|
|
@@ -96,6 +102,7 @@ export function deriveColors(t: ThemeColors, scheme: 'light' | 'dark'): Resolved
|
|
|
96
102
|
foregroundMuted,
|
|
97
103
|
surface,
|
|
98
104
|
surfaceStrong,
|
|
105
|
+
skeleton,
|
|
99
106
|
destructiveTint,
|
|
100
107
|
destructiveBorder,
|
|
101
108
|
successTint,
|
package/src/theme/types.ts
CHANGED
|
@@ -29,10 +29,13 @@ export type ResolvedColors = ThemeColors & {
|
|
|
29
29
|
foregroundSubtle: string // ~55% — body text, subtitles
|
|
30
30
|
foregroundMuted: string // ~35% — captions, timestamps, placeholders
|
|
31
31
|
|
|
32
|
-
// Surface fills (chips unselected, input bg, tag bg
|
|
32
|
+
// Surface fills (chips unselected, input bg, tag bg)
|
|
33
33
|
surface: string // background slightly off-canvas
|
|
34
34
|
surfaceStrong: string // slightly stronger fill for pressed/hover states
|
|
35
35
|
|
|
36
|
+
// Skeleton placeholder — higher contrast than surface for visibility
|
|
37
|
+
skeleton: string
|
|
38
|
+
|
|
36
39
|
// Semantic tints (light bg for alert banners, toast backgrounds)
|
|
37
40
|
destructiveTint: string
|
|
38
41
|
destructiveBorder: string
|