feat(ui): refine gem-blue acrylic palette and focus borders
Derive the gem-blue palette with OKLCH tonal and complementary-color rules while preserving acrylic opacity, blur and surface hierarchy. Darker focus tokens exposed stacked field rings, fallback outlines and persistent basemap selection rings. Keep fallback focus styles in the base layer and use one themed field boundary or inset card stroke. Preserve keyboard focus, invalid states and native input semantics. Add browser regression coverage for pointer and keyboard focus, all basemap presentations, narrow layouts and rendered contrast. Validation in an isolated checkout: pnpm lint, pnpm typecheck, pnpm test (393 tests), focused browser suites and pnpm build.
This commit is contained in:
@@ -57,7 +57,7 @@ export function MapAnnotationPanel({
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<div className={cn("px-3 py-2 text-xs text-slate-500", MAP_READABLE_RADIUS_CLASS_NAME, MAP_READABLE_SURFACE_CLASS_NAME)}>
|
||||
<div className={cn("px-3 py-2 text-xs text-[var(--ink-muted)]", MAP_READABLE_RADIUS_CLASS_NAME, MAP_READABLE_SURFACE_CLASS_NAME)}>
|
||||
{emptyText}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
|
||||
MAP_READABLE_RADIUS_CLASS_NAME,
|
||||
MAP_READABLE_SURFACE_CLASS_NAME,
|
||||
MAP_SELECTION_CARD_FOCUS_CLASS_NAME,
|
||||
MAP_TOOL_PANEL_SURFACE_CLASS_NAME
|
||||
} from "./map-control-styles";
|
||||
|
||||
@@ -85,12 +86,12 @@ export function BaseLayersControl({
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center gap-2 px-1">
|
||||
<span className={cn("grid h-8 w-8 shrink-0 place-items-center bg-blue-50 text-blue-700", MAP_ICON_CELL_RADIUS_CLASS_NAME)}>
|
||||
<span className={cn("grid h-8 w-8 shrink-0 place-items-center bg-[var(--action-soft)] text-[var(--action-blue-hover)]", MAP_ICON_CELL_RADIUS_CLASS_NAME)}>
|
||||
<Map size={17} aria-hidden="true" />
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<h2 className="truncate text-sm font-semibold leading-tight text-slate-950">{title}</h2>
|
||||
<p className="mt-0.5 truncate text-xs text-slate-500">
|
||||
<p className="mt-0.5 truncate text-xs text-[var(--ink-muted)]">
|
||||
当前 {activeLayer?.label ?? "--"}
|
||||
</p>
|
||||
</div>
|
||||
@@ -110,10 +111,11 @@ export function BaseLayersControl({
|
||||
className={cn(
|
||||
"flex min-h-[76px] flex-col p-1 text-left transition duration-150",
|
||||
MAP_READABLE_RADIUS_CLASS_NAME,
|
||||
MAP_SELECTION_CARD_FOCUS_CLASS_NAME,
|
||||
MAP_READABLE_SURFACE_CLASS_NAME,
|
||||
active
|
||||
? "border-blue-500 text-blue-700 shadow-xs ring-2 ring-blue-100"
|
||||
: "text-slate-700 hover:border-blue-300 hover:bg-blue-50/40",
|
||||
? "border-[var(--action-blue)] text-[var(--action-blue-hover)] shadow-xs"
|
||||
: "text-slate-700 hover:border-[var(--palette-brand)] hover:bg-[var(--action-soft)]/40",
|
||||
option.disabled && "cursor-not-allowed opacity-50"
|
||||
)}
|
||||
>
|
||||
@@ -163,8 +165,9 @@ export function BaseLayersControl({
|
||||
className={cn(
|
||||
"flex h-[84px] w-[84px] flex-col p-1 text-center transition duration-150",
|
||||
MAP_READABLE_RADIUS_CLASS_NAME,
|
||||
MAP_SELECTION_CARD_FOCUS_CLASS_NAME,
|
||||
MAP_READABLE_SURFACE_CLASS_NAME,
|
||||
active ? "border-blue-500 shadow-xs ring-2 ring-blue-100" : "border-slate-200 hover:border-blue-300 hover:bg-blue-50/40",
|
||||
active ? "border-[var(--action-blue)] shadow-xs" : "border-[var(--surface-divider)] hover:border-[var(--palette-brand)] hover:bg-[var(--action-soft)]/40",
|
||||
option.disabled && "cursor-not-allowed opacity-50"
|
||||
)}
|
||||
>
|
||||
@@ -184,11 +187,11 @@ export function BaseLayersControl({
|
||||
type="button"
|
||||
aria-label={`${title}:当前 ${activeLayer?.label ?? ""}`}
|
||||
title={`${title}:当前 ${activeLayer?.label ?? ""}`}
|
||||
className={cn("grid h-[84px] w-[84px] place-items-center p-1 text-slate-700 shadow-xs transition hover:border-blue-300 hover:text-blue-700", MAP_READABLE_RADIUS_CLASS_NAME, MAP_READABLE_SURFACE_CLASS_NAME)}
|
||||
className={cn("grid h-[84px] w-[84px] place-items-center p-1 text-slate-700 shadow-xs transition hover:border-[var(--palette-brand)] hover:text-[var(--action-blue-hover)]", MAP_READABLE_RADIUS_CLASS_NAME, MAP_READABLE_SURFACE_CLASS_NAME, MAP_SELECTION_CARD_FOCUS_CLASS_NAME)}
|
||||
>
|
||||
<span className={cn("relative h-full w-full overflow-hidden border border-white shadow-inner", MAP_ICON_CELL_RADIUS_CLASS_NAME)}>
|
||||
{activeLayer ? (
|
||||
<span className={cn("absolute inset-0", activeLayer.swatchClassName ?? "bg-slate-100")} />
|
||||
<span className={cn("absolute inset-0", activeLayer.swatchClassName ?? "bg-[var(--surface-control)]")} />
|
||||
) : (
|
||||
<Map size={18} aria-hidden="true" className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2" />
|
||||
)}
|
||||
@@ -213,11 +216,11 @@ function BaseLayerSwatch({ option, active }: BaseLayerSwatchProps) {
|
||||
className={cn(
|
||||
"relative block min-h-0 flex-1 overflow-hidden border border-white shadow-inner",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
option.swatchClassName ?? "bg-slate-100"
|
||||
option.swatchClassName ?? "bg-[var(--surface-control)]"
|
||||
)}
|
||||
>
|
||||
{active ? (
|
||||
<span className="absolute right-0.5 top-0.5 grid h-4 w-4 place-items-center rounded-full bg-blue-600 text-white shadow-xs">
|
||||
<span className="absolute right-0.5 top-0.5 grid h-4 w-4 place-items-center rounded-full bg-[var(--action-blue)] text-white shadow-xs">
|
||||
<Check size={10} aria-hidden="true" />
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
@@ -45,12 +45,12 @@ export function MapControlPanel({
|
||||
)}
|
||||
>
|
||||
<div className={cn("relative mb-3 flex items-center gap-2.5 px-2.5 py-2", MAP_READABLE_RADIUS_CLASS_NAME, MAP_READABLE_SURFACE_CLASS_NAME)}>
|
||||
<span className={cn("grid h-8 w-8 shrink-0 place-items-center bg-blue-100 text-blue-700", MAP_ICON_CELL_RADIUS_CLASS_NAME)}>
|
||||
<span className={cn("grid h-8 w-8 shrink-0 place-items-center bg-[var(--action-selection-soft)] text-[var(--action-blue-hover)]", MAP_ICON_CELL_RADIUS_CLASS_NAME)}>
|
||||
<Icon size={17} aria-hidden="true" />
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<h2 className="truncate text-sm font-semibold leading-tight text-slate-950">{title}</h2>
|
||||
{description ? <p className="mt-0.5 truncate text-xs text-slate-500">{description}</p> : null}
|
||||
{description ? <p className="mt-0.5 truncate text-xs text-[var(--ink-muted)]">{description}</p> : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className={cn("relative space-y-3", contentClassName)}>{children}</div>
|
||||
@@ -61,7 +61,7 @@ export function MapControlPanel({
|
||||
export function MapPanelSection({ title, children }: { title: string; children: ReactNode }) {
|
||||
return (
|
||||
<section>
|
||||
<div className="mb-1.5 px-1 text-xs font-semibold text-slate-500">{title}</div>
|
||||
<div className="mb-1.5 px-1 text-xs font-semibold text-[var(--ink-muted)]">{title}</div>
|
||||
<div className="space-y-1.5">{children}</div>
|
||||
</section>
|
||||
);
|
||||
@@ -85,7 +85,7 @@ export function MapModeButton({ icon: Icon, label, active = false, disabled = fa
|
||||
className={cn(
|
||||
"flex h-14 flex-col items-center justify-center gap-1 text-xs font-semibold transition duration-150",
|
||||
MAP_COMPACT_RADIUS_CLASS_NAME,
|
||||
active ? "bg-blue-600 text-white" : "surface-control text-slate-600 hover:text-blue-700",
|
||||
active ? "bg-[var(--action-blue)] text-white" : "surface-control text-slate-600 hover:text-[var(--action-blue-hover)]",
|
||||
disabled && "cursor-not-allowed opacity-55 hover:text-slate-600"
|
||||
)}
|
||||
>
|
||||
@@ -112,7 +112,7 @@ export function MapActionChip({
|
||||
disabled={disabled}
|
||||
onClick={onClick}
|
||||
className={cn(
|
||||
"flex h-10 items-center justify-center gap-1.5 text-xs font-semibold text-slate-700 transition duration-150 hover:border-blue-200 hover:text-blue-700",
|
||||
"flex h-10 items-center justify-center gap-1.5 text-xs font-semibold text-slate-700 transition duration-150 hover:border-[var(--surface-border)] hover:text-[var(--action-blue-hover)]",
|
||||
MAP_COMPACT_RADIUS_CLASS_NAME,
|
||||
MAP_READABLE_SURFACE_CLASS_NAME,
|
||||
disabled && "cursor-not-allowed opacity-55 hover:border-white/70 hover:text-slate-700"
|
||||
@@ -163,17 +163,17 @@ export function MapActionRow({
|
||||
"flex min-h-12 w-full items-center gap-2.5 border px-2.5 py-2 text-left",
|
||||
MAP_COMPACT_RADIUS_CLASS_NAME,
|
||||
isPrimary
|
||||
? "border-blue-600 bg-blue-600 text-white shadow-lg shadow-blue-600/25 hover:bg-blue-700"
|
||||
? "border-[var(--action-blue)] bg-[var(--action-blue)] text-white shadow-lg shadow-[color:var(--action-blue)]/25 hover:bg-[var(--action-blue-hover)]"
|
||||
: strong
|
||||
? "border-blue-100 bg-blue-50/95 text-blue-800"
|
||||
: "surface-control border-transparent text-slate-700 hover:border-blue-100 hover:bg-white hover:text-blue-700",
|
||||
? "border-[var(--surface-border)] bg-[var(--action-soft)]/95 text-[var(--action-blue-pressed)]"
|
||||
: "surface-control border-transparent text-slate-700 hover:border-[var(--surface-border)] hover:bg-[var(--surface-reading)] hover:text-[var(--action-blue-hover)]",
|
||||
isDanger && "hover:border-red-100 hover:text-red-700",
|
||||
selected && !isPrimary && "border-blue-200 bg-blue-50 text-blue-800",
|
||||
selected && !isPrimary && "border-[var(--surface-border)] bg-[var(--action-soft)] text-[var(--action-blue-pressed)]",
|
||||
muted && "opacity-70",
|
||||
disabled &&
|
||||
(isPrimary
|
||||
? "cursor-not-allowed opacity-55 hover:border-blue-600 hover:bg-blue-600 hover:text-white"
|
||||
: "cursor-not-allowed opacity-55 hover:border-white/70 hover:bg-white/95 hover:text-slate-700"),
|
||||
? "cursor-not-allowed opacity-55 hover:border-[var(--action-blue)] hover:bg-[var(--action-blue-hover)] hover:text-white"
|
||||
: "cursor-not-allowed opacity-55 hover:border-white/70 hover:bg-[var(--surface-reading)]/95 hover:text-slate-700"),
|
||||
disabled && "shadow-none"
|
||||
)}
|
||||
>
|
||||
@@ -182,10 +182,10 @@ export function MapActionRow({
|
||||
"grid h-8 w-8 shrink-0 place-items-center",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
isPrimary
|
||||
? "bg-white/16 text-white"
|
||||
? "bg-[var(--surface-reading)]/16 text-white"
|
||||
: selected || strong
|
||||
? "bg-blue-600 text-white"
|
||||
: "bg-slate-100 text-slate-500",
|
||||
? "bg-[var(--action-blue)] text-white"
|
||||
: "bg-[var(--surface-control)] text-[var(--ink-muted)]",
|
||||
isDanger && "bg-red-50 text-red-600"
|
||||
)}
|
||||
>
|
||||
@@ -193,19 +193,19 @@ export function MapActionRow({
|
||||
</span>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate text-sm font-semibold">{label}</span>
|
||||
<span className={cn("block truncate text-xs", isPrimary ? "text-blue-100" : "text-slate-500")}>{description}</span>
|
||||
<span className={cn("block truncate text-xs", isPrimary ? "text-[var(--palette-paper)]" : "text-[var(--ink-muted)]")}>{description}</span>
|
||||
</span>
|
||||
{status ? (
|
||||
<span
|
||||
className={cn(
|
||||
"shrink-0 rounded-full px-2 py-0.5 text-xs font-semibold",
|
||||
isPrimary ? "bg-white/15 text-white" : "bg-slate-100 text-slate-500"
|
||||
isPrimary ? "bg-[var(--surface-reading)]/15 text-white" : "bg-[var(--surface-control)] text-[var(--ink-muted)]"
|
||||
)}
|
||||
>
|
||||
{status}
|
||||
</span>
|
||||
) : (
|
||||
<ChevronRight size={15} aria-hidden="true" className={cn("shrink-0", isPrimary ? "text-blue-100" : "text-slate-400")} />
|
||||
<ChevronRight size={15} aria-hidden="true" className={cn("shrink-0", isPrimary ? "text-[var(--palette-paper)]" : "text-[var(--ink-muted)]")} />
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
@@ -214,7 +214,7 @@ export function MapActionRow({
|
||||
export function MapMetricTile({ label, value }: { label: string; value: string }) {
|
||||
return (
|
||||
<div className={cn("px-2.5 py-2", MAP_READABLE_RADIUS_CLASS_NAME, MAP_READABLE_SURFACE_STRONG_CLASS_NAME)}>
|
||||
<div className="text-xs text-slate-500">{label}</div>
|
||||
<div className="text-xs text-[var(--ink-muted)]">{label}</div>
|
||||
<div className="mt-1 truncate text-sm font-semibold text-slate-900">{value}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -53,19 +53,19 @@ export function MapDrawToolbar({ items, label = "绘制工具", className = "",
|
||||
"flex min-h-10 items-center gap-2 border px-2.5 py-2 text-left text-xs font-semibold transition duration-150",
|
||||
MAP_COMPACT_RADIUS_CLASS_NAME,
|
||||
item.active
|
||||
? "border-blue-600 bg-blue-600 text-white shadow-[var(--action-shadow-primary)]"
|
||||
: "text-slate-700 hover:border-blue-100 hover:bg-white hover:text-blue-700",
|
||||
? "border-[var(--action-blue)] bg-[var(--action-blue)] text-white shadow-[var(--action-shadow-primary)]"
|
||||
: "text-slate-700 hover:border-[var(--surface-border)] hover:bg-[var(--surface-reading)] hover:text-[var(--action-blue-hover)]",
|
||||
!item.active && MAP_READABLE_SURFACE_CLASS_NAME,
|
||||
isDanger && "hover:border-red-100 hover:text-red-700",
|
||||
item.disabled &&
|
||||
"cursor-not-allowed opacity-55 hover:border-white/70 hover:bg-white/95 hover:text-slate-700"
|
||||
"cursor-not-allowed opacity-55 hover:border-white/70 hover:bg-[var(--surface-reading)]/95 hover:text-slate-700"
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
"grid h-7 w-7 shrink-0 place-items-center",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
item.active ? "bg-white/16 text-white" : "bg-slate-100 text-slate-500",
|
||||
item.active ? "bg-[var(--surface-reading)]/16 text-white" : "bg-[var(--surface-control)] text-[var(--ink-muted)]",
|
||||
isDanger && "bg-red-50 text-red-600"
|
||||
)}
|
||||
>
|
||||
@@ -108,8 +108,8 @@ export function MapDrawToolbar({ items, label = "绘制工具", className = "",
|
||||
"grid h-10 w-10 shrink-0 place-items-center border border-transparent text-slate-600",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
item.active
|
||||
? "border-blue-600 bg-blue-600 text-white shadow-[var(--action-shadow-primary)]"
|
||||
: "hover:bg-blue-50 hover:text-blue-700",
|
||||
? "border-[var(--action-blue)] bg-[var(--action-blue)] text-white shadow-[var(--action-shadow-primary)]"
|
||||
: "hover:bg-[var(--action-soft)] hover:text-[var(--action-blue-hover)]",
|
||||
isDanger && "hover:bg-red-50 hover:text-red-700",
|
||||
item.disabled && "opacity-45 hover:bg-transparent hover:text-slate-600"
|
||||
)}
|
||||
@@ -120,7 +120,7 @@ export function MapDrawToolbar({ items, label = "绘制工具", className = "",
|
||||
<TooltipContent
|
||||
side="top"
|
||||
sideOffset={7}
|
||||
className="border border-slate-200 bg-white px-2.5 py-1.5 text-xs font-medium text-slate-800 shadow-lg"
|
||||
className="border border-[var(--surface-divider)] bg-[var(--surface-reading)] px-2.5 py-1.5 text-xs font-medium text-slate-800 shadow-lg"
|
||||
>
|
||||
{item.label}
|
||||
</TooltipContent>
|
||||
|
||||
@@ -58,12 +58,12 @@ export function MapLayerControl({
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3 px-1">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
<span className={cn("grid h-8 w-8 shrink-0 place-items-center bg-blue-50 text-blue-700", MAP_ICON_CELL_RADIUS_CLASS_NAME)}>
|
||||
<span className={cn("grid h-8 w-8 shrink-0 place-items-center bg-[var(--action-soft)] text-[var(--action-blue-hover)]", MAP_ICON_CELL_RADIUS_CLASS_NAME)}>
|
||||
<Layers3 size={17} aria-hidden="true" />
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<h2 className="truncate text-sm font-semibold leading-tight text-slate-950">{title}</h2>
|
||||
<p className="mt-0.5 text-xs text-slate-500">
|
||||
<p className="mt-0.5 text-xs text-[var(--ink-muted)]">
|
||||
{items.filter((item) => item.visible).length}/{items.length} 可见
|
||||
</p>
|
||||
</div>
|
||||
@@ -86,8 +86,8 @@ export function MapLayerControl({
|
||||
"flex min-h-12 w-full items-center gap-3 border px-2.5 text-left text-sm transition duration-150",
|
||||
MAP_COMPACT_RADIUS_CLASS_NAME,
|
||||
item.visible
|
||||
? "surface-control border-blue-100 text-slate-900"
|
||||
: "surface-well border-transparent text-slate-500 hover:border-slate-200 hover:bg-white",
|
||||
? "surface-control border-[var(--surface-border)] text-slate-900"
|
||||
: "surface-well border-transparent text-[var(--ink-muted)] hover:border-[var(--surface-divider)] hover:bg-[var(--surface-reading)]",
|
||||
disabled && "cursor-not-allowed opacity-60 hover:bg-transparent"
|
||||
)}
|
||||
>
|
||||
@@ -95,19 +95,19 @@ export function MapLayerControl({
|
||||
className={cn(
|
||||
"grid h-8 w-8 shrink-0 place-items-center",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
item.visible ? "bg-blue-600 text-white" : "bg-slate-100 text-slate-400"
|
||||
item.visible ? "bg-[var(--action-blue)] text-white" : "bg-[var(--surface-control)] text-[var(--ink-muted)]"
|
||||
)}
|
||||
>
|
||||
{item.locked ? <Lock size={15} aria-hidden="true" /> : <Icon size={15} aria-hidden="true" />}
|
||||
</span>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate font-semibold">{item.label}</span>
|
||||
{item.description ? <span className="block truncate text-xs text-slate-500">{item.description}</span> : null}
|
||||
{item.description ? <span className="block truncate text-xs text-[var(--ink-muted)]">{item.description}</span> : null}
|
||||
</span>
|
||||
<span
|
||||
className={cn(
|
||||
"h-2.5 w-2.5 rounded-full",
|
||||
item.visible ? "bg-blue-600" : "bg-slate-300"
|
||||
item.visible ? "bg-[var(--action-blue)]" : "bg-slate-300"
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
MAP_READABLE_RADIUS_CLASS_NAME,
|
||||
MAP_READABLE_SURFACE_CLASS_NAME,
|
||||
MAP_READABLE_SURFACE_STRONG_CLASS_NAME
|
||||
MAP_READABLE_SURFACE_STRONG_CLASS_NAME,
|
||||
MAP_SELECTION_CARD_FOCUS_CLASS_NAME
|
||||
} from "./map-control-styles";
|
||||
|
||||
export type MapLayerPanelProps = {
|
||||
@@ -71,27 +72,27 @@ function LayerVisibilitySection({ items, onToggleLayer }: LayerVisibilitySection
|
||||
<ChevronRight
|
||||
size={14}
|
||||
aria-hidden="true"
|
||||
className="shrink-0 text-slate-400 transition-transform duration-150 ease-out motion-reduce:transition-none group-open/layer:rotate-90"
|
||||
className="shrink-0 text-[var(--ink-muted)] transition-transform duration-150 ease-out motion-reduce:transition-none group-open/layer:rotate-90"
|
||||
/>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate text-xs font-semibold text-slate-700">{group.label}</span>
|
||||
{group.description ? (
|
||||
<span className="mt-0.5 block truncate text-[10px] leading-tight text-slate-500">
|
||||
<span className="mt-0.5 block truncate text-[10px] leading-tight text-[var(--ink-muted)]">
|
||||
{group.description}
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
<span className="shrink-0 rounded-full bg-white/75 px-2 py-0.5 text-[10px] font-medium tabular-nums text-slate-500 shadow-xs shadow-slate-950/5">
|
||||
<span className="shrink-0 rounded-full bg-[var(--surface-reading)]/75 px-2 py-0.5 text-[10px] font-medium tabular-nums text-[var(--ink-muted)] shadow-xs shadow-slate-950/5">
|
||||
{group.items.filter((item) => item.visible).length}/{group.items.length}
|
||||
</span>
|
||||
</summary>
|
||||
<div className="border-t border-slate-200/70 bg-white/45 p-1.5">
|
||||
<div className="border-t border-[var(--surface-divider)]/70 bg-[var(--surface-reading)]/45 p-1.5">
|
||||
{groupLayerItemsByCollection(group.items).map((collection) => (
|
||||
<div key={collection.id} className="not-first:mt-2.5">
|
||||
{collection.label ? (
|
||||
<div className="mb-1 flex items-center gap-2 px-1.5 text-[10px] font-medium text-slate-500">
|
||||
<div className="mb-1 flex items-center gap-2 px-1.5 text-[10px] font-medium text-[var(--ink-muted)]">
|
||||
<span className="truncate">{collection.label}</span>
|
||||
<span className="h-px min-w-3 flex-1 bg-slate-200/80" aria-hidden="true" />
|
||||
<span className="h-px min-w-3 flex-1 bg-[var(--surface-divider)]/80" aria-hidden="true" />
|
||||
<span className="shrink-0 tabular-nums">{collection.items.length} 层</span>
|
||||
</div>
|
||||
) : null}
|
||||
@@ -181,11 +182,11 @@ function LayerVisibilityRow({
|
||||
title={meta}
|
||||
onClick={() => onToggleLayer(item.id, !item.visible)}
|
||||
className={cn(
|
||||
"flex min-h-12 w-full items-center gap-2.5 border px-2 py-1.5 text-left transition-[background-color,border-color,color,box-shadow,transform] duration-150 ease-out motion-reduce:transition-none active:scale-[0.98] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-blue-500/60 focus-visible:ring-offset-1",
|
||||
"flex min-h-12 w-full items-center gap-2.5 border px-2 py-1.5 text-left transition-[background-color,border-color,color,box-shadow,transform] duration-150 ease-out motion-reduce:transition-none active:scale-[0.98] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-[var(--action-focus-ring)] focus-visible:ring-offset-1",
|
||||
MAP_COMPACT_RADIUS_CLASS_NAME,
|
||||
item.visible
|
||||
? "border-blue-200/90 bg-white text-slate-950 shadow-xs shadow-slate-950/5"
|
||||
: "border-transparent bg-slate-100/55 text-slate-600 [@media(hover:hover)]:hover:border-slate-200 [@media(hover:hover)]:hover:bg-white/75",
|
||||
? "border-[var(--surface-border)]/90 bg-[var(--surface-reading)] text-slate-950 shadow-xs shadow-slate-950/5"
|
||||
: "border-transparent bg-[var(--surface-control)]/55 text-slate-600 [@media(hover:hover)]:hover:border-[var(--surface-divider)] [@media(hover:hover)]:hover:bg-[var(--surface-reading)]/75",
|
||||
disabled && "cursor-not-allowed opacity-55 active:scale-100"
|
||||
)}
|
||||
>
|
||||
@@ -193,7 +194,7 @@ function LayerVisibilityRow({
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate text-xs font-semibold leading-tight">{item.label}</span>
|
||||
{meta ? (
|
||||
<span className="mt-0.5 block truncate text-[10px] leading-tight text-slate-500">
|
||||
<span className="mt-0.5 block truncate text-[10px] leading-tight text-[var(--ink-muted)]">
|
||||
{meta}
|
||||
</span>
|
||||
) : null}
|
||||
@@ -201,7 +202,7 @@ function LayerVisibilityRow({
|
||||
<span
|
||||
className={cn(
|
||||
"grid h-8 w-8 shrink-0 place-items-center rounded-lg transition-[background-color,color,opacity] duration-150 motion-reduce:transition-none",
|
||||
item.visible ? "bg-blue-50 text-blue-700" : "bg-transparent text-slate-400"
|
||||
item.visible ? "bg-[var(--action-soft)] text-[var(--action-blue-hover)]" : "bg-transparent text-[var(--ink-muted)]"
|
||||
)}
|
||||
>
|
||||
{item.locked ? <Lock size={15} aria-hidden="true" /> : <Icon size={15} aria-hidden="true" />}
|
||||
@@ -236,7 +237,7 @@ function LayerVisual({
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className={cn(
|
||||
"grid h-8 w-8 shrink-0 place-items-center rounded-lg bg-slate-50 shadow-inner shadow-slate-950/5 transition-opacity duration-150 motion-reduce:transition-none",
|
||||
"grid h-8 w-8 shrink-0 place-items-center rounded-lg bg-[var(--surface-reading)] shadow-inner shadow-slate-950/5 transition-opacity duration-150 motion-reduce:transition-none",
|
||||
!visible && "opacity-45"
|
||||
)}
|
||||
>
|
||||
@@ -292,8 +293,8 @@ function BaseLayerSection({ options, activeLayerId, onSelectLayer }: BaseLayerSe
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-1.5 flex items-center justify-between px-1">
|
||||
<span className="text-xs font-semibold text-slate-500">底图</span>
|
||||
<MapIcon size={14} aria-hidden="true" className="text-slate-400" />
|
||||
<span className="text-xs font-semibold text-[var(--ink-muted)]">底图</span>
|
||||
<MapIcon size={14} aria-hidden="true" className="text-[var(--ink-muted)]" />
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
{options.map((option) => {
|
||||
@@ -309,10 +310,11 @@ function BaseLayerSection({ options, activeLayerId, onSelectLayer }: BaseLayerSe
|
||||
className={cn(
|
||||
"flex min-h-[76px] flex-col p-1 text-left transition duration-150",
|
||||
MAP_READABLE_RADIUS_CLASS_NAME,
|
||||
MAP_SELECTION_CARD_FOCUS_CLASS_NAME,
|
||||
active ? MAP_READABLE_SURFACE_STRONG_CLASS_NAME : MAP_READABLE_SURFACE_CLASS_NAME,
|
||||
active
|
||||
? "border-blue-500 text-blue-700 ring-2 ring-blue-100"
|
||||
: "text-slate-700 hover:border-blue-300 hover:bg-blue-50/40",
|
||||
? "border-[var(--action-blue)] text-[var(--action-blue-hover)]"
|
||||
: "text-slate-700 hover:border-[var(--palette-brand)] hover:bg-[var(--action-soft)]/40",
|
||||
option.disabled && "cursor-not-allowed opacity-50"
|
||||
)}
|
||||
>
|
||||
@@ -339,11 +341,11 @@ function BaseLayerSwatch({ option, active }: BaseLayerSwatchProps) {
|
||||
className={cn(
|
||||
"relative block min-h-0 flex-1 overflow-hidden border border-white shadow-inner",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
option.swatchClassName ?? "bg-slate-100"
|
||||
option.swatchClassName ?? "bg-[var(--surface-control)]"
|
||||
)}
|
||||
>
|
||||
{active ? (
|
||||
<span className="absolute right-0.5 top-0.5 grid h-4 w-4 place-items-center rounded-full bg-blue-600 text-white">
|
||||
<span className="absolute right-0.5 top-0.5 grid h-4 w-4 place-items-center rounded-full bg-[var(--action-blue)] text-white">
|
||||
<Check size={10} aria-hidden="true" />
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
@@ -40,7 +40,7 @@ export function MapLegend({ title = "图例", items, className = "" }: MapLegend
|
||||
)}
|
||||
>
|
||||
<h2 className="px-1 text-sm font-semibold leading-tight text-slate-950">{title}</h2>
|
||||
<p className="mt-0.5 px-1 text-xs text-slate-500">当前地图符号与分级</p>
|
||||
<p className="mt-0.5 px-1 text-xs text-[var(--ink-muted)]">当前地图符号与分级</p>
|
||||
<MapLegendList items={items} className="mt-3" />
|
||||
</section>
|
||||
);
|
||||
@@ -58,7 +58,7 @@ export function MapLegendList({ items, className = "" }: MapLegendListProps) {
|
||||
return (
|
||||
<div className={cn("surface-well rounded-xl border px-3 py-4 text-center", className)}>
|
||||
<p className="text-xs font-semibold text-slate-700">暂无可见业务图层</p>
|
||||
<p className="mt-1 text-[11px] leading-relaxed text-slate-500">请先在图层面板中打开需要查看的内容。</p>
|
||||
<p className="mt-1 text-[11px] leading-relaxed text-[var(--ink-muted)]">请先在图层面板中打开需要查看的内容。</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -75,21 +75,21 @@ export function MapLegendList({ items, className = "" }: MapLegendListProps) {
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate text-xs font-semibold text-slate-700">{group.label}</span>
|
||||
{group.description ? (
|
||||
<span className="mt-0.5 block truncate text-[10px] leading-tight text-slate-500">
|
||||
<span className="mt-0.5 block truncate text-[10px] leading-tight text-[var(--ink-muted)]">
|
||||
{group.description}
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
<span className="shrink-0 rounded-full bg-white/75 px-2 py-0.5 text-[10px] font-medium tabular-nums text-slate-500 shadow-xs shadow-slate-950/5">
|
||||
<span className="shrink-0 rounded-full bg-[var(--surface-reading)]/75 px-2 py-0.5 text-[10px] font-medium tabular-nums text-[var(--ink-muted)] shadow-xs shadow-slate-950/5">
|
||||
{group.items.length} 类
|
||||
</span>
|
||||
</div>
|
||||
<ul
|
||||
className={cn(
|
||||
"border-t border-slate-200/70",
|
||||
"border-t border-[var(--surface-divider)]/70",
|
||||
group.layout === "grid"
|
||||
? "grid grid-cols-2 gap-px bg-slate-200/70"
|
||||
: "divide-y divide-slate-200/70 bg-white/45"
|
||||
? "grid grid-cols-2 gap-px bg-[var(--surface-divider)]/70"
|
||||
: "divide-y divide-[var(--surface-divider)]/70 bg-[var(--surface-reading)]/45"
|
||||
)}
|
||||
>
|
||||
{group.items.map((item) => (
|
||||
@@ -134,13 +134,13 @@ function LegendItem({ item, compact }: { item: MapLegendItem; compact: boolean }
|
||||
<li
|
||||
className={cn(
|
||||
"flex items-center text-slate-700",
|
||||
compact ? "min-h-11 gap-2 bg-white/70 px-2 py-1.5" : "min-h-9 gap-2.5 px-2.5 py-1.5"
|
||||
compact ? "min-h-11 gap-2 bg-[var(--surface-reading)]/70 px-2 py-1.5" : "min-h-9 gap-2.5 px-2.5 py-1.5"
|
||||
)}
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className={cn(
|
||||
"grid shrink-0 place-items-center bg-slate-50 shadow-inner shadow-slate-950/5",
|
||||
"grid shrink-0 place-items-center bg-[var(--surface-reading)] shadow-inner shadow-slate-950/5",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
compact ? "h-7 w-7" : "h-7 w-9"
|
||||
)}
|
||||
@@ -156,11 +156,11 @@ function LegendItem({ item, compact }: { item: MapLegendItem; compact: boolean }
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate text-[11px] font-semibold leading-tight">{item.label}</span>
|
||||
{compact && item.description ? (
|
||||
<span className="mt-0.5 block truncate text-[10px] leading-tight text-slate-500">{item.description}</span>
|
||||
<span className="mt-0.5 block truncate text-[10px] leading-tight text-[var(--ink-muted)]">{item.description}</span>
|
||||
) : null}
|
||||
</span>
|
||||
{!compact && item.description ? (
|
||||
<span className="shrink-0 text-[10px] text-slate-500">{item.description}</span>
|
||||
<span className="shrink-0 text-[10px] text-[var(--ink-muted)]">{item.description}</span>
|
||||
) : null}
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,9 @@ export const MAP_COMPACT_RADIUS_CLASS_NAME = MAP_CONTROL_RADIUS_CLASS_NAME;
|
||||
|
||||
export const MAP_ICON_CELL_RADIUS_CLASS_NAME = "rounded-lg";
|
||||
|
||||
export const MAP_SELECTION_CARD_FOCUS_CLASS_NAME =
|
||||
"outline-hidden focus-visible:outline-1 focus-visible:outline-solid focus-visible:outline-[var(--action-focus-ring)] focus-visible:-outline-offset-1";
|
||||
|
||||
export const MAP_CONTROL_SURFACE_CLASS_NAME =
|
||||
"acrylic-control border";
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ export function MapMeasurePanel({
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<section>
|
||||
<div className="mb-1.5 px-1 text-xs font-semibold text-slate-500 max-lg:hidden">
|
||||
<div className="mb-1.5 px-1 text-xs font-semibold text-[var(--ink-muted)] max-lg:hidden">
|
||||
测量类型
|
||||
</div>
|
||||
<div
|
||||
@@ -98,8 +98,8 @@ export function MapMeasurePanel({
|
||||
"flex h-10 min-w-0 touch-manipulation items-center justify-center gap-1.5 px-2 text-xs font-semibold transition-[color,background-color,box-shadow,transform] duration-150 ease-out focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-[var(--action-focus-ring)] focus-visible:ring-offset-1 focus-visible:ring-offset-[var(--action-focus-offset)] active:scale-95 motion-reduce:transition-none",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
mode.id === activeModeId
|
||||
? "bg-blue-600 text-white shadow-[var(--action-shadow-primary)]"
|
||||
: "text-slate-600 [@media(hover:hover)]:hover:bg-white/85 [@media(hover:hover)]:hover:text-blue-700",
|
||||
? "bg-[var(--action-blue)] text-white shadow-[var(--action-shadow-primary)]"
|
||||
: "text-slate-600 [@media(hover:hover)]:hover:bg-[var(--surface-reading)]/85 [@media(hover:hover)]:hover:text-[var(--action-blue-hover)]",
|
||||
mode.disabled && "cursor-not-allowed opacity-45 active:scale-100"
|
||||
)}
|
||||
>
|
||||
@@ -117,12 +117,12 @@ export function MapMeasurePanel({
|
||||
<div className="px-3.5 py-2.5">
|
||||
<div className="flex min-w-0 items-start justify-between gap-3">
|
||||
<div className="min-w-0 pt-0.5">
|
||||
<div className="text-xs font-semibold text-blue-700">{resultLabel}</div>
|
||||
<div className="text-xs font-semibold text-[var(--action-blue-hover)]">{resultLabel}</div>
|
||||
<div className="mt-1.5 flex min-w-0 items-baseline gap-1.5 text-slate-950">
|
||||
<span className="truncate text-[32px] font-semibold leading-none tracking-[-0.02em] tabular-nums">
|
||||
{resultValue}
|
||||
</span>
|
||||
<span className="shrink-0 text-xs font-semibold text-slate-500">{resultUnit}</span>
|
||||
<span className="shrink-0 text-xs font-semibold text-[var(--ink-muted)]">{resultUnit}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -140,8 +140,8 @@ export function MapMeasurePanel({
|
||||
"h-10 min-w-10 touch-manipulation px-2 text-xs font-semibold transition-[color,background-color,box-shadow,transform] duration-150 ease-out focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-[var(--action-focus-ring)] focus-visible:ring-offset-1 focus-visible:ring-offset-[var(--action-focus-offset)] active:scale-95 motion-reduce:transition-none",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
unit.id === activeUnitId
|
||||
? "bg-blue-600 text-white shadow-[var(--action-shadow-primary)]"
|
||||
: "text-slate-600 [@media(hover:hover)]:hover:bg-white/85 [@media(hover:hover)]:hover:text-blue-700"
|
||||
? "bg-[var(--action-blue)] text-white shadow-[var(--action-shadow-primary)]"
|
||||
: "text-slate-600 [@media(hover:hover)]:hover:bg-[var(--surface-reading)]/85 [@media(hover:hover)]:hover:text-[var(--action-blue-hover)]"
|
||||
)}
|
||||
>
|
||||
{unit.label}
|
||||
@@ -152,13 +152,13 @@ export function MapMeasurePanel({
|
||||
</div>
|
||||
|
||||
{metrics.length > 0 ? (
|
||||
<dl className="grid grid-cols-[repeat(auto-fit,minmax(92px,1fr))] border-t border-slate-200/80">
|
||||
<dl className="grid grid-cols-[repeat(auto-fit,minmax(92px,1fr))] border-t border-[var(--surface-divider)]/80">
|
||||
{metrics.map((metric, index) => (
|
||||
<div
|
||||
key={metric.label}
|
||||
className={cn("min-w-0 px-3.5 py-2", index > 0 && "border-l border-slate-200/80")}
|
||||
className={cn("min-w-0 px-3.5 py-2", index > 0 && "border-l border-[var(--surface-divider)]/80")}
|
||||
>
|
||||
<dt className="truncate text-[11px] text-slate-500">{metric.label}</dt>
|
||||
<dt className="truncate text-[11px] text-[var(--ink-muted)]">{metric.label}</dt>
|
||||
<dd className="mt-0.5 truncate text-sm font-semibold tabular-nums text-slate-900">
|
||||
{metric.value}
|
||||
</dd>
|
||||
@@ -172,28 +172,28 @@ export function MapMeasurePanel({
|
||||
className={cn(
|
||||
"flex min-h-10 items-center gap-2.5 border-t px-3.5 py-2",
|
||||
status.tone === "active"
|
||||
? "border-blue-100 bg-blue-50/90"
|
||||
? "border-[var(--surface-border)] bg-[var(--action-soft)]/90"
|
||||
: status.tone === "ready"
|
||||
? "border-emerald-100 bg-emerald-50/80"
|
||||
: "border-slate-200/80 bg-slate-50/75"
|
||||
: "border-[var(--surface-divider)]/80 bg-[var(--surface-reading)]/75"
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
"h-2 w-2 shrink-0 rounded-full",
|
||||
status.tone === "active"
|
||||
? "bg-blue-600 motion-safe:animate-pulse"
|
||||
? "bg-[var(--action-blue)] motion-safe:animate-pulse"
|
||||
: status.tone === "ready"
|
||||
? "bg-emerald-500"
|
||||
: status.tone === "disabled"
|
||||
? "bg-amber-400"
|
||||
? "bg-[var(--status-warning-mark)]"
|
||||
: "bg-slate-400"
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div className="flex min-w-0 items-baseline gap-2">
|
||||
<div className="shrink-0 text-xs font-semibold text-slate-800">{status.label}</div>
|
||||
<div className="truncate text-[11px] text-slate-500">{status.description}</div>
|
||||
<div className="truncate text-[11px] text-[var(--ink-muted)]">{status.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -238,18 +238,18 @@ function MeasureActionButton({
|
||||
MAP_COMPACT_RADIUS_CLASS_NAME,
|
||||
primary
|
||||
? active
|
||||
? "border-blue-300 bg-white text-slate-950 shadow-[0_3px_10px_rgba(37,99,235,0.14)] ring-1 ring-inset ring-blue-100 [@media(hover:hover)]:hover:border-blue-400 [@media(hover:hover)]:hover:bg-blue-50/70"
|
||||
? "border-[var(--palette-brand)] bg-[var(--surface-reading)] text-slate-950 shadow-[0_3px_10px_rgba(37,99,235,0.14)] ring-1 ring-inset ring-[var(--surface-border)] [@media(hover:hover)]:hover:border-[var(--palette-brand)] [@media(hover:hover)]:hover:bg-[var(--action-soft)]/70"
|
||||
: action.variant === "primary"
|
||||
? "border-slate-200 bg-slate-50/90 text-slate-900 shadow-xs [@media(hover:hover)]:hover:border-slate-300 [@media(hover:hover)]:hover:bg-white"
|
||||
? "border-[var(--surface-divider)] bg-[var(--surface-reading)]/90 text-slate-900 shadow-xs [@media(hover:hover)]:hover:border-[var(--surface-border)] [@media(hover:hover)]:hover:bg-[var(--surface-reading)]"
|
||||
: "border-slate-800 bg-slate-800 text-white shadow-xs [@media(hover:hover)]:hover:border-slate-900 [@media(hover:hover)]:hover:bg-slate-900"
|
||||
: cn(
|
||||
MAP_READABLE_SURFACE_CLASS_NAME,
|
||||
danger
|
||||
? "text-red-600 [@media(hover:hover)]:hover:border-red-200 [@media(hover:hover)]:hover:bg-red-50"
|
||||
: "text-slate-700 [@media(hover:hover)]:hover:border-blue-200 [@media(hover:hover)]:hover:text-blue-700"
|
||||
: "text-slate-700 [@media(hover:hover)]:hover:border-[var(--surface-border)] [@media(hover:hover)]:hover:text-[var(--action-blue-hover)]"
|
||||
),
|
||||
action.disabled &&
|
||||
"cursor-not-allowed opacity-45 shadow-none active:scale-100 [@media(hover:hover)]:hover:border-slate-200 [@media(hover:hover)]:hover:bg-transparent [@media(hover:hover)]:hover:text-slate-700"
|
||||
"cursor-not-allowed opacity-45 shadow-none active:scale-100 [@media(hover:hover)]:hover:border-[var(--surface-divider)] [@media(hover:hover)]:hover:bg-transparent [@media(hover:hover)]:hover:text-slate-700"
|
||||
)}
|
||||
>
|
||||
{primary ? (
|
||||
@@ -257,8 +257,8 @@ function MeasureActionButton({
|
||||
className={cn(
|
||||
"grid h-8 w-8 shrink-0 place-items-center rounded-lg",
|
||||
active
|
||||
? "bg-blue-600 text-white"
|
||||
: "bg-white text-slate-700 ring-1 ring-inset ring-slate-200"
|
||||
? "bg-[var(--action-blue)] text-white"
|
||||
: "bg-[var(--surface-reading)] text-slate-700 ring-1 ring-inset ring-[var(--surface-divider)]"
|
||||
)}
|
||||
>
|
||||
<Icon size={15} strokeWidth={2.2} aria-hidden="true" />
|
||||
@@ -269,7 +269,7 @@ function MeasureActionButton({
|
||||
{primary ? (
|
||||
<span className="min-w-0 flex-1 text-left">
|
||||
<span className="block truncate text-sm font-semibold leading-4">{action.label}</span>
|
||||
<span className="mt-0.5 block truncate text-[10px] font-medium leading-3 text-slate-500">
|
||||
<span className="mt-0.5 block truncate text-[10px] font-medium leading-3 text-[var(--ink-muted)]">
|
||||
{action.description}
|
||||
</span>
|
||||
</span>
|
||||
@@ -278,12 +278,12 @@ function MeasureActionButton({
|
||||
)}
|
||||
{primary ? (
|
||||
active ? (
|
||||
<span className="flex shrink-0 items-center gap-1 rounded-full bg-blue-50 px-2 py-1 text-[10px] font-semibold text-blue-700 ring-1 ring-inset ring-blue-200">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-blue-600 motion-safe:animate-pulse" aria-hidden="true" />
|
||||
<span className="flex shrink-0 items-center gap-1 rounded-full bg-[var(--action-soft)] px-2 py-1 text-[10px] font-semibold text-[var(--action-blue-hover)] ring-1 ring-inset ring-[var(--surface-border)]">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[var(--action-blue)] motion-safe:animate-pulse" aria-hidden="true" />
|
||||
进行中
|
||||
</span>
|
||||
) : (
|
||||
<ChevronRight size={16} aria-hidden="true" className="shrink-0 text-slate-400" />
|
||||
<ChevronRight size={16} aria-hidden="true" className="shrink-0 text-[var(--ink-muted)]" />
|
||||
)
|
||||
) : null}
|
||||
</button>
|
||||
|
||||
@@ -44,7 +44,7 @@ export function showMapNotice(options: MapNoticeOptions) {
|
||||
: undefined,
|
||||
classNames: {
|
||||
cancelButton: cn(
|
||||
"pointer-events-auto absolute right-2 top-2 z-10 grid h-8 w-8 place-items-center border border-transparent bg-transparent p-0 text-slate-400 after:absolute after:-inset-1 after:content-[''] hover:border-slate-200 hover:bg-slate-50 hover:text-slate-700",
|
||||
"pointer-events-auto absolute right-2 top-2 z-10 grid h-8 w-8 place-items-center border border-transparent bg-transparent p-0 text-[var(--ink-muted)] after:absolute after:-inset-1 after:content-[''] hover:border-[var(--surface-divider)] hover:bg-[var(--surface-reading)] hover:text-slate-700",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME
|
||||
)
|
||||
},
|
||||
|
||||
@@ -118,7 +118,7 @@ function MapNoticeAction({ label, onClick }: { label: string; onClick: () => voi
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className={cn(
|
||||
"pointer-events-auto mt-2 border-blue-100 bg-blue-50 text-blue-700",
|
||||
"pointer-events-auto mt-2 border-[var(--surface-border)] bg-[var(--action-soft)] text-[var(--action-blue-hover)]",
|
||||
MAP_COMPACT_RADIUS_CLASS_NAME
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -17,7 +17,7 @@ export function MapToaster() {
|
||||
classNames: {
|
||||
toast: "group pointer-events-none",
|
||||
closeButton:
|
||||
"pointer-events-auto absolute right-2 top-2 grid h-8 w-8 place-items-center rounded-lg border border-transparent text-slate-400 after:absolute after:-inset-1 after:content-[''] hover:bg-white/70 hover:text-slate-700"
|
||||
"pointer-events-auto absolute right-2 top-2 grid h-8 w-8 place-items-center rounded-lg border border-transparent text-[var(--ink-muted)] after:absolute after:-inset-1 after:content-[''] hover:bg-[var(--surface-reading)]/70 hover:text-slate-700"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -125,7 +125,7 @@ export function MapScaleLine({
|
||||
) : (
|
||||
<span className={cn(COORDINATE_READOUT_WIDTH_CLASS_NAME, "min-w-0 truncate text-right tabular-nums")}>{coordinateLabel}</span>
|
||||
)}
|
||||
<span className="text-slate-500">Mapbox/OSM</span>
|
||||
<span className="text-[var(--ink-muted)]">Mapbox/OSM</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -70,9 +70,9 @@ export function MapToolbar({
|
||||
"relative grid h-10 w-10 shrink-0 place-items-center border border-transparent text-slate-700",
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
tool.active
|
||||
? "border-blue-600 bg-blue-600 text-white shadow-[var(--action-shadow-primary)]"
|
||||
? "border-[var(--action-blue)] bg-[var(--action-blue)] text-white shadow-[var(--action-shadow-primary)]"
|
||||
: MAP_CONTROL_HOVER_CLASS_NAME,
|
||||
tool.disabled && "text-slate-400 opacity-45 hover:bg-transparent hover:text-slate-400 hover:ring-0"
|
||||
tool.disabled && "text-[var(--ink-muted)] opacity-45 hover:bg-transparent hover:text-[var(--ink-muted)] hover:ring-0"
|
||||
)}
|
||||
>
|
||||
<Icon size={20} strokeWidth={2.15} aria-hidden="true" />
|
||||
@@ -87,7 +87,7 @@ export function MapToolbar({
|
||||
<TooltipContent
|
||||
side={isVertical ? "left" : "top"}
|
||||
sideOffset={8}
|
||||
className="border border-slate-200 bg-white px-2.5 py-1.5 text-xs font-medium text-slate-800 shadow-lg"
|
||||
className="border border-[var(--surface-divider)] bg-[var(--surface-reading)] px-2.5 py-1.5 text-xs font-medium text-slate-800 shadow-lg"
|
||||
>
|
||||
{title}
|
||||
</TooltipContent>
|
||||
|
||||
@@ -159,8 +159,8 @@ function ControlButton({
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
"bg-transparent text-slate-700",
|
||||
MAP_CONTROL_HOVER_CLASS_NAME,
|
||||
pressed && "bg-blue-50 text-blue-700",
|
||||
disabled && "text-slate-400 opacity-45 hover:bg-transparent hover:text-slate-400"
|
||||
pressed && "bg-[var(--action-soft)] text-[var(--action-blue-hover)]",
|
||||
disabled && "text-[var(--ink-muted)] opacity-45 hover:bg-transparent hover:text-[var(--ink-muted)]"
|
||||
)}
|
||||
>
|
||||
{Icon ? <Icon size={18} strokeWidth={2.2} aria-hidden="true" /> : content}
|
||||
@@ -169,7 +169,7 @@ function ControlButton({
|
||||
<TooltipContent
|
||||
side="left"
|
||||
sideOffset={8}
|
||||
className="border border-slate-200 bg-white px-2.5 py-1.5 text-xs font-medium text-slate-800 shadow-lg"
|
||||
className="border border-[var(--surface-divider)] bg-[var(--surface-reading)] px-2.5 py-1.5 text-xs font-medium text-slate-800 shadow-lg"
|
||||
>
|
||||
{label}
|
||||
</TooltipContent>
|
||||
@@ -206,8 +206,8 @@ function CompassModeIndicator({
|
||||
className={cn(
|
||||
"absolute -bottom-0.5 -right-0.5 min-w-4 rounded-[4px] px-0.5 text-center text-[8px] font-bold leading-3 tracking-[-0.02em] shadow-xs ring-1",
|
||||
mode === "3D"
|
||||
? "bg-blue-600 text-white ring-blue-700/30"
|
||||
: "bg-white text-slate-600 ring-slate-300"
|
||||
? "bg-[var(--action-blue)] text-white ring-[var(--action-blue)]/30"
|
||||
: "bg-[var(--surface-reading)] text-slate-600 ring-[var(--surface-border)]"
|
||||
)}
|
||||
>
|
||||
{mode}
|
||||
|
||||
Reference in New Issue
Block a user