Spaces:
Running
Running
import { globSync } from 'fast-glob'; | |
import fs from 'node:fs/promises'; | |
import { basename } from 'node:path'; | |
import { defineConfig, presetIcons, presetUno, transformerDirectives } from 'unocss'; | |
const iconPaths = globSync('./icons/*.svg'); | |
const collectionName = 'bolt'; | |
const customIconCollection = iconPaths.reduce( | |
(acc, iconPath) => { | |
const [iconName] = basename(iconPath).split('.'); | |
acc[collectionName] ??= {}; | |
acc[collectionName][iconName] = async () => fs.readFile(iconPath, 'utf8'); | |
return acc; | |
}, | |
{} as Record<string, Record<string, () => Promise<string>>>, | |
); | |
const BASE_COLORS = { | |
white: '#FFFFFF', | |
gray: { | |
50: '#FAFAFA', | |
100: '#F5F5F5', | |
200: '#E5E5E5', | |
300: '#D4D4D4', | |
400: '#A3A3A3', | |
500: '#737373', | |
600: '#525252', | |
700: '#404040', | |
800: '#262626', | |
900: '#171717', | |
950: '#0A0A0A', | |
}, | |
accent: { | |
50: '#F8F5FF', | |
100: '#F0EBFF', | |
200: '#E1D6FF', | |
300: '#CEBEFF', | |
400: '#B69EFF', | |
500: '#9C7DFF', | |
600: '#8A5FFF', | |
700: '#7645E8', | |
800: '#6234BB', | |
900: '#502D93', | |
950: '#2D1959', | |
}, | |
green: { | |
50: '#F0FDF4', | |
100: '#DCFCE7', | |
200: '#BBF7D0', | |
300: '#86EFAC', | |
400: '#4ADE80', | |
500: '#22C55E', | |
600: '#16A34A', | |
700: '#15803D', | |
800: '#166534', | |
900: '#14532D', | |
950: '#052E16', | |
}, | |
orange: { | |
50: '#FFFAEB', | |
100: '#FEEFC7', | |
200: '#FEDF89', | |
300: '#FEC84B', | |
400: '#FDB022', | |
500: '#F79009', | |
600: '#DC6803', | |
700: '#B54708', | |
800: '#93370D', | |
900: '#792E0D', | |
}, | |
red: { | |
50: '#FEF2F2', | |
100: '#FEE2E2', | |
200: '#FECACA', | |
300: '#FCA5A5', | |
400: '#F87171', | |
500: '#EF4444', | |
600: '#DC2626', | |
700: '#B91C1C', | |
800: '#991B1B', | |
900: '#7F1D1D', | |
950: '#450A0A', | |
}, | |
}; | |
const COLOR_PRIMITIVES = { | |
...BASE_COLORS, | |
alpha: { | |
white: generateAlphaPalette(BASE_COLORS.white), | |
gray: generateAlphaPalette(BASE_COLORS.gray[900]), | |
red: generateAlphaPalette(BASE_COLORS.red[500]), | |
accent: generateAlphaPalette(BASE_COLORS.accent[500]), | |
}, | |
}; | |
export default defineConfig({ | |
safelist: [ | |
...Object.keys(customIconCollection[collectionName]||{}).map(x=>`i-bolt:${x}`) | |
], | |
shortcuts: { | |
'bolt-ease-cubic-bezier': 'ease-[cubic-bezier(0.4,0,0.2,1)]', | |
'transition-theme': 'transition-[background-color,border-color,color] duration-150 bolt-ease-cubic-bezier', | |
kdb: 'bg-bolt-elements-code-background text-bolt-elements-code-text py-1 px-1.5 rounded-md', | |
'max-w-chat': 'max-w-[var(--chat-max-width)]', | |
}, | |
rules: [ | |
/** | |
* This shorthand doesn't exist in Tailwind and we overwrite it to avoid | |
* any conflicts with minified CSS classes. | |
*/ | |
['b', {}], | |
], | |
theme: { | |
colors: { | |
...COLOR_PRIMITIVES, | |
bolt: { | |
elements: { | |
borderColor: 'var(--bolt-elements-borderColor)', | |
borderColorActive: 'var(--bolt-elements-borderColorActive)', | |
background: { | |
depth: { | |
1: 'var(--bolt-elements-bg-depth-1)', | |
2: 'var(--bolt-elements-bg-depth-2)', | |
3: 'var(--bolt-elements-bg-depth-3)', | |
4: 'var(--bolt-elements-bg-depth-4)', | |
}, | |
}, | |
textPrimary: 'var(--bolt-elements-textPrimary)', | |
textSecondary: 'var(--bolt-elements-textSecondary)', | |
textTertiary: 'var(--bolt-elements-textTertiary)', | |
code: { | |
background: 'var(--bolt-elements-code-background)', | |
text: 'var(--bolt-elements-code-text)', | |
}, | |
button: { | |
primary: { | |
background: 'var(--bolt-elements-button-primary-background)', | |
backgroundHover: 'var(--bolt-elements-button-primary-backgroundHover)', | |
text: 'var(--bolt-elements-button-primary-text)', | |
}, | |
secondary: { | |
background: 'var(--bolt-elements-button-secondary-background)', | |
backgroundHover: 'var(--bolt-elements-button-secondary-backgroundHover)', | |
text: 'var(--bolt-elements-button-secondary-text)', | |
}, | |
danger: { | |
background: 'var(--bolt-elements-button-danger-background)', | |
backgroundHover: 'var(--bolt-elements-button-danger-backgroundHover)', | |
text: 'var(--bolt-elements-button-danger-text)', | |
}, | |
}, | |
item: { | |
contentDefault: 'var(--bolt-elements-item-contentDefault)', | |
contentActive: 'var(--bolt-elements-item-contentActive)', | |
contentAccent: 'var(--bolt-elements-item-contentAccent)', | |
contentDanger: 'var(--bolt-elements-item-contentDanger)', | |
backgroundDefault: 'var(--bolt-elements-item-backgroundDefault)', | |
backgroundActive: 'var(--bolt-elements-item-backgroundActive)', | |
backgroundAccent: 'var(--bolt-elements-item-backgroundAccent)', | |
backgroundDanger: 'var(--bolt-elements-item-backgroundDanger)', | |
}, | |
actions: { | |
background: 'var(--bolt-elements-actions-background)', | |
code: { | |
background: 'var(--bolt-elements-actions-code-background)', | |
}, | |
}, | |
artifacts: { | |
background: 'var(--bolt-elements-artifacts-background)', | |
backgroundHover: 'var(--bolt-elements-artifacts-backgroundHover)', | |
borderColor: 'var(--bolt-elements-artifacts-borderColor)', | |
inlineCode: { | |
background: 'var(--bolt-elements-artifacts-inlineCode-background)', | |
text: 'var(--bolt-elements-artifacts-inlineCode-text)', | |
}, | |
}, | |
messages: { | |
background: 'var(--bolt-elements-messages-background)', | |
linkColor: 'var(--bolt-elements-messages-linkColor)', | |
code: { | |
background: 'var(--bolt-elements-messages-code-background)', | |
}, | |
inlineCode: { | |
background: 'var(--bolt-elements-messages-inlineCode-background)', | |
text: 'var(--bolt-elements-messages-inlineCode-text)', | |
}, | |
}, | |
icon: { | |
success: 'var(--bolt-elements-icon-success)', | |
error: 'var(--bolt-elements-icon-error)', | |
primary: 'var(--bolt-elements-icon-primary)', | |
secondary: 'var(--bolt-elements-icon-secondary)', | |
tertiary: 'var(--bolt-elements-icon-tertiary)', | |
}, | |
preview: { | |
addressBar: { | |
background: 'var(--bolt-elements-preview-addressBar-background)', | |
backgroundHover: 'var(--bolt-elements-preview-addressBar-backgroundHover)', | |
backgroundActive: 'var(--bolt-elements-preview-addressBar-backgroundActive)', | |
text: 'var(--bolt-elements-preview-addressBar-text)', | |
textActive: 'var(--bolt-elements-preview-addressBar-textActive)', | |
}, | |
}, | |
terminals: { | |
background: 'var(--bolt-elements-terminals-background)', | |
buttonBackground: 'var(--bolt-elements-terminals-buttonBackground)', | |
}, | |
dividerColor: 'var(--bolt-elements-dividerColor)', | |
loader: { | |
background: 'var(--bolt-elements-loader-background)', | |
progress: 'var(--bolt-elements-loader-progress)', | |
}, | |
prompt: { | |
background: 'var(--bolt-elements-prompt-background)', | |
}, | |
sidebar: { | |
dropdownShadow: 'var(--bolt-elements-sidebar-dropdownShadow)', | |
buttonBackgroundDefault: 'var(--bolt-elements-sidebar-buttonBackgroundDefault)', | |
buttonBackgroundHover: 'var(--bolt-elements-sidebar-buttonBackgroundHover)', | |
buttonText: 'var(--bolt-elements-sidebar-buttonText)', | |
}, | |
cta: { | |
background: 'var(--bolt-elements-cta-background)', | |
text: 'var(--bolt-elements-cta-text)', | |
}, | |
}, | |
}, | |
}, | |
}, | |
transformers: [transformerDirectives()], | |
presets: [ | |
presetUno({ | |
dark: { | |
light: '[data-theme="light"]', | |
dark: '[data-theme="dark"]', | |
}, | |
}), | |
presetIcons({ | |
warn: true, | |
collections: { | |
...customIconCollection, | |
}, | |
unit: 'em', | |
}), | |
], | |
}); | |
/** | |
* Generates an alpha palette for a given hex color. | |
* | |
* @param hex - The hex color code (without alpha) to generate the palette from. | |
* @returns An object where keys are opacity percentages and values are hex colors with alpha. | |
* | |
* Example: | |
* | |
* ``` | |
* { | |
* '1': '#FFFFFF03', | |
* '2': '#FFFFFF05', | |
* '3': '#FFFFFF08', | |
* } | |
* ``` | |
*/ | |
function generateAlphaPalette(hex: string) { | |
return [1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].reduce( | |
(acc, opacity) => { | |
const alpha = Math.round((opacity / 100) * 255) | |
.toString(16) | |
.padStart(2, '0'); | |
acc[opacity] = `${hex}${alpha}`; | |
return acc; | |
}, | |
{} as Record<number, string>, | |
); | |
} | |