Shadcn
Shadcn
DatePickerWithRange 本地化适配
interface DatePickerWithRangeProps {
onDateChange?: (start: string, end: string) => void
}
export function DatePickerWithRange({
onDateChange
}: DatePickerWithRangeProps) {
const [date, setDate] = React.useState<DateRange | undefined>({
// from: new Date(new Date().getFullYear(), 0, 20),
// to: addDays(new Date(new Date().getFullYear(), 0, 20), 20),
from: new Date(),
to: new Date(),
})
// 监听内部 date 变化,并触发外部回调
React.useEffect(() => {
if (date?.from && date?.to) {
const startStr = format(date.from, "yyyy-MM-dd")
const endStr = format(date.to, "yyyy-MM-dd")
onDateChange?.(startStr, endStr)
}
}, [date, onDateChange])
return (
<Popover>
<PopoverTrigger render={<Button variant="outline" id="date-picker-range" className="justify-start px-2.5 font-normal"><CalendarIcon data-icon="inline-start" />{date?.from ? (
date.to ? (
<>
{format(date.from, "yyyy年MM月dd日", { locale: zhCN })} -{" "}
{format(date.to, "yyyy年MM月dd日", { locale: zhCN })}
</>
) : (
format(date.from, "yyyy年MM月dd日", { locale: zhCN })
)
) : (
<span>选择日期范围</span>
)}</Button>} />
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="range"
defaultMonth={date?.from}
selected={date}
onSelect={setDate}
numberOfMonths={2}
locale={zhCN}
/>
</PopoverContent>
</Popover>
)
}
Tailwind v4 的适配性问题
Tailwind CSS v4 和最新版的 Shadcn UI 默认全面启用了 oklch 颜色空间。这是一个非常现代的 CSS 特性,在最新的 PC 浏览器(Chrome 111+, Safari 15.4+)上运行完美。
但是,Android 平板自带的内置浏览器(或稍老版本的移动端 Chrome 内核)极大概率还不支持 oklch()!
当浏览器不认识 oklch(1 0 0) 时,它会直接忽略这行 CSS,导致所有依赖这些变量的背景、边框颜色全部失效,退化成默认的透明或白色。同时,布局错乱也可能是因为某些现代 CSS 特性(如某些 Flex/Grid 复合属性)在内置浏览器上的降级。
为了在 Android/平板设备上完美运行,你需要做以下三步调整:
第一步:将 oklch 降级为 hsl 格式(最关键)
你需要把 index.css 中的颜色变量替换为所有浏览器都支持的 hsl 格式。
请将你的 :root 和 .dark 部分替换为以下高兼容性的 HSL 版本:
:root {
--background: hsl(0 0% 100%);
--foreground: hsl(240 10% 3.9%);
--card: hsl(0 0% 100%);
--card-foreground: hsl(240 10% 3.9%);
--popover: hsl(0 0% 100%);
--popover-foreground: hsl(240 10% 3.9%);
--primary: hsl(240 5.9% 10%);
--primary-foreground: hsl(0 0% 98%);
--secondary: hsl(240 4.8% 95.9%);
--secondary-foreground: hsl(240 5.9% 10%);
--muted: hsl(240 4.8% 95.9%);
--muted-foreground: hsl(240 3.8% 46.1%);
--accent: hsl(240 4.8% 95.9%);
--accent-foreground: hsl(240 5.9% 10%);
--destructive: hsl(0 84.2% 60.2%);
--border: hsl(240 5.9% 90%);
--input: hsl(240 5.9% 90%);
--ring: hsl(240 100% 50%); /* 你之前的 oklch(0.708 0 0) 类似一个灰色/主色,这里用标准占位 */
--chart-1: hsl(12 76% 61%);
--chart-2: hsl(173 58% 39%);
--chart-3: hsl(197 37% 24%);
--chart-4: hsl(43 74% 66%);
--chart-5: hsl(27 87% 67%);
--radius: 0.5rem;
--sidebar-background: hsl(0 0% 98%);
--sidebar-foreground: hsl(240 5.3% 26.1%);
--sidebar-primary: hsl(240 5.9% 10%);
--sidebar-primary-foreground: hsl(0 0% 98%);
--sidebar-accent: hsl(240 4.8% 95.9%);
--sidebar-accent-foreground: hsl(240 5.9% 10%);
--sidebar-border: hsl(220 13% 91%);
--sidebar-ring: hsl(217.2 91.2% 59.8%);
}
.dark {
--background: hsl(240 10% 3.9%);
--foreground: hsl(0 0% 98%);
--card: hsl(240 10% 3.9%);
--card-foreground: hsl(0 0% 98%);
--popover: hsl(240 10% 3.9%);
--popover-foreground: hsl(0 0% 98%);
--primary: hsl(0 0% 98%);
--primary-foreground: hsl(240 5.9% 10%);
--secondary: hsl(240 3.7% 15.9%);
--secondary-foreground: hsl(0 0% 98%);
--muted: hsl(240 3.7% 15.9%);
--muted-foreground: hsl(240 5% 64.9%);
--accent: hsl(240 3.7% 15.9%);
--accent-foreground: hsl(0 0% 98%);
--destructive: hsl(0 62.8% 30.6%);
--border: hsl(240 3.7% 15.9%);
--input: hsl(240 3.7% 15.9%);
--ring: hsl(240 4.9% 83.9%);
--chart-1: hsl(220 70% 50%);
--chart-2: hsl(160 60% 45%);
--chart-3: hsl(30 80% 55%);
--chart-4: hsl(280 65% 60%);
--chart-5: hsl(340 75% 55%);
--sidebar-background: hsl(240 5.9% 10%);
--sidebar-foreground: hsl(240 4.8% 95.9%);
--sidebar-primary: hsl(224.3 76.3% 48%);
--sidebar-primary-foreground: hsl(0 0% 100%);
--sidebar-accent: hsl(240 3.7% 15.9%);
--sidebar-accent-foreground: hsl(240 4.8% 95.9%);
--sidebar-border: hsl(240 3.7% 15.9%);
--sidebar-ring: hsl(217.2 91.2% 59.8%);
}
(注:如果这里改回 HSL 后颜色有轻微色差,是因为色彩空间不同导致的,但保证能在安卓上正常渲染出颜色。)
第二步:禁止小米浏览器的“强制深色模式”魔改
小米/安卓自带浏览器经常会自作聪明地反转你的网页颜色。
去你的 index.html 的 <head> 标签中,加上这行:
<meta name="color-scheme" content="light dark">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
color-scheme告诉浏览器:我已经自己处理了深色和浅色模式,请系统不要强行干预反转我的颜色。viewport限制最大缩放比例,防止移动端布局被轻易破坏或双击放大。
第三步:验证浏览器内核问题
为了验证是不是小米自带浏览器内核太老的问题:
你可以尝试在小米 Pad 上下载一个最新版的 Google Chrome 或 Edge 浏览器,然后通过 IP:端口 访问你的开发服务器。
- 如果在 Pad 的最新版 Chrome 里一切正常,而在自带浏览器里错乱,那 100% 是浏览器内核对新 CSS 支持不佳(尤其是 OKLCH 和嵌套语法)。
- 如果大屏项目最终是在特定的 Android 设备上的 Webview 运行(比如用你之前提到的 Godot Android Plugin 包裹),你必须确保 Android 系统中的
Android System WebView组件更新到了较新的版本,否则就会遇到一堆不兼容的问题。
总结: 把 oklch 换成 hsl,加上 color-scheme 标签,然后再在 Pad 上刷新看看,大概率颜色就能直接出来了。遇到边框消失的元素,再补一个 border-solid 即可。
浙公网安备 33010602011771号