mirror of
https://github.com/moeru-ai/airi.git
synced 2026-04-28 06:29:33 +00:00
202 lines
6.4 KiB
TypeScript
202 lines
6.4 KiB
TypeScript
import type { WebFontMeta } from '@unocss/preset-web-fonts'
|
|
import type { Preset, PresetOrFactoryAwaitable } from 'unocss'
|
|
|
|
import { setDefaultAutoSelectFamilyAttemptTimeout } from 'node:net'
|
|
|
|
import { createExternalPackageIconLoader } from '@iconify/utils/lib/loader/external-pkg'
|
|
import { presetChromatic } from '@proj-airi/unocss-preset-chromatic'
|
|
import { colorToString } from '@unocss/preset-mini/utils'
|
|
import { defineConfig, mergeConfigs, presetAttributify, presetIcons, presetTypography, presetWind3, transformerDirectives, transformerVariantGroup } from 'unocss'
|
|
import { presetScrollbar } from 'unocss-preset-scrollbar'
|
|
import { parseColor } from 'unocss/preset-mini'
|
|
|
|
// On Netlify, building will result in when fetching metadata and fonts from @unocss/preset-web-fonts plugin:
|
|
//
|
|
// [cause]: AggregateError [ETIMEDOUT]:
|
|
// at internalConnectMultiple (node:net:1134:18)
|
|
// code: 'ETIMEDOUT',
|
|
// [errors]: [
|
|
// Error: connect ETIMEDOUT 146.75.77.229:443 ...
|
|
// Error: connect ENETUNREACH 2a04:4e42:83::485:443 - Local (:::0) ...
|
|
// ]
|
|
//
|
|
// This is same for either Google Fonts or Fontsource as provider. But GitHub Actions and local development works fine.
|
|
// My assumption is that the default timeout for auto-selecting family is too short (250ms)[^1] for the implementation
|
|
// of the Happy Eyeballs algorithm in Node.js, which is used by the `net` module to connect to the server, workflows
|
|
// illustrates like this:
|
|
//
|
|
// lookupAndConnect > autoSelectFamilyAttemptTimeout > lookupAndConnectMultiple > internalConnectMultiple > defaultTriggerAsyncIdScope
|
|
//
|
|
// Such mechanism will be used when the `net` module attempts to connect to a server using both IPv4 and IPv6 addresses,
|
|
// which is the case for Netlify builder.
|
|
//
|
|
// In order to fix this issue, we can increase the timeout to 1000ms (1 second) so that the algorithm has more time to
|
|
// attempt to connect to the server before timing out.
|
|
//
|
|
// [^1]: https://github.com/nodejs/node/pull/44731/files#diff-d76469e9e7f555294a7a5488c5c8fc4ef8ce5aea448cc26a1322d1ab693e09caR921
|
|
setDefaultAutoSelectFamilyAttemptTimeout(1000)
|
|
|
|
export function presetStoryMockHover(): PresetOrFactoryAwaitable {
|
|
return {
|
|
name: 'story-mock-hover',
|
|
variants: [
|
|
(matcher) => {
|
|
if (!matcher.includes('hover')) {
|
|
return matcher
|
|
}
|
|
|
|
return {
|
|
matcher,
|
|
selector: (s) => {
|
|
return `${s}, ${s.replace(/:hover$/, '')}._hover`
|
|
},
|
|
}
|
|
},
|
|
],
|
|
}
|
|
}
|
|
|
|
export function safelistAllPrimaryBackgrounds(): string[] {
|
|
return [
|
|
...[undefined, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950].map((shade) => {
|
|
const prefix = shade ? `bg-primary-${shade}` : `bg-primary`
|
|
return [
|
|
prefix,
|
|
...[5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map(opacity => `${prefix}/${opacity}`),
|
|
]
|
|
}).flat(),
|
|
]
|
|
}
|
|
|
|
export function presetWebFontsFonts(provider: 'fontsource' | 'none'): Record<string, string | WebFontMeta | (string | WebFontMeta)[]> {
|
|
return {
|
|
'sans': {
|
|
name: provider === 'fontsource' ? 'DM Sans' : 'DM Sans Variable',
|
|
provider,
|
|
},
|
|
'serif': {
|
|
name: 'DM Serif Display',
|
|
provider,
|
|
},
|
|
'mono': {
|
|
name: 'DM Mono',
|
|
provider,
|
|
},
|
|
'cute': {
|
|
name: 'Kiwi Maru',
|
|
provider,
|
|
},
|
|
'cuteen': {
|
|
name: 'Sniglet',
|
|
provider,
|
|
},
|
|
'jura': {
|
|
name: provider === 'fontsource' ? 'Jura' : 'Jura Variable',
|
|
provider,
|
|
},
|
|
'gugi': {
|
|
name: 'Gugi',
|
|
provider,
|
|
},
|
|
'quicksand': {
|
|
name: provider === 'fontsource' ? 'Quicksand' : 'Quicksand Variable',
|
|
provider,
|
|
},
|
|
'urbanist': {
|
|
name: provider === 'fontsource' ? 'Urbanist' : 'Urbanist Variable',
|
|
provider,
|
|
},
|
|
'm-plus-rounded': {
|
|
name: 'M PLUS Rounded 1c',
|
|
provider,
|
|
},
|
|
'quanlai': {
|
|
name: 'cjkfonts AllSeto',
|
|
provider: 'none',
|
|
},
|
|
'xiaolai': {
|
|
name: 'Xiaolai SC',
|
|
provider: 'none',
|
|
},
|
|
}
|
|
}
|
|
|
|
export function sharedUnoConfig() {
|
|
return defineConfig({
|
|
presets: [
|
|
presetWind3(),
|
|
presetAttributify(),
|
|
presetTypography(),
|
|
presetIcons({
|
|
scale: 1.2,
|
|
collections: {
|
|
...createExternalPackageIconLoader('@proj-airi/lobe-icons'),
|
|
},
|
|
}),
|
|
presetScrollbar(),
|
|
presetChromatic({
|
|
baseHue: 220.44,
|
|
colors: {
|
|
primary: 0,
|
|
complementary: 180,
|
|
},
|
|
}) as Preset,
|
|
],
|
|
transformers: [
|
|
transformerDirectives({
|
|
applyVariable: ['--at-apply'],
|
|
}),
|
|
transformerVariantGroup(),
|
|
],
|
|
safelist: [
|
|
...'prose prose-sm m-auto text-left'.split(' '),
|
|
...safelistAllPrimaryBackgrounds(),
|
|
],
|
|
// hyoban/unocss-preset-shadcn: Use shadcn ui with UnoCSS
|
|
// https://github.com/hyoban/unocss-preset-shadcn
|
|
//
|
|
// Thanks to
|
|
// https://github.com/unovue/shadcn-vue/issues/34#issuecomment-2467318118
|
|
// https://github.com/hyoban-template/shadcn-vue-unocss-starter
|
|
//
|
|
// By default, `.ts` and `.js` files are NOT extracted.
|
|
// If you want to extract them, use the following configuration.
|
|
// It's necessary to add the following configuration if you use shadcn-vue or shadcn-svelte.
|
|
content: {
|
|
pipeline: {
|
|
include: [
|
|
// the default
|
|
/\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/,
|
|
// include js/ts files
|
|
'(components|src)/**/*.{js,ts,vue}',
|
|
'**/stage-ui/**/*.{vue,js,ts}',
|
|
'**/ui/**/*.{vue,js,ts}',
|
|
],
|
|
},
|
|
},
|
|
rules: [
|
|
[/^mask-\[(.*)\]$/, ([, suffix]) => ({ '-webkit-mask-image': suffix.replace(/_/g, ' ') })],
|
|
[/^bg-dotted-\[(.*)\]$/, ([, color], { theme }) => {
|
|
const parsedColor = parseColor(color, theme)
|
|
// Util usage: https://github.com/unocss/unocss/blob/f57ef6ae50006a92f444738e50f3601c0d1121f2/packages-presets/preset-mini/src/_utils/utilities.ts#L186
|
|
return {
|
|
'background-image': `radial-gradient(circle at 1px 1px, ${colorToString(parsedColor?.cssColor ?? parsedColor?.color ?? color, 'var(--un-background-opacity)')} 1px, transparent 0)`,
|
|
'--un-background-opacity': parsedColor?.cssColor?.alpha ?? parsedColor?.alpha ?? 1,
|
|
}
|
|
}],
|
|
],
|
|
})
|
|
}
|
|
|
|
export function histoireUnoConfig() {
|
|
return defineConfig({
|
|
presets: [
|
|
presetStoryMockHover(),
|
|
],
|
|
})
|
|
}
|
|
|
|
export default mergeConfigs([
|
|
sharedUnoConfig(),
|
|
histoireUnoConfig(),
|
|
])
|