mirror of
https://github.com/unraid/api.git
synced 2026-01-07 09:10:05 -06:00
@@ -35,8 +35,7 @@ const DEFAULT_INCLUDE_ROOT = true;
|
||||
|
||||
const KEYFRAME_AT_RULES = new Set(['keyframes']);
|
||||
const NON_SCOPED_AT_RULES = new Set(['font-face', 'page']);
|
||||
const MERGE_WITH_SCOPE_PATTERNS: RegExp[] = [/^\.theme-/, /^\.has-custom-/, /^\.dark\b/, /^\.light\b/];
|
||||
const ROOT_ELEMENT_PATTERN = /^(html|body)(?=$|[.#[:\s>+~])/;
|
||||
const MERGE_WITH_SCOPE_PATTERNS: RegExp[] = [/^\.theme-/, /^\.has-custom-/, /^\.dark\b/];
|
||||
|
||||
function shouldScopeRule(rule: Rule, targetLayers: Set<string>, includeRootRules: boolean): boolean {
|
||||
const hasSelectorString = typeof rule.selector === 'string' && rule.selector.length > 0;
|
||||
@@ -105,12 +104,6 @@ function prefixSelector(selector: string, scope: string): string {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
const rootElementMatch = trimmed.match(ROOT_ELEMENT_PATTERN);
|
||||
if (rootElementMatch) {
|
||||
const suffix = trimmed.slice(rootElementMatch[0].length);
|
||||
return suffix ? `${scope}${suffix}` : scope;
|
||||
}
|
||||
|
||||
if (trimmed === ':root') {
|
||||
return scope;
|
||||
}
|
||||
|
||||
@@ -67,24 +67,6 @@ describe('scopeTailwindToUnapi plugin', () => {
|
||||
expect(rule.selector).toBe('.unapi .card');
|
||||
});
|
||||
|
||||
it('scopes html and body selectors to the root scope element', () => {
|
||||
const plugin = scopeTailwindToUnapi();
|
||||
const rule = createRule(['html', 'body.dark']);
|
||||
|
||||
plugin.Rule?.(rule);
|
||||
|
||||
expect(rule.selectors).toEqual(['.unapi', '.unapi.dark']);
|
||||
});
|
||||
|
||||
it('merges theme mode selectors onto the unapi scope', () => {
|
||||
const plugin = scopeTailwindToUnapi();
|
||||
const rule = createRule(['.light', '.dark']);
|
||||
|
||||
plugin.Rule?.(rule);
|
||||
|
||||
expect(rule.selectors).toEqual(['.unapi.light', '.unapi.dark']);
|
||||
});
|
||||
|
||||
it('processes large rule sets within the target budget', () => {
|
||||
const plugin = scopeTailwindToUnapi();
|
||||
const totalRules = 10_000;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Tailwind v4 configuration with Nuxt UI v3
|
||||
* Using scoped selectors to prevent breaking Unraid WebGUI
|
||||
*/
|
||||
@@ -9,8 +9,7 @@
|
||||
/* Import theme and utilities only - no global preflight */
|
||||
@import "tailwindcss/theme.css" layer(theme);
|
||||
@import "tailwindcss/utilities.css" layer(utilities);
|
||||
@import "@nuxt/ui/.nuxt/ui.css" layer(theme);
|
||||
@import "@nuxt/ui";
|
||||
@import "@nuxt/ui";
|
||||
@import 'tw-animate-css';
|
||||
@import '../../../@tailwind-shared/index.css';
|
||||
|
||||
@@ -18,14 +17,25 @@
|
||||
@source "../**/*.{vue,ts,js,tsx,jsx}";
|
||||
@source "../../../unraid-ui/src/**/*.{vue,ts,js,tsx,jsx}";
|
||||
|
||||
/*
|
||||
/*
|
||||
* Scoped base styles for .unapi elements only
|
||||
* Import Tailwind's preflight into our custom layer and scope it
|
||||
*/
|
||||
|
||||
@layer unapi-base {
|
||||
/* Scope Tailwind preflight so Nuxt UI components get default browser resets */
|
||||
@import "tailwindcss/preflight.css";
|
||||
/* Scope all Tailwind preflight styles to .unapi */
|
||||
.unapi {
|
||||
@import "tailwindcss/preflight.css";
|
||||
}
|
||||
|
||||
/* Override Unraid's button styles for Nuxt UI components */
|
||||
.unapi button {
|
||||
/* Reset Unraid's button styles */
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* Accessible focus styles for keyboard navigation */
|
||||
.unapi button:focus-visible {
|
||||
@@ -33,12 +43,21 @@
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Restore button functionality while removing Unraid's forced styles */
|
||||
.unapi button:not([role="switch"]) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
/* Ensure Nuxt UI modal/slideover close buttons work properly */
|
||||
.unapi [role="dialog"] button,
|
||||
.unapi [data-radix-collection-item] button {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
margin: 0 !important;
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* Focus styles for dialog buttons */
|
||||
@@ -76,6 +95,37 @@
|
||||
padding-inline-start: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
/* Reset toggle/switch button backgrounds */
|
||||
.unapi button[role="switch"],
|
||||
.unapi button[role="switch"][data-state="checked"],
|
||||
.unapi button[role="switch"][data-state="unchecked"] {
|
||||
background-color: transparent;
|
||||
background: transparent;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
/* Style for checked state */
|
||||
.unapi button[role="switch"][data-state="checked"] {
|
||||
background-color: #ff8c2f; /* Unraid orange */
|
||||
}
|
||||
|
||||
/* Style for unchecked state */
|
||||
.unapi button[role="switch"][data-state="unchecked"] {
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
/* Dark mode toggle styles */
|
||||
.unapi.dark button[role="switch"][data-state="unchecked"],
|
||||
.dark .unapi button[role="switch"][data-state="unchecked"] {
|
||||
background-color: #333;
|
||||
border-color: #555;
|
||||
}
|
||||
|
||||
/* Toggle thumb/handle */
|
||||
.unapi button[role="switch"] span {
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
|
||||
/* Override link styles inside .unapi */
|
||||
|
||||
@@ -96,8 +96,6 @@ export default defineConfig({
|
||||
'~': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
'~~': fileURLToPath(new URL('./', import.meta.url)),
|
||||
'~/': fileURLToPath(new URL('./src/', import.meta.url)),
|
||||
'#build': fileURLToPath(new URL('./node_modules/@nuxt/ui/.nuxt', import.meta.url)),
|
||||
'#build/ui.css': fileURLToPath(new URL('./node_modules/@nuxt/ui/.nuxt/ui.css', import.meta.url)),
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user