Files
qiming/qiming-xagi-frontend-templates/packages/react-vite/tailwind.config.js
2026-06-01 13:43:09 +08:00

507 lines
10 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** @type {import('tailwindcss').Config} */
// Tailwind default palette names
const defaultColors = [
'slate',
'gray',
'zinc',
'neutral',
'stone',
'red',
'orange',
'amber',
'yellow',
'lime',
'green',
'emerald',
'teal',
'cyan',
'sky',
'blue',
'indigo',
'violet',
'purple',
'fuchsia',
'pink',
'rose',
];
// Custom palette extension
const customColors = ['primary'];
// Shade steps
const colorShades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
// Utility prefixes that take color tokens
const colorPrefixes = [
'text',
'bg',
'border',
'ring',
'divide',
'placeholder',
'from',
'via',
'to',
'stroke',
'fill',
'accent',
'caret',
'outline',
];
// Build safelist entries for color utilities
function generateColorSafelist() {
const safelist = [];
const allColors = [...defaultColors, ...customColors];
// For each color-related prefix × palette name
colorPrefixes.forEach(prefix => {
allColors.forEach(color => {
// Shade-specific classes (e.g. text-blue-500)
colorShades.forEach(shade => {
safelist.push(`${prefix}-${color}-${shade}`);
});
// Base color token without shade
safelist.push(`${prefix}-${color}`);
});
});
// Special keywords: white, black, transparent, current
const specialColors = ['white', 'black', 'transparent', 'current'];
colorPrefixes.forEach(prefix => {
specialColors.forEach(color => {
safelist.push(`${prefix}-${color}`);
});
});
return safelist;
}
// Default Tailwind spacing scale
const spacingValues = [
0,
0.5,
1,
1.5,
2,
2.5,
3,
3.5,
4,
5,
6,
7,
8,
9,
10,
11,
12,
14,
16,
20,
24,
28,
32,
36,
40,
44,
48,
52,
56,
60,
64,
72,
80,
96,
// Extra spacing keys used in this project
18,
88,
// Keyword spacing tokens
'px',
'auto',
'full',
'screen',
];
// Padding / margin utility prefixes
const spacingPrefixes = {
padding: ['p', 'px', 'py', 'pt', 'pr', 'pb', 'pl'],
margin: ['m', 'mx', 'my', 'mt', 'mr', 'mb', 'ml'],
};
// Safelist spacing utilities
function generateSpacingSafelist() {
const safelist = [];
const allPrefixes = [...spacingPrefixes.padding, ...spacingPrefixes.margin];
// For each prefix × spacing value
allPrefixes.forEach(prefix => {
spacingValues.forEach(value => {
// Numeric spacing (p-3, m-4, fractional keys, …)
if (typeof value === 'number') {
// Numeric keys; Tailwind normalizes fractional classes
safelist.push(`${prefix}-${value}`);
} else {
// Keyword spacing (px, auto, full, screen)
safelist.push(`${prefix}-${value}`);
}
});
});
return safelist;
}
// Default border-width scale
const borderWidthValues = [0, 1, 2, 4, 8];
// Border-width utility prefixes
const borderWidthPrefixes = [
'border',
'border-t',
'border-r',
'border-b',
'border-l',
'border-x',
'border-y',
];
// Safelist border-width utilities
function generateBorderWidthSafelist() {
const safelist = [];
// For each prefix × width value
borderWidthPrefixes.forEach(prefix => {
borderWidthValues.forEach(value => {
// e.g. border-0, border-2, border-4, border-8
safelist.push(`${prefix}-${value}`);
});
});
// Plain `border` (default 1px)
safelist.push('border');
return safelist;
}
// Default border-style keywords
const borderStyleValues = [
'solid',
'dashed',
'dotted',
'double',
'hidden',
'none',
];
// Safelist border-style utilities
function generateBorderStyleSafelist() {
const safelist = [];
// border-solid, border-dashed, …
borderStyleValues.forEach(style => {
safelist.push(`border-${style}`);
});
return safelist;
}
// Default font-weight tokens
const fontWeightValues = [
'thin', // 100
'extralight', // 200
'light', // 300
'normal', // 400
'medium', // 500
'semibold', // 600
'bold', // 700
'extrabold', // 800
'black', // 900
];
// Safelist font-weight utilities
function generateFontWeightSafelist() {
const safelist = [];
// font-thin, font-light, font-bold, …
fontWeightValues.forEach(weight => {
safelist.push(`font-${weight}`);
});
return safelist;
}
// Default text-size keys
// Matches Tailwind docs: xs … 9xl
const fontSizeValues = [
'xs',
'sm',
'base',
'lg',
'xl',
'2xl',
'3xl',
'4xl',
'5xl',
'6xl',
'7xl',
'8xl',
'9xl',
];
// Safelist text-* size utilities
function generateFontSizeSafelist() {
const safelist = [];
// text-sm, text-base, text-lg, …
fontSizeValues.forEach(size => {
safelist.push(`text-${size}`);
});
return safelist;
}
// Default line-height keys
// Matches Tailwind: none … loose, numeric 310
const lineHeightValues = [
'none',
'tight',
'snug',
'normal',
'relaxed',
'loose',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
];
// Safelist leading-* utilities
function generateLineHeightSafelist() {
const safelist = [];
// leading-none, leading-tight, leading-5, …
lineHeightValues.forEach(value => {
safelist.push(`leading-${value}`);
});
return safelist;
}
// Default letter-spacing tokens
// Matches Tailwind tracking scale
const letterSpacingValues = [
'tighter',
'tight',
'normal',
'wide',
'wider',
'widest',
];
// Safelist tracking-* utilities
function generateLetterSpacingSafelist() {
const safelist = [];
// tracking-tighter, tracking-wide, …
letterSpacingValues.forEach(value => {
safelist.push(`tracking-${value}`);
});
return safelist;
}
// Default text-align keywords
// Matches Tailwind text-* alignment
const textAlignValues = ['left', 'center', 'right', 'justify', 'start', 'end'];
// Safelist text-align utilities (text-left, …)
function generateTextAlignSafelist() {
const safelist = [];
// Note: shares `text-` prefix with font sizes in safelist
textAlignValues.forEach(value => {
safelist.push(`text-${value}`);
});
return safelist;
}
// Default opacity percentage steps
// Matches Tailwind opacity scale
const opacityValues = [
0, 5, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90, 95, 100,
];
// Safelist opacity-* utilities
function generateOpacitySafelist() {
const safelist = [];
// opacity-0, opacity-50, opacity-100, …
opacityValues.forEach(value => {
safelist.push(`opacity-${value}`);
});
return safelist;
}
// Default border-radius keys
// Matches Tailwind rounded-* scale
const borderRadiusValues = [
'none',
'sm',
'md',
'lg',
'xl',
'2xl',
'3xl',
'full',
];
// rounded-* utility prefixes
const borderRadiusPrefixes = [
'rounded',
'rounded-t',
'rounded-r',
'rounded-b',
'rounded-l',
'rounded-tl',
'rounded-tr',
'rounded-bl',
'rounded-br',
];
// Safelist rounded utilities
function generateBorderRadiusSafelist() {
const safelist = [];
// For each rounded prefix × radius token
borderRadiusPrefixes.forEach(prefix => {
borderRadiusValues.forEach(value => {
// rounded-md, rounded-lg, rounded-tl-sm, …
safelist.push(`${prefix}-${value}`);
});
});
return safelist;
}
// Default box-shadow tokens
// Matches Tailwind shadow-* scale
const shadowValues = ['sm', 'md', 'lg', 'xl', '2xl', 'inner', 'none'];
// Safelist shadow-* utilities
function generateShadowSafelist() {
const safelist = [];
// shadow-sm, shadow-md, shadow-lg, …
shadowValues.forEach(value => {
safelist.push(`shadow-${value}`);
});
return safelist;
}
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
// Merge every generated utility into safelist so dynamic class names are not purged
safelist: [
...generateColorSafelist(),
...generateSpacingSafelist(),
...generateBorderWidthSafelist(),
...generateBorderStyleSafelist(),
...generateFontWeightSafelist(),
...generateFontSizeSafelist(),
...generateLineHeightSafelist(),
...generateLetterSpacingSafelist(),
...generateTextAlignSafelist(),
...generateOpacitySafelist(),
...generateBorderRadiusSafelist(),
...generateShadowSafelist(),
],
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
},
gray: {
50: '#f9fafb',
100: '#f3f4f6',
200: '#e5e7eb',
300: '#d1d5db',
400: '#9ca3af',
500: '#6b7280',
600: '#4b5563',
700: '#374151',
800: '#1f2937',
900: '#111827',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['Fira Code', 'monospace'],
},
spacing: {
18: '4.5rem',
88: '22rem',
},
borderRadius: {
'4xl': '2rem',
},
boxShadow: {
soft: '0 2px 15px -3px rgba(0, 0, 0, 0.07), 0 10px 20px -2px rgba(0, 0, 0, 0.04)',
},
animation: {
'fade-in': 'fadeIn 0.5s ease-in-out',
'slide-up': 'slideUp 0.3s ease-out',
'bounce-slow': 'bounce 2s infinite',
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
'accordion-down': {
from: { height: '0' },
to: { height: 'var(--radix-accordion-content-height)' },
},
'accordion-up': {
from: { height: 'var(--radix-accordion-content-height)' },
to: { height: '0' },
},
},
},
},
plugins: [
function ({ addUtilities }) {
const newUtilities = {
'.text-balance': {
'text-wrap': 'balance',
},
};
addUtilities(newUtilities);
},
],
darkMode: 'class',
};