Improve admin mobile dark mode contrast
This commit is contained in:
@@ -46,14 +46,19 @@ function DashboardCard({
|
||||
}: React.ComponentProps<typeof Card> & { variant?: 'default' | 'embedded' }) {
|
||||
const theme = useAdminTheme();
|
||||
const isEmbedded = variant === 'embedded';
|
||||
const cardSurface = isEmbedded
|
||||
? (theme.surfaceMuted ?? theme.glassSurface ?? theme.surface)
|
||||
: (theme.glassSurfaceStrong ?? theme.surface);
|
||||
const cardBorder = theme.glassBorder ?? theme.border;
|
||||
const cardShadow = theme.glassShadow ?? theme.shadow;
|
||||
return (
|
||||
<Card
|
||||
backgroundColor={theme.surface}
|
||||
backgroundColor={cardSurface}
|
||||
borderRadius={isEmbedded ? 16 : 20}
|
||||
borderWidth={1}
|
||||
borderColor={theme.border}
|
||||
borderColor={cardBorder}
|
||||
padding="$3.5"
|
||||
shadowColor={theme.shadow}
|
||||
shadowColor={cardShadow}
|
||||
shadowOpacity={isEmbedded ? 0 : 0.16}
|
||||
shadowRadius={isEmbedded ? 0 : 16}
|
||||
shadowOffset={isEmbedded ? { width: 0, height: 0 } : { width: 0, height: 10 }}
|
||||
@@ -444,7 +449,8 @@ function LifecycleHero({
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
borderWidth={1}
|
||||
borderColor={theme.border}
|
||||
borderColor={theme.glassBorder ?? theme.border}
|
||||
backgroundColor={theme.surfaceMuted}
|
||||
borderRadius={12}
|
||||
paddingHorizontal="$2.5"
|
||||
paddingVertical="$2"
|
||||
|
||||
@@ -18,9 +18,9 @@ export function BottomNav({ active, onNavigate }: { active: NavKey; onNavigate:
|
||||
const theme = useAdminTheme();
|
||||
|
||||
// Modern Glass Background
|
||||
const navSurface = 'rgba(255, 255, 255, 0.85)';
|
||||
const navBorder = theme.border;
|
||||
const navShadow = theme.shadow;
|
||||
const navSurface = theme.glassSurfaceStrong ?? theme.surfaceMuted ?? theme.surface;
|
||||
const navBorder = theme.glassBorder ?? theme.border;
|
||||
const navShadow = theme.glassShadow ?? theme.shadow;
|
||||
|
||||
const [pressedKey, setPressedKey] = React.useState<NavKey | null>(null);
|
||||
|
||||
@@ -62,7 +62,7 @@ export function BottomNav({ active, onNavigate }: { active: NavKey; onNavigate:
|
||||
const IconCmp = item.icon;
|
||||
|
||||
// Dynamic Styles
|
||||
const color = activeState ? theme.primary : theme.subtle;
|
||||
const color = activeState ? theme.primary : theme.muted;
|
||||
const strokeWidth = activeState ? 2.5 : 2;
|
||||
|
||||
return (
|
||||
|
||||
@@ -253,9 +253,13 @@ export function MobileSelect({
|
||||
style,
|
||||
...props
|
||||
}: MobileSelectProps) {
|
||||
const { border, surface, text, primary, danger, subtle } = useAdminTheme();
|
||||
const borderColor = hasError ? danger : border;
|
||||
const { border, surface, text, primary, danger, subtle, glassSurfaceStrong, surfaceMuted, glassBorder } = useAdminTheme();
|
||||
const borderColor = hasError ? danger : (glassBorder ?? border);
|
||||
const ringColor = hasError ? withAlpha(danger, 0.18) : withAlpha(primary, 0.18);
|
||||
const triggerSurface = surfaceMuted ?? glassSurfaceStrong ?? surface;
|
||||
const contentSurface = glassSurfaceStrong ?? surface;
|
||||
const itemSurface = surface;
|
||||
const itemHover = surfaceMuted ?? surface;
|
||||
const hasSizing =
|
||||
typeof containerStyle === 'object' &&
|
||||
containerStyle !== null &&
|
||||
@@ -298,7 +302,7 @@ export function MobileSelect({
|
||||
borderRadius={12}
|
||||
borderWidth={1}
|
||||
borderColor={borderColor as any}
|
||||
backgroundColor={surface as any}
|
||||
backgroundColor={triggerSurface as any}
|
||||
paddingVertical={compact ? 6 : 10}
|
||||
paddingHorizontal="$3"
|
||||
disabled={props.disabled}
|
||||
@@ -320,14 +324,22 @@ export function MobileSelect({
|
||||
zIndex={200000}
|
||||
{...({ borderRadius: 14 } as any)}
|
||||
borderWidth={1}
|
||||
borderColor={border}
|
||||
backgroundColor={surface as any}
|
||||
borderColor={glassBorder ?? border}
|
||||
backgroundColor={contentSurface as any}
|
||||
>
|
||||
<Select.Viewport {...({ padding: "$2" } as any)}>
|
||||
<Select.Group>
|
||||
{options.map((option, index) => (
|
||||
<Select.Item index={index} key={`${option.value}-${index}`} value={option.value} disabled={option.disabled}>
|
||||
<Select.ItemText>{option.label}</Select.ItemText>
|
||||
<Select.Item
|
||||
index={index}
|
||||
key={`${option.value}-${index}`}
|
||||
value={option.value}
|
||||
disabled={option.disabled}
|
||||
backgroundColor={itemSurface as any}
|
||||
hoverStyle={{ backgroundColor: itemHover as any }}
|
||||
pressStyle={{ backgroundColor: itemHover as any }}
|
||||
>
|
||||
<Select.ItemText {...({ color: text } as any)}>{option.label}</Select.ItemText>
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Group>
|
||||
|
||||
@@ -44,27 +44,27 @@ export function PillBadge({
|
||||
tone?: 'success' | 'warning' | 'danger' | 'muted';
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const { theme } = useAdminTheme();
|
||||
const { successText, warningText, dangerText, muted, surfaceMuted, border } = useAdminTheme();
|
||||
const palette: Record<typeof tone, { bg: string; text: string; border: string }> = {
|
||||
success: {
|
||||
bg: String(theme.backgroundStrong?.val ?? '#ecfdf3'),
|
||||
text: String(theme.green10?.val ?? '#047857'),
|
||||
border: String(theme.green6?.val ?? '#bbf7d0'),
|
||||
bg: withAlpha(successText, 0.16),
|
||||
text: successText,
|
||||
border: withAlpha(successText, 0.35),
|
||||
},
|
||||
warning: {
|
||||
bg: String(theme.yellow3?.val ?? '#fffbeb'),
|
||||
text: String(theme.yellow11?.val ?? '#92400e'),
|
||||
border: String(theme.yellow6?.val ?? '#fef3c7'),
|
||||
bg: withAlpha(warningText, 0.16),
|
||||
text: warningText,
|
||||
border: withAlpha(warningText, 0.35),
|
||||
},
|
||||
danger: {
|
||||
bg: String(theme.red3?.val ?? '#FEE2E2'),
|
||||
text: String(theme.red11?.val ?? '#B91C1C'),
|
||||
border: String(theme.red6?.val ?? '#FCA5A5'),
|
||||
bg: withAlpha(dangerText, 0.16),
|
||||
text: dangerText,
|
||||
border: withAlpha(dangerText, 0.35),
|
||||
},
|
||||
muted: {
|
||||
bg: String(theme.gray3?.val ?? '#f3f4f6'),
|
||||
text: String(theme.gray11?.val ?? '#374151'),
|
||||
border: String(theme.gray6?.val ?? '#e5e7eb'),
|
||||
bg: surfaceMuted,
|
||||
text: muted,
|
||||
border,
|
||||
},
|
||||
};
|
||||
const colors = palette[tone] ?? palette.muted;
|
||||
@@ -210,7 +210,11 @@ export function KpiStrip({
|
||||
tone?: 'accent' | 'neutral';
|
||||
}>
|
||||
}) {
|
||||
const { glassSurface, border, textStrong, textMuted, primary, surfaceMuted, surface } = useAdminTheme();
|
||||
const { glassSurface, glassSurfaceStrong, glassBorder, border, textStrong, textMuted, primary, surfaceMuted, surface } = useAdminTheme();
|
||||
const cardSurface = surfaceMuted ?? glassSurfaceStrong ?? glassSurface ?? surface;
|
||||
const cardBorder = glassBorder ?? border;
|
||||
const separatorColor = withAlpha(textStrong, 0.12);
|
||||
const innerSeparatorColor = withAlpha(textStrong, 0.08);
|
||||
|
||||
return (
|
||||
<XStack flexWrap="wrap" gap="$2">
|
||||
@@ -222,10 +226,10 @@ export function KpiStrip({
|
||||
return (
|
||||
<Card
|
||||
key={index}
|
||||
backgroundColor={glassSurface ?? surface}
|
||||
backgroundColor={cardSurface}
|
||||
borderRadius={14}
|
||||
borderWidth={1}
|
||||
borderColor={border}
|
||||
borderColor={cardBorder}
|
||||
padding="$2.5"
|
||||
flexGrow={1}
|
||||
flexBasis="48%"
|
||||
@@ -242,7 +246,7 @@ export function KpiStrip({
|
||||
>
|
||||
{item.value}
|
||||
</Text>
|
||||
<Separator vertical backgroundColor={border} height={32} opacity={0.6} />
|
||||
<Separator vertical backgroundColor={separatorColor} height={32} />
|
||||
<YStack alignItems="center" space="$0.5">
|
||||
<XStack
|
||||
width={28}
|
||||
@@ -264,7 +268,7 @@ export function KpiStrip({
|
||||
>
|
||||
{item.label}
|
||||
</Text>
|
||||
<Separator backgroundColor={border} opacity={0.4} width={28} alignSelf="center" />
|
||||
<Separator backgroundColor={innerSeparatorColor} width={28} alignSelf="center" />
|
||||
{item.note ? (
|
||||
<Text fontSize={9} fontWeight="800" color={iconColor} opacity={0.9} textTransform="uppercase">
|
||||
{item.note}
|
||||
|
||||
@@ -127,6 +127,8 @@ export function useAdminTheme() {
|
||||
border,
|
||||
text,
|
||||
textStrong: text, // Alias
|
||||
textMuted: muted, // Alias for legacy usage
|
||||
textSubtle: subtle, // Alias for legacy usage
|
||||
muted, // Now properly derived from text color
|
||||
subtle, // Now properly derived from text color
|
||||
primary,
|
||||
@@ -134,12 +136,12 @@ export function useAdminTheme() {
|
||||
accentSoft: String(theme.blue3?.val ?? ADMIN_COLORS.accentSoft),
|
||||
accentStrong: String(theme.blue11?.val ?? ADMIN_COLORS.primaryStrong),
|
||||
successBg: String(theme.backgroundStrong?.val ?? '#DCFCE7'),
|
||||
successText: String(theme.green10?.val ?? '#166534'),
|
||||
successText: String(theme.green10?.val ?? ADMIN_COLORS.success),
|
||||
dangerBg: String(theme.red3?.val ?? '#FEE2E2'),
|
||||
dangerText: String(theme.red11?.val ?? ADMIN_COLORS.danger),
|
||||
warningBg: String(theme.yellow3?.val ?? '#FEF3C7'),
|
||||
warningBorder: String(theme.yellow6?.val ?? '#FCD34D'),
|
||||
warningText: String(theme.yellow11?.val ?? '#B45309'),
|
||||
warningText: String(theme.yellow11?.val ?? ADMIN_COLORS.warning),
|
||||
infoBg: String(theme.blue3?.val ?? ADMIN_COLORS.accentSoft),
|
||||
infoText: String(theme.blue10?.val ?? ADMIN_COLORS.primaryStrong),
|
||||
danger: String(theme.danger?.val ?? ADMIN_COLORS.danger),
|
||||
|
||||
Reference in New Issue
Block a user