@unocss/svelte-scoped
Version:
Use UnoCSS in a modular fashion with styles being stored only in the Svelte component they are used in: Vite plugin for apps, Svelte preprocessor for component libraries
103 lines (102 loc) • 4.39 kB
JavaScript
import { i as transformClasses, n as transformStyle, r as themeRE, t as checkForApply } from "./transformStyle-CBL_Mx-C.mjs";
import process from "node:process";
import { createRecoveryConfigLoader } from "@unocss/config";
import { createGenerator, warnOnce } from "@unocss/core";
import presetWind3 from "@unocss/preset-wind3";
import MagicString from "magic-string";
//#region src/_preprocess/addGeneratedStyles.ts
const actualStylesTagWithCapturedDirectivesRE = new RegExp(/(?<!<!--\s*)/.source + /<style([^>]*)>[\s\S]*?<\/style\s*>/.source, "g");
const captureOpeningStyleTagWithAttributesRE = /(<style[^>]*>)/;
function addGeneratedStylesIntoStyleBlock(s, styles) {
if (s.original.match(actualStylesTagWithCapturedDirectivesRE)) s.replace(captureOpeningStyleTagWithAttributesRE, `$1${styles}`);
else s.append(`\n<style>${styles}</style>`);
}
//#endregion
//#region src/_preprocess/wrapGlobal.ts
const EXTRACT_SELECTOR_RE = new RegExp(/(?<![\d(])/.source + /([[.][\s\S]+?)/.source + /(\{[\s\S]+?\})/.source, "g");
function wrapSelectorsWithGlobal(css) {
return css.replace(EXTRACT_SELECTOR_RE, ":global($1)$2");
}
//#endregion
//#region src/_preprocess/index.ts
function UnocssSveltePreprocess(options = {}, unoContextFromVite, isViteBuild) {
if (!options.classPrefix) options.classPrefix = "usp-";
let uno;
const makeGenerator = async () => {
if (unoContextFromVite) {
await unoContextFromVite.ready;
return unoContextFromVite.uno;
}
const defaults = { presets: [presetWind3()] };
return await createGenerator((await createRecoveryConfigLoader()(process.cwd(), options.configOrPath)).config, defaults);
};
return {
markup: async ({ content, filename }) => {
uno ??= await makeGenerator();
if (isViteBuild && options.combine === void 0) options.combine = isViteBuild();
const s = new MagicString(content);
const transformed = await transformClasses({
s,
filename: filename ?? "",
uno,
options,
removeCommentsToMakeGlobalWrappingEasy: true
});
if (!transformed) return;
addGeneratedStylesIntoStyleBlock(s, wrapSelectorsWithGlobal(transformed.generatedStyles));
if (s.hasChanged()) return {
code: s.toString(),
map: s.generateMap({
hires: true,
source: filename ?? ""
})
};
},
style: async ({ content, attributes, filename }) => {
const svelte3AddPreflights = attributes["uno:preflights"];
const svelte3AddSafelist = attributes["uno:safelist"];
const svelte4DeprecatedAddPreflights = attributes.uno && attributes.preflights;
const svelte4DeprecatedAddSafelist = attributes.uno && attributes.safelist;
let addPreflights = attributes["uno-preflights"] || svelte3AddPreflights || svelte4DeprecatedAddPreflights;
let addSafelist = attributes["uno-safelist"] || svelte3AddSafelist || svelte4DeprecatedAddSafelist;
if (unoContextFromVite && (addPreflights || addSafelist)) {
addPreflights = false;
addSafelist = false;
warnOnce("Notice for those transitioning to @unocss/svelte-scoped/vite: uno-preflights and uno-safelist are only for use in component libraries. Please see the documentation for how to add preflights and safelist into your head tag. If you are consuming a component library built by @unocss/svelte-scoped/preprocess, you can ignore this upgrade notice.");
}
const { hasApply, applyVariables } = checkForApply(content, options.applyVariables);
const hasThemeFn = options.transformThemeDirective === false ? false : !!content.match(themeRE);
if (!(addPreflights || addSafelist || hasApply || hasThemeFn)) return;
uno ??= await makeGenerator();
let preflightsSafelistCss = "";
if (addPreflights || addSafelist) {
const { css } = await uno.generate([], {
preflights: !!addPreflights,
safelist: !!addSafelist,
minify: true
});
preflightsSafelistCss = wrapSelectorsWithGlobal(css);
}
if (hasApply || hasThemeFn) {
const s = new MagicString(content);
await transformStyle({
s,
uno,
prepend: preflightsSafelistCss,
applyVariables,
transformThemeFn: hasThemeFn
});
if (s.hasChanged()) return {
code: s.toString(),
map: s.generateMap({
hires: true,
source: filename ?? ""
})
};
}
if (preflightsSafelistCss) return { code: preflightsSafelistCss + content };
}
};
}
//#endregion
export { UnocssSveltePreprocess as default };