统一组件图标布局并完善选择吸附交互

This commit is contained in:
ljz committed 2026-08-06 23:35:50 +08:00
1 parent 40c72422ff
commit 7671418582
16 files changed
+4359 -598

No files matched your search

+28 -3
View File
@@ -1,4 +1,6 @@
import type { ReactNode } from "react";
import { createContext, useContext, type ReactNode } from "react";
import type { ComponentSymbolViewBox } from "./types";
export type SymbolDomain =
| "neutral"
@@ -11,25 +13,48 @@ type SymbolSvgProps = {
children: ReactNode;
className?: string;
domain?: SymbolDomain;
viewBox?: string;
strokeScaling?: "independent" | "geometry";
};
type SymbolViewBoxProviderProps = {
children: ReactNode;
viewBox: ComponentSymbolViewBox;
};
const SymbolViewBoxContext = createContext("0 -8 64 64");
export const SYMBOL_STROKE = "var(--component-symbol-stroke, currentColor)";
export const SYMBOL_FILL = "var(--component-symbol-fill, #ffffff)";
export const SYMBOL_ACCENT = "var(--component-symbol-accent, currentColor)";
export const SYMBOL_MUTED = "var(--component-symbol-muted, #64748b)";
/** 由图标注册表统一提供 SVG 画布,避免渲染器与接口布局分别维护 viewBox。 */
export function SymbolViewBoxProvider({
children,
viewBox,
}: SymbolViewBoxProviderProps) {
return (
<SymbolViewBoxContext.Provider
value={`${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`}
>
{children}
</SymbolViewBoxContext.Provider>
);
}
export function SymbolSvg({
children,
className,
domain = "neutral",
viewBox = "0 0 64 48",
strokeScaling = "independent",
}: SymbolSvgProps) {
const viewBox = useContext(SymbolViewBoxContext);
return (
<svg
aria-hidden="true"
className={["component-symbol-svg", className].filter(Boolean).join(" ")}
data-symbol-domain={domain}
data-symbol-stroke-scaling={strokeScaling}
fill="none"
focusable="false"
viewBox={viewBox}