Shortcuts
core:shortcuts 插件支援可重複使用的樣式組合。定義具名樣式捷徑,並以字串樣式項目的形式傳入 pika(),或在樣式定義中透過 __shortcut 屬性來使用它們。
運作原理
- 捷徑定義在
rawConfigConfigured期間從config.shortcuts.shortcuts收集。 - 在
configureEngine期間,每個定義會被解析並註冊:- 靜態規則儲存供精確比對查找。
- 動態規則儲存供基於 RegExp 的比對。
- 為已知捷徑新增自動補齊條目。
- 插件在兩個鉤子上運作:
transformStyleItems— 字串樣式項目會透過ShortcutResolver進行檢查。若符合,解析後的項目會取代原始字串。transformStyleDefinitions— 當樣式定義包含__shortcut屬性時,捷徑會被解析,產生的樣式定義會插入在目前定義其餘屬性的前面。
- 未匹配的捷徑字串保持不變(直接傳遞)。
設定
ts
interface ShortcutsConfig {
/** Array of shortcut definitions. @default [] */
shortcuts: Shortcut[]
}捷徑定義格式
共有 5 種定義捷徑的形式:1 種字串形式、2 種元組形式和 2 種物件形式。
字串形式
純字串僅作為自動補齊建議登錄——不會建立解析規則。
ts
// String form: autocomplete-only, no resolution rule
const shortcut = 'flex-center'元組形式——靜態
ts
type TupleFormStatic = [shortcut: string, value: Arrayable<ResolvedStyleItem>]值可以是 StyleDefinition 物件、參照另一個捷徑的 string,或兩者的陣列:
ts
// Tuple form — static: [name, value]
// value can be a StyleDefinition, a string (another shortcut), or an array of both
const shortcuts = [
// Single style definition
['flex-center', {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}],
// Multiple style items (array of StyleDefinitions)
['btn-base', [
{ padding: '0.5rem 1rem', borderRadius: '0.25rem', cursor: 'pointer' },
{ border: 'none', fontSize: '1rem' },
]],
// Reference another shortcut by name (string value)
['centered', 'flex-center'],
]元組形式——動態
ts
type TupleFormDynamic = [shortcut: RegExp, value: (matched: RegExpMatchArray) => Awaitable<Arrayable<ResolvedStyleItem>>, autocomplete?: Arrayable<string>]解析函式接收來自模式比對的 RegExpMatchArray,並回傳一個或多個 ResolvedStyleItem。可選的自動補齊提示為動態模式提供 IDE 建議:
ts
// Tuple form — dynamic: [pattern, resolver, autocomplete?]
// The resolver receives RegExpMatchArray and returns ResolvedStyleItem(s)
const shortcuts = [
// Dynamic margin shortcut
[
/^m-(\d+)$/,
(m: RegExpMatchArray) => ({ margin: `${Number(m[1]) * 0.25}rem` }),
['m-1', 'm-2', 'm-4', 'm-8'], // autocomplete hints
],
// Dynamic size shortcut returning a single definition
[
/^size-(\d+)$/,
(m: RegExpMatchArray) => ({
width: `${m[1]}px`,
height: `${m[1]}px`,
}),
['size-16', 'size-24', 'size-32'],
],
// Dynamic shortcut returning multiple style items
[
/^card-(\w+)$/,
(m: RegExpMatchArray) => [
{ padding: '1rem', borderRadius: '0.5rem' },
{ backgroundColor: m[1] },
],
],
]物件形式
等同於元組形式,但使用具名屬性。靜態和動態兩種變體均支援:
ts
// Object form — equivalent to tuple forms but with named properties
const shortcuts = [
// Object form — static
{
shortcut: 'flex-center',
value: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
},
// Object form — dynamic
{
shortcut: /^p-(\d+)$/,
value: (m: RegExpMatchArray) => ({
padding: `${Number(m[1]) * 0.25}rem`,
}),
autocomplete: ['p-1', 'p-2', 'p-4'],
},
]完整範例
ts
// pika.config.ts
import { defineEngineConfig } from '@pikacss/unplugin-pikacss'
export default defineEngineConfig({
shortcuts: {
shortcuts: [
// String form: autocomplete-only
'my-custom-shortcut',
// Tuple form — static
['flex-center', {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}],
// Tuple form — static with multiple style items
['btn', [
{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center' },
{ padding: '0.5rem 1rem', borderRadius: '0.25rem' },
{ border: 'none', cursor: 'pointer', fontSize: '1rem' },
]],
// Tuple form — dynamic
[
/^m-(\d+)$/,
m => ({ margin: `${Number(m[1]) * 0.25}rem` }),
['m-1', 'm-2', 'm-4', 'm-8'],
],
// Object form — static
{
shortcut: 'sr-only',
value: {
position: 'absolute',
width: '1px',
height: '1px',
padding: '0',
margin: '-1px',
overflow: 'hidden',
clip: 'rect(0, 0, 0, 0)',
whiteSpace: 'nowrap',
borderWidth: '0',
},
},
// Object form — dynamic
{
shortcut: /^size-(\d+)$/,
value: m => ({ width: `${m[1]}px`, height: `${m[1]}px` }),
autocomplete: ['size-16', 'size-24', 'size-32'],
},
],
},
})與 pika() 搭配使用
捷徑可以兩種方式使用:
作為字串引數
將捷徑名稱作為字串引數傳入 pika()。它們會與其他樣式項目一起被解析:
ts
// Use a shortcut as a string argument to pika()
// Shortcuts resolve to their underlying style items at build time
// Single shortcut
const centered = pika('flex-center')
// Shortcut mixed with inline style definitions
const card = pika(
'flex-center',
{ gap: '1rem', padding: '2rem' },
)
// Dynamic shortcut as string argument
const spaced = pika('m-4', { color: 'blue' })產生的 CSS 輸出:
css
/* pika('flex-center', { gap: '1rem', padding: '2rem' }) */
.a { display: flex; }
.b { align-items: center; }
.c { justify-content: center; }
.d { gap: 1rem; }
.e { padding: 2rem; }__shortcut 屬性
在樣式定義中使用 __shortcut 套用一個或多個捷徑。解析後的樣式會在定義中的其他屬性之前合併:
ts
// Use __shortcut property in a style definition
// Shortcut styles are inserted BEFORE other properties in the definition
// Single shortcut via __shortcut
const centered = pika({
__shortcut: 'flex-center',
gap: '1rem',
})
// Multiple shortcuts via __shortcut array
const button = pika({
__shortcut: ['flex-center', 'btn'],
backgroundColor: '#0ea5e9',
color: 'white',
})
// Dynamic shortcut via __shortcut
const spacing = pika({
__shortcut: 'm-4',
})產生的 CSS 輸出:
css
/* pika({ __shortcut: 'flex-center', gap: '1rem' }) */
.a { display: flex; }
.b { align-items: center; }
.c { justify-content: center; }
.d { gap: 1rem; }
/* pika({ __shortcut: 'm-4' }) */
.e { margin: 1rem; }屬性順序
使用 __shortcut 時,捷徑樣式會插入在定義其餘屬性的前面。這意味著與 __shortcut 一起定義的屬性可以覆寫捷徑的值。
defineShortcut() 輔助函式
使用 defineShortcut() 作為個別捷徑定義的型別安全恆等輔助函式。它提供完整的 TypeScript 自動補齊:
ts
import { defineEngineConfig, defineShortcut } from '@pikacss/unplugin-pikacss'
// defineShortcut() is a type-safe identity helper
// It provides full TypeScript autocomplete for shortcut definitions
const flexCenter = defineShortcut(['flex-center', {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}])
const dynamicMargin = defineShortcut({
shortcut: /^m-(\d+)$/,
value: m => ({ margin: `${Number(m[1]) * 0.25}rem` }),
autocomplete: ['m-1', 'm-2', 'm-4'],
})
export default defineEngineConfig({
shortcuts: {
shortcuts: [flexCenter, dynamicMargin],
},
})遞迴解析
捷徑可以透過名稱參照其他捷徑。解析是遞迴的——捷徑的值可以是指向另一個已登錄捷徑的字串:
ts
// Shortcuts can reference other shortcuts — resolution is recursive
const shortcuts = [
['flex-center', {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}],
// 'btn' resolves to 'flex-center' (another shortcut) + inline styles
['btn', [
'flex-center', // references the shortcut above
{ padding: '0.5rem 1rem', borderRadius: '0.25rem' },
]],
]當呼叫 pika('btn') 時,引擎會先解析 'flex-center',再將結果與其餘的行內樣式合併。
自動補齊
插件會登錄:
__shortcut作為樣式定義的額外屬性,接受string | string[]值。- 所有靜態捷徑名稱作為自動補齊建議。
- 動態解析結果會透過
onResolved自動回饋至自動補齊。
Engine API
插件可以用程式方式管理捷徑:
engine.shortcuts.resolver—ShortcutResolver實例engine.shortcuts.add(...list)— 在執行階段新增捷徑定義
行為說明
- 動態解析結果在首次解析後會被快取。
- 靜態和動態規則都儲存在繼承自
AbstractResolver的ShortcutResolver中。 - 無效的捷徑設定形式會被靜默略過。
- 捷徑可以參照其他捷徑——解析是遞迴的。
- 解析錯誤會被捕捉並記錄為警告;原始字串將被回傳。
原始碼參考
packages/core/src/internal/plugins/shortcuts.ts