mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-21 07:21:46 +01:00
refactor(module)!: implement design system with CSS variables (#2298)
This commit is contained in:
@@ -31,7 +31,7 @@ export interface AlertProps {
|
||||
actions?: ButtonProps[]
|
||||
/**
|
||||
* Display a close button to dismiss the alert.
|
||||
* `{ size: 'md', color: 'gray', variant: 'link' }`{lang="ts-type"}
|
||||
* `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"}
|
||||
* @emits `close`
|
||||
* @defaultValue false
|
||||
*/
|
||||
@@ -117,7 +117,7 @@ const ui = computed(() => alert({
|
||||
v-if="close"
|
||||
:icon="closeIcon || appConfig.ui.icons.close"
|
||||
size="md"
|
||||
color="gray"
|
||||
color="neutral"
|
||||
variant="link"
|
||||
aria-label="Close"
|
||||
v-bind="typeof close === 'object' ? close : undefined"
|
||||
|
||||
@@ -67,7 +67,7 @@ export interface CommandPaletteProps<G, T> extends Pick<ComboboxRootProps, 'mult
|
||||
placeholder?: InputProps['placeholder']
|
||||
/**
|
||||
* Display a close button in the input (useful when inside a Modal for example).
|
||||
* `{ size: 'md', color: 'gray', variant: 'ghost' }`{lang="ts-type"}
|
||||
* `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
|
||||
* @defaultValue false
|
||||
*/
|
||||
close?: ButtonProps | boolean
|
||||
@@ -233,7 +233,7 @@ const groups = computed(() => {
|
||||
v-if="close"
|
||||
:icon="closeIcon || appConfig.ui.icons.close"
|
||||
size="md"
|
||||
color="gray"
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
aria-label="Close"
|
||||
v-bind="typeof close === 'object' ? close : undefined"
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface ModalProps extends DialogRootProps {
|
||||
portal?: boolean
|
||||
/**
|
||||
* Display a close button to dismiss the modal.
|
||||
* `{ size: 'md', color: 'gray', variant: 'ghost' }`{lang="ts-type"}
|
||||
* `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
|
||||
* @defaultValue true
|
||||
*/
|
||||
close?: ButtonProps | boolean
|
||||
@@ -138,7 +138,7 @@ const ui = computed(() => modal({
|
||||
v-if="close"
|
||||
:icon="closeIcon || appConfig.ui.icons.close"
|
||||
size="md"
|
||||
color="gray"
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
aria-label="Close"
|
||||
v-bind="typeof close === 'object' ? close : undefined"
|
||||
|
||||
@@ -142,7 +142,7 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]
|
||||
<slot :name="item.slot ? `${item.slot}-trailing`: 'item-trailing'" :item="item" :active="active" :index="index">
|
||||
<UBadge
|
||||
v-if="item.badge"
|
||||
color="gray"
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
:size="((props.ui?.linkTrailingBadgeSize || ui.linkTrailingBadgeSize()) as BadgeProps['size'])"
|
||||
v-bind="(typeof item.badge === 'string' || typeof item.badge === 'number') ? { label: item.badge } : item.badge"
|
||||
|
||||
@@ -44,7 +44,7 @@ export interface PaginationProps extends Pick<PaginationRootProps, 'defaultPage'
|
||||
ellipsisIcon?: string
|
||||
/**
|
||||
* The color of the pagination controls.
|
||||
* @defaultValue 'gray'
|
||||
* @defaultValue 'neutral'
|
||||
*/
|
||||
color?: ButtonProps['color']
|
||||
/**
|
||||
@@ -106,7 +106,7 @@ import { useAppConfig } from '#imports'
|
||||
|
||||
const props = withDefaults(defineProps<PaginationProps>(), {
|
||||
size: 'md',
|
||||
color: 'gray',
|
||||
color: 'neutral',
|
||||
variant: 'outline',
|
||||
activeColor: 'primary',
|
||||
activeVariant: 'solid',
|
||||
|
||||
@@ -35,7 +35,7 @@ export interface SlideoverProps extends DialogRootProps {
|
||||
portal?: boolean
|
||||
/**
|
||||
* Display a close button to dismiss the slideover.
|
||||
* `{ size: 'md', color: 'gray', variant: 'ghost' }`{lang="ts-type"}
|
||||
* `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
|
||||
* @defaultValue true
|
||||
*/
|
||||
close?: ButtonProps | boolean
|
||||
@@ -137,7 +137,7 @@ const ui = computed(() => slideover({
|
||||
v-if="close"
|
||||
:icon="closeIcon || appConfig.ui.icons.close"
|
||||
size="md"
|
||||
color="gray"
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
aria-label="Close"
|
||||
v-bind="typeof close === 'object' ? close : undefined"
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open'
|
||||
actions?: ButtonProps[]
|
||||
/**
|
||||
* Display a close button to dismiss the toast.
|
||||
* `{ size: 'md', color: 'gray', variant: 'link' }`{lang="ts-type"}
|
||||
* `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"}
|
||||
* @defaultValue true
|
||||
*/
|
||||
close?: ButtonProps | boolean
|
||||
@@ -145,7 +145,7 @@ defineExpose({
|
||||
v-if="close"
|
||||
:icon="closeIcon || appConfig.ui.icons.close"
|
||||
size="md"
|
||||
color="gray"
|
||||
color="neutral"
|
||||
variant="link"
|
||||
aria-label="Close"
|
||||
v-bind="typeof close === 'object' ? close : undefined"
|
||||
|
||||
@@ -1,59 +1,50 @@
|
||||
@theme {
|
||||
--color-gray-*: initial;
|
||||
--color-cool-50: #f9fafb;
|
||||
--color-cool-100: #f3f4f6;
|
||||
--color-cool-200: #e5e7eb;
|
||||
--color-cool-300: #d1d5db;
|
||||
--color-cool-400: #9ca3af;
|
||||
--color-cool-500: #6b7280;
|
||||
--color-cool-600: #4b5563;
|
||||
--color-cool-700: #374151;
|
||||
--color-cool-800: #1f2937;
|
||||
--color-cool-900: #111827;
|
||||
--color-cool-950: #030712;
|
||||
|
||||
--spacing-4_5: 1.125rem;
|
||||
|
||||
--color-primary-50: var(--color-primary-50);
|
||||
--color-primary-100: var(--color-primary-100);
|
||||
--color-primary-200: var(--color-primary-200);
|
||||
--color-primary-300: var(--color-primary-300);
|
||||
--color-primary-400: var(--color-primary-400);
|
||||
--color-primary-500: var(--color-primary-500);
|
||||
--color-primary-600: var(--color-primary-600);
|
||||
--color-primary-700: var(--color-primary-700);
|
||||
--color-primary-800: var(--color-primary-800);
|
||||
--color-primary-900: var(--color-primary-900);
|
||||
--color-primary-950: var(--color-primary-950);
|
||||
--color-error-50: var(--color-error-50);
|
||||
--color-error-100: var(--color-error-100);
|
||||
--color-error-200: var(--color-error-200);
|
||||
--color-error-300: var(--color-error-300);
|
||||
--color-error-400: var(--color-error-400);
|
||||
--color-error-500: var(--color-error-500);
|
||||
--color-error-600: var(--color-error-600);
|
||||
--color-error-700: var(--color-error-700);
|
||||
--color-error-800: var(--color-error-800);
|
||||
--color-error-900: var(--color-error-900);
|
||||
--color-error-950: var(--color-error-950);
|
||||
--color-gray-50: var(--color-gray-50);
|
||||
--color-gray-100: var(--color-gray-100);
|
||||
--color-gray-200: var(--color-gray-200);
|
||||
--color-gray-300: var(--color-gray-300);
|
||||
--color-gray-400: var(--color-gray-400);
|
||||
--color-gray-500: var(--color-gray-500);
|
||||
--color-gray-600: var(--color-gray-600);
|
||||
--color-gray-700: var(--color-gray-700);
|
||||
--color-gray-800: var(--color-gray-800);
|
||||
--color-gray-900: var(--color-gray-900);
|
||||
--color-gray-950: var(--color-gray-950);
|
||||
}
|
||||
|
||||
@variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply antialiased font-sans text-[--ui-text] bg-[--ui-bg];
|
||||
}
|
||||
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
color-scheme: light;
|
||||
|
||||
--ui-text-dimmed: var(--ui-color-neutral-400);
|
||||
--ui-text-muted: var(--ui-color-neutral-500);
|
||||
--ui-text-toned: var(--ui-color-neutral-600);
|
||||
--ui-text: var(--ui-color-neutral-700);
|
||||
--ui-text-highlighted: var(--ui-color-neutral-900);
|
||||
|
||||
--ui-bg: var(--color-white);
|
||||
--ui-bg-elevated: var(--ui-color-neutral-100);
|
||||
--ui-bg-accented: var(--ui-color-neutral-200);
|
||||
--ui-bg-inverted: var(--ui-color-neutral-900);
|
||||
|
||||
--ui-border: var(--ui-color-neutral-200);
|
||||
--ui-border-accented: var(--ui-color-neutral-300);
|
||||
--ui-border-inverted: var(--ui-color-neutral-900);
|
||||
}
|
||||
|
||||
.dark {
|
||||
color-scheme: dark;
|
||||
|
||||
--ui-text-dimmed: var(--ui-color-neutral-500);
|
||||
--ui-text-muted: var(--ui-color-neutral-400);
|
||||
--ui-text-toned: var(--ui-color-neutral-300);
|
||||
--ui-text: var(--ui-color-neutral-200);
|
||||
--ui-text-highlighted: var(--color-white);
|
||||
|
||||
--ui-bg: var(--ui-color-neutral-900);
|
||||
--ui-bg-elevated: var(--ui-color-neutral-800);
|
||||
--ui-bg-accented: var(--ui-color-neutral-700);
|
||||
--ui-bg-inverted: var(--color-white);
|
||||
|
||||
--ui-border: var(--ui-color-neutral-800);
|
||||
--ui-border-accented: var(--ui-color-neutral-700);
|
||||
--ui-border-inverted: var(--color-white);
|
||||
}
|
||||
|
||||
@keyframes accordion-up {
|
||||
|
||||
@@ -9,19 +9,24 @@ export default defineNuxtPlugin(() => {
|
||||
|
||||
const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]
|
||||
|
||||
function generateColor(key: string, value: string) {
|
||||
return `${shades.map(shade => `--color-${key}-${shade}: var(--color-${value}-${shade});`).join('\n ')}`
|
||||
function generateShades(key: string, value: string) {
|
||||
return `${shades.map(shade => `--ui-color-${key}-${shade}: var(--color-${value}-${shade});`).join('\n ')}`
|
||||
}
|
||||
function generateColor(key: string, shade: number) {
|
||||
return `--ui-${key}: var(--ui-color-${key}-${shade});`
|
||||
}
|
||||
|
||||
const root = computed(() => {
|
||||
const { neutral, ...colors } = appConfig.ui.colors
|
||||
|
||||
return `:root {
|
||||
${Object.entries(appConfig.ui.colors).map(([key, value]: [string, string]) => generateColor(key, value)).join('\n ')}
|
||||
--color-primary-DEFAULT: var(--color-primary-500);
|
||||
${Object.entries(appConfig.ui.colors).map(([key, value]: [string, string]) => generateShades(key, value)).join('\n ')}
|
||||
|
||||
${Object.keys(colors).map(key => generateColor(key, 500)).join('\n ')}
|
||||
}
|
||||
.dark {
|
||||
--color-primary-DEFAULT: var(--color-primary-400);
|
||||
}
|
||||
`
|
||||
${Object.keys(colors).map(key => generateColor(key, 400)).join('\n ')}
|
||||
}`
|
||||
})
|
||||
|
||||
// Head
|
||||
|
||||
Reference in New Issue
Block a user