52 lines
1.4 KiB
TypeScript
52 lines
1.4 KiB
TypeScript
import type { Integration, IntegrationContext } from "../contracts/index.ts";
|
|
|
|
export interface UtilityContext {
|
|
name: string;
|
|
value?: string;
|
|
selector: string;
|
|
}
|
|
|
|
export type Utility = (context: UtilityContext) => string | undefined;
|
|
|
|
export interface LayoutHookContext {
|
|
utilities: (name: string, utility: Utility) => void;
|
|
concentric: (name?: string) => void;
|
|
}
|
|
|
|
export function concentric(name = "concentric"): Utility {
|
|
return ({ selector, value }) => {
|
|
const radius = value ?? "1rem";
|
|
return `${selector} { border-radius: ${radius}; }\n${selector} > * { border-radius: inherit; }`;
|
|
};
|
|
}
|
|
|
|
export function layoutHooks(
|
|
hook: (context: LayoutHookContext) => void,
|
|
): Integration {
|
|
return {
|
|
name: "layout-hooks",
|
|
setup(context: IntegrationContext) {
|
|
const utilities = new Map<string, Utility>();
|
|
hook({
|
|
utilities: (name, utility) => utilities.set(name, utility),
|
|
concentric: (name) =>
|
|
utilities.set(name ?? "concentric", concentric(name)),
|
|
});
|
|
context.loader("utilities", {
|
|
name: "utilities",
|
|
extensions: [".utilities.css"],
|
|
load(file) {
|
|
const css = file.source.split(/\s+/).flatMap((token) => {
|
|
const [name, value] = token.split(":", 2);
|
|
const utility = utilities.get(name ?? "");
|
|
return (
|
|
utility?.({ name: name ?? "", value, selector: `.${token}` }) ??
|
|
[]
|
|
);
|
|
});
|
|
return { data: {}, content: css.join("\n") };
|
|
},
|
|
});
|
|
},
|
|
};
|
|
}
|