@bitrix24/b24ui-nuxt
Version:
Bitrix24 UI-Kit for developing web applications REST API for NUXT & VUE
161 lines (160 loc) • 4.78 kB
JavaScript
import { createTV, cnMerge } from "tailwind-variants";
import appConfig from "#build/app.config";
const appConfigTv = appConfig;
const twMergeConfig = {
theme: {},
classGroups: {
"b24-context": [
"light",
"dark",
"edge-light",
"edge-dark",
"inherit",
"base-mode"
],
"b24-colors": [
// primary ////
"style-filled",
"style-filled-inverted",
"style-filled-success",
"style-filled-success-inverted",
"style-filled-alert",
"style-filled-alert-inverted",
"style-filled-copilot",
"style-filled-alert-inverted",
"style-filled-warning",
"style-filled-warning-inverted",
"style-filled-no-accent",
"style-filled-no-accent-inverted",
// secondary ////
"style-tinted",
"style-tinted-alert",
"style-outline",
"style-outline-accent-1",
"style-outline-accent-2",
"style-outline-no-accent",
"style-tinted-no-accent-1",
// tertiary ////
"style-plain",
"style-plain-accent",
"style-plain-no-accent",
// custom ////
"style-selection",
"style-filled-boost",
// old ////
"style-old-default",
"style-old-danger",
"style-old-success",
"style-old-warning",
"style-old-primary",
"style-old-secondary",
"style-old-collab",
"style-old-ai"
],
"b24-bg": [
// @deprecate This rule (style-blurred-bg) is deprecated and will be removed in version `3.0.0`
"style-blurred-bg",
"style-blurred-bg-input",
"style-transparent-bg"
]
},
conflictingClassGroups: {
"b24-context": ["b24-context"],
"b24-colors": ["b24-colors"],
"b24-bg": ["b24-bg"]
}
};
const config = {
...appConfigTv.b24ui?.tv || {},
twMerge: true,
twMergeConfig
};
const baseTv = /* @__PURE__ */ createTV(config);
function findReplacer(value) {
if (typeof value === "function") {
return value;
}
if (Array.isArray(value)) {
for (let i = value.length - 1; i >= 0; i--) {
const replacer = findReplacer(value[i]);
if (replacer) {
return replacer;
}
}
}
return void 0;
}
function plainClasses(value) {
if (Array.isArray(value)) {
return value.flatMap((item) => plainClasses(item));
}
if (typeof value === "function") {
return [];
}
return [value];
}
function applyReplacer(replacer, slotProps, resolveDefaults) {
return cnMerge(replacer(resolveDefaults()), ...plainClasses(slotProps.class), ...plainClasses(slotProps.className))(config) ?? "";
}
function wrapSlots(slots, directives) {
return new Proxy(slots, {
get(target, key) {
const slot = target[key];
if (typeof slot !== "function") {
return slot;
}
return (slotProps = {}) => {
const replacer = findReplacer(slotProps.class) ?? findReplacer(slotProps.className) ?? directives?.[key];
if (!replacer) {
return slot(slotProps);
}
return applyReplacer(replacer, slotProps, () => slot({ ...slotProps, class: void 0, className: void 0 }));
};
}
});
}
function extractDirectives(componentConfig) {
if (!componentConfig || typeof componentConfig !== "object") {
return { config: componentConfig };
}
let config2 = componentConfig;
let directives;
if (typeof componentConfig.base === "function") {
directives = { base: componentConfig.base };
config2 = { ...config2, base: "" };
}
const slots = componentConfig.slots;
if (slots && typeof slots === "object") {
const replacers = Object.entries(slots).filter(([, value]) => typeof value === "function");
if (replacers.length) {
directives ??= {};
const cleaned = { ...slots };
for (const [slot, replacer] of replacers) {
directives[slot] = replacer;
cleaned[slot] = "";
}
config2 = { ...config2, slots: cleaned };
}
}
return { config: config2, directives };
}
export const tv = ((componentConfig) => {
const { config: cleanConfig, directives } = extractDirectives(componentConfig);
const component = baseTv(cleanConfig);
return new Proxy(component, {
apply(target, thisArg, args) {
const result = Reflect.apply(target, thisArg, args);
if (result && typeof result === "object") {
return wrapSlots(result, directives);
}
if (typeof result === "string") {
const slotProps = args[0] ?? {};
const replacer = findReplacer(slotProps.class) ?? findReplacer(slotProps.className) ?? directives?.base;
if (replacer) {
return applyReplacer(replacer, slotProps, () => Reflect.apply(target, thisArg, [{ ...slotProps, class: void 0, className: void 0 }]));
}
}
return result;
}
});
});