# Alert Dialog ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/alert-dialog ``` ```ts import { AdminAlertDialog, AdminAlertDialogAction, AdminAlertDialogCancel, AdminAlertDialogContent, AdminAlertDialogDescription, AdminAlertDialogFooter, AdminAlertDialogHeader, AdminAlertDialogTitle, AdminAlertDialogTrigger, } from '@/components/admin/alert-dialog' ``` ## 用法 ```vue ``` ## 場景 ### 以 overlay [命令式](https://ui.nuxt.com/docs/composables/use-overlay){rel=""nofollow""}開啟 需要由 composable 驅動時,搭配 [`useOverlay()`](https://component-registry-4d4d86.gitlab.io/docs/admin/overlay)。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-alert-dialog ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------------- | --------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `open` | `boolean | undefined` | — | The controlled open state of the dialog. Can be binded as \`v-model\:open\`. | | `defaultOpen` | `boolean | undefined` | — | The open state of the dialog when it is initially rendered. Use when you do not need to control its open state. | | `unmountOnHide` | `boolean | undefined` | `true` | When set to \`false\`, the dialog content will not be unmounted when closed, but instead hidden with CSS. \
Useful for SEO or when you want to improve performance by not remounting the component on every open. | | `class` | `unknown` | — | — | #### Events | 名稱 | Payload | 說明 | | ------------- | --------- | -- | | `update:open` | `boolean` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | --------------------------------------- | -- | | `default` | `{ open: boolean; close: () => void; }` | — | :: ### admin-alert-dialog-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------------------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `disableOutsidePointerEvents` | `boolean | undefined` | — | When \`true\`, hover/focus/click interactions will be disabled on elements outside\
the \`DismissableLayer\`. Users will need to click twice on outside elements to\
interact with them: once to close the \`DismissableLayer\`, and again to trigger the element. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `showCloseButton` | `boolean | undefined` | `true` | 設為 \`false\` 時隱藏右上角關閉 X 按鈕 | #### Events | 名稱 | Payload | 說明 | | -------------------- | --------------------------------------------- | -- | | `escapeKeyDown` | `KeyboardEvent` | — | | `pointerDownOutside` | `PointerDownOutsideEvent` | — | | `focusOutside` | `FocusOutsideEvent` | — | | `interactOutside` | `PointerDownOutsideEvent | FocusOutsideEvent` | — | | `openAutoFocus` | `Event` | — | | `closeAutoFocus` | `Event` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-alert-dialog-action ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-alert-dialog-cancel ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `unknown` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-alert-dialog-description ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-alert-dialog-footer ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-alert-dialog-header ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-alert-dialog-title ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-alert-dialog-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `unknown` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminAlertDialog"} # Audio Player ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/audio-player ``` ```ts import { AdminAudioPlayer, AdminAudioPlayerControls, AdminAudioPlayerProgress, AdminAudioPlayerSettings, AdminAudioPlayerTime, AdminAudioPlayerToolbar, AdminAudioPlayerVolume } from '@/components/admin/audio-player' ``` vidstack 是一組 web components(`` / `` / …),需要告訴 Vue 編譯器把它們當成 native custom element,否則 dev console 會出現 `[Vue warn]: Failed to resolve component: media-*` 警告。 **Nuxt 3 / 4** ```ts [nuxt.config.ts] export default defineNuxtConfig({ vue: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('media-') } } }) ``` **Vue 3 + Vite** ```ts [vite.config.ts] import vue from '@vitejs/plugin-vue' import { defineConfig } from 'vite' export default defineConfig({ plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('media-') } } }) ] }) ``` ## 用法 傳入 `src` 即可播放音檔,預設組裝包含進度條、時間顯示、播放控制(播放、快退 10 秒、快進 10 秒)、設定(播放速度)與音量。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-audio-player ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------------------------ | | `src`\* | `MediaSrc` | — | 音訊來源(vidstack \`MediaSrc\` 格式) | | `class` | `ClassValue` | — | 根元素之自訂 class | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ------------ | -------- | ----------------------- | | `ended` | — | 播放結束時觸發 | | `error` | `Error` | 載入或播放發生錯誤時觸發 | | `pause` | — | 暫停播放時觸發 | | `play` | — | 開始播放時觸發 | | `timeUpdate` | `number` | 播放進度更新時觸發,payload 為當前秒數 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-audio-player-controls ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-audio-player-progress ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-audio-player-settings ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-audio-player-time ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-audio-player-toolbar ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-audio-player-volume ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ## 注意事項 - **必須加 `isCustomElement` 設定**:未加上 `vue.compilerOptions.isCustomElement` 規則時,dev console 會對每個 `` 元素噴 `Failed to resolve component` 警告。詳細寫法見上方「安裝」章節。 - **不支援 SSR**:vidstack 為 browser-only;元件殼不含 ``(engine 仍以 `defineAsyncComponent` 拆 chunk)。Nuxt 請自行以 `` 包覆;純 CSR 不需處理。見 [安裝 · SSR](https://component-registry-4d4d86.gitlab.io/docs/get-started/installation#ssr-nuxt)。 - **音量設定跨實例共享**:所有 `` 與 `` 實例共用同一組 `localStorage` key(`admin:player:volume` / `admin:player:muted`);多個分頁同時開啟時不會即時同步,避免使用者剛調整的音量被其他分頁覆蓋掉。 - **播放速度不記憶**:每次元件 mount 都重設為 `1`;如需專案級記憶請消費端自行包裝。 ## 更新紀錄 :admin-changelog{component="AdminAudioPlayer"} # Avatar ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/avatar ``` ```ts import { AdminAvatar, AdminAvatarFallback, AdminAvatarImage, } from '@/components/admin/avatar' ``` ## 用法 ```vue ``` ## 場景 ### Fallback 圖示 / 縮寫 載入失敗時回退到 `admin-avatar-fallback`。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-avatar ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-avatar-image ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------------- | -------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `src`\* | `string` | — | — | | `referrerPolicy` | `HTMLAttributeReferrerPolicy | undefined` | — | — | | `crossOrigin` | `"" | "anonymous" | "use-credentials" | undefined` | — | — | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | *\\\* 代表必填* #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-avatar-fallback ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `delayMs` | `number | undefined` | — | Useful for delaying rendering so it only appears for those with slower connections. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminAvatar"} # Badge ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/badge ``` ```ts import { AdminBadge } from '@/components/admin/badge' ``` ## 用法 ```vue ``` ## 場景 ### 尺寸 尺寸:`small`(圓點)、`medium`(預設)、`large`(可塞多字)。 ```vue ``` ### 附掛在圖示上 以絕對定位疊在 icon 右上角,做未讀數 / 新訊息提示。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-badge ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `variant` | `"default" | undefined` | — | 視覺樣式變體 | | `size` | `"small" | "medium" | "large" | undefined` | — | Badge 尺寸 | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminBadge"} # Breadcrumb ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/breadcrumb ``` ```ts import { AdminBreadcrumb, AdminBreadcrumbItem, AdminBreadcrumbLink, AdminBreadcrumbList, AdminBreadcrumbPage, AdminBreadcrumbSeparator, } from '@/components/admin/breadcrumb' ``` ## 用法 ```vue ``` ## 場景 ### 多層階層 以 `admin-breadcrumb-link` 連接每一層,最後一層用 `admin-breadcrumb-page` 標記當前頁。 ```vue ``` ### Theme 變體 `theme` prop 切換 `primary` / `secondary`,當前頁文字會套用對應色系。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-breadcrumb ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------------------------------- | --- | ------------------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | | `theme` | `"primary" | "secondary" | undefined` | — | 主題色(透過 context 傳遞給所有子元件) | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-breadcrumb-list ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-breadcrumb-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-breadcrumb-link ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"a"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-breadcrumb-page ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-breadcrumb-separator ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminBreadcrumb"} # Button ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/button ``` ```ts import { AdminButton } from '@/components/admin/button' ``` ## 用法 ```vue ``` ## 場景 ### 尺寸 尺寸:`medium`(預設)、`small`。 ```vue ``` ### 樣式 `variant`:`filled`/`outline`/`ghost`;`disabled` 為停用。 ```vue ``` ### 顏色 `color`:`primary`(預設)、`secondary`;可與任一 variant 組合。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-button ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ---------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `variant` | `"filled" | "outline" | "ghost" | undefined` | — | 視覺樣式變體 | | `size` | `"small" | "medium" | undefined` | — | 按鈕尺寸 | | `color` | `"primary" | "secondary" | "text" | undefined` | — | 主色系(影響背景與邊框顏色);\`text\` 為 ghost variant 專屬色階,其他 variant 下無對應樣式 | | `class` | `ClassValue` | — | 根元素之自訂 class | | `disabled` | `boolean | undefined` | — | 設為 \`true\` 時禁用按鈕並套用視覺停用樣式 | | `type` | `"reset" | "submit" | "button" | undefined` | — | 原生 \`type\` 屬性;未指定時瀏覽器預設為 \`submit\`,表單內之工具按鈕請設為 \`button\` | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 注意事項 - **`color="text"` 為 ghost 專屬**:`text` 色階僅在 `variant="ghost"` 下有對應樣式(toolbar / dropdown trigger 等次要 icon-only action 場景);搭配 `filled`/`outline` 時無效果,渲染同該 variant 預設色。 - **表單內請設 `type="button"`**:原生 `type` 未指定時瀏覽器預設為 `submit`,放在 `
` 內的工具按鈕會觸發表單送出。 ## 更新紀錄 :admin-changelog{component="AdminButton"} # Checkbox ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/checkbox ``` ```ts import { AdminCheckbox, AdminCheckboxGroup, AdminCheckboxInput, AdminCheckboxLabel, } from '@/components/admin/checkbox' ``` ## 用法 ```vue ``` ## 場景 ### 多選群組 以 `admin-checkbox-group` 包住多個 `admin-checkbox`(各 input 帶 `value`),`v-model` 以陣列承接被選中的 value,勾選同步由底層 `CheckboxGroupRoot` 處理。 ```vue ``` ### Indeterminate(不定態) 父層 checkbox 依子項目狀態在 `true` / `false` / `'indeterminate'` 三態間切換。 ```vue ``` ### 錯誤狀態 ```vue ``` ## Type-safe 封裝 `AdminCheckboxGroup` 已是 generic(`T extends AcceptableValue`),以較嚴的 ref 綁定 `v-model` 即可收斂為選項 value 的 literal union 陣列。若要讓 value 與清單對齊,可自行封裝:傳入 `options`(建議加 `as const`),由封裝元件以 `options` 為單一事實來源渲染各選項。 如此 `options` 即聯集來源,各選項的 `value` 結構上不可能越界;型別安全落在 `v-model` 與 `defaultValue` 必須對齊 `options` 的 value union(元素型別)。 > 此食譜刻意精簡;需要時可自行 fork 擴充。封裝元件僅為文件示範,不屬 registry 安裝產物。 ```vue ``` ::alert{title="需開啟 strictVModel" type="info"} 型別檢查需開啟 `strictVModel`(若已開啟 `strictTemplates` 則已包含)。設定見 [Type-safe](https://component-registry-4d4d86.gitlab.io/docs/get-started/type-safe)。下列同時含合法綁定與刻意錯誤綁定;錯誤處以 `@vue-expect-error` 標示。 :: ```vue ``` ## API 參考 ### 組成 ```vue ``` 單顆 checkbox 不需群組時,直接以 `v-model` 綁定 input: ```vue ``` ### admin-checkbox ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | -------------------- | --- | ------------------------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | | `id` | `string | undefined` | — | 為內部 input 提供自訂 \`id\`;未指定時自動產生 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-checkbox-group ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | | `defaultValue` | `TValue[] | undefined` | — | The value of the checkbox when it is initially rendered. Use when you do not need to control its value. | | `modelValue` | `TValue[] | undefined` | — | The controlled value of the checkbox. Can be binded with v-model. | | `rovingFocus` | `boolean | undefined` | — | When \`false\`, navigating through the items using arrow keys will be disabled. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the checkboxes | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `dir` | `Direction$5 | undefined` | — | The direction of navigation between items. | | `orientation` | `Orientation$1 | undefined` | — | The orientation of the group.\
Mainly so arrow navigation is done accordingly (left & right vs. up & down) | | `loop` | `boolean | undefined` | `false` | Whether keyboard navigation should loop around | | `name` | `string | undefined` | — | The name of the field. Submitted with its owning form as part of a name/value pair. | | `required` | `boolean | undefined` | — | When \`true\`, indicates that the user must set the value before the owning form can be submitted. | #### Events | 名稱 | Payload | 說明 | | ------------------- | ---------- | -- | | `update:modelValue` | `TValue[]` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-checkbox-input ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------- | ---------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `defaultValue` | `boolean | "indeterminate" | undefined` | — | The value of the checkbox when it is initially rendered. Use when you do not need to control its value. | | `modelValue` | `boolean | "indeterminate" | null | undefined` | — | The controlled value of the checkbox. Can be binded with v-model. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the checkbox | | `value` | `AcceptableValue | undefined` | `"on"` | The value given as data when submitted with a \`name\`. | | `id` | `string | undefined` | — | Id of the element | | `trueValue` | `boolean | undefined` | — | The value used when the checkbox is checked. Defaults to \`true\`. | | `falseValue` | `boolean | undefined` | — | The value used when the checkbox is unchecked. Defaults to \`false\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `name` | `string | undefined` | — | The name of the field. Submitted with its owning form as part of a name/value pair. | | `required` | `boolean | undefined` | — | When \`true\`, indicates that the user must set the value before the owning form can be submitted. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `isError` | `boolean | undefined` | — | 設為 \`true\` 時套用 \`aria-invalid\` 與錯誤態樣式 | #### Events | 名稱 | Payload | 說明 | | ------------------- | --------------------------- | -- | | `update:modelValue` | `boolean | "indeterminate"` | — | #### Slots | 名稱 | Bindings | 說明 | | ------ | ------------------------------------------------------------------------------ | --------------------------------------------------------------------- | | `icon` | `{ modelValue: boolean | "indeterminate"; state: boolean | "indeterminate"; }` | 自訂指示圖示;接收 CheckboxRoot 之 slot scope props(\`modelValue\` 與 \`state\`) | :: ### admin-checkbox-label ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminCheckbox"} # Color Picker ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/color-picker ``` ```ts import type { ColorPickerSwatch } from '@/components/admin/color-picker' import { AdminColorPicker, AdminColorPickerContent, AdminColorPickerTrigger, } from '@/components/admin/color-picker' ``` ## 用法 ```vue ``` ## 場景 ### 停用狀態 ```vue ``` ### 自訂 trigger 當預設 trigger 樣式不符需求,透過 `AdminColorPickerTrigger` 的 default slot 自行渲染觸發器;slot 內第一個元素會直接成為觸發 DOM。 ```vue ``` ## API 參考 `swatches` 中每個 `value` 須唯一,且 `v-model` 綁定值須為其中某個 `value`;若綁定值不在清單內,trigger 會顯示為未選狀態。 以 `as const satisfies readonly ColorPickerSwatch[]` 宣告 `swatches`,`modelValue` 會收斂成各 `value` 的 literal union,綁定清單外的字串即觸發 TypeScript 型別錯誤;未加 `as const` 時 `modelValue` 退回 `string`,維持向後相容。 ### 組成 ```vue ``` 需要自訂 trigger 時放入 slot 內容: ```vue ``` ### admin-color-picker ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | -------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `class` | `unknown` | — | — | | `modelValue` | `TValue | undefined` | — | 受控值,以 \`v-model\` 綁定;須為 \`swatches\` 中某個 \`value\`,否則 trigger 視為未選 | | `swatches`\* | `readonly ColorPickerSwatch[]` | — | 可選顏色清單(必填);每個 \`value\` 須唯一。以 \`as const satisfies readonly ColorPickerSwatch\[]\` 宣告時,\`modelValue\` 會收斂成各 \`value\` 的 literal union | | `disabled` | `boolean | undefined` | `false` | 設為 \`true\` 時禁用 picker | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ------------------- | -------------------- | ------------------------------------------ | | `update:modelValue` | `TValue | undefined` | modelValue 更新時觸發;未選 / 取消選擇時為 \`undefined\` | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-color-picker-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | ---------------------------------------- | ---------- | ----------------------- | | `align` | `"start" | "end" | "center" | undefined` | `"center"` | 對齊 trigger 之位置 | | `sideOffset` | `number | undefined` | `4` | content 與 trigger 之間的距離 | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-color-picker-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | | `default` | `{ value: string | undefined; swatch: ColorPickerSwatch | undefined; open: boolean; disabled: boolean; }` | 預設 slot;若提供則以自訂內容取代預設 trigger,並傳遞當前值、選中之 swatch、open 與 disabled 狀態 | :: ## 更新紀錄 :admin-changelog{component="AdminColorPicker"} # Cropper ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/cropper ``` ```ts import type { CropResult } from '@/components/admin/cropper' import { AdminCropper, AdminCropperPreview, AdminCropperZoom, useAdminCropperContext } from '@/components/admin/cropper' ``` cropperjs v2 是一組 web components(`` / `` / `` …),需要告訴 Vue 編譯器把它們當成 native custom element,否則 dev console 會出現 `[Vue warn]: Failed to resolve component: cropper-*` 警告。視專案類型把下列設定加進去: **Nuxt 3 / 4** ```ts [nuxt.config.ts] export default defineNuxtConfig({ vue: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('cropper-') } } }) ``` **Vue 3 + Vite** ```ts [vite.config.ts] import vue from '@vitejs/plugin-vue' import { defineConfig } from 'vite' export default defineConfig({ plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('cropper-') } } }) ] }) ``` ## 用法 ```vue ``` ## 場景 ### 互動 playground ```vue ``` ### 自訂 zoom 控制 ```vue ``` ### 多步驟裁切流程 搭配 `admin-dialog` 與 `admin-stepper` 完成「電腦版裁切 → 手機版裁切 → 預覽結果」三步驟流程;每一步用一個 `` instance 鎖定不同 aspect ratio,最後一步直接以 `result.toDataURL()` 顯示成品。 ```vue ``` ### 裁切 GIF 動畫 呼叫 `result.toBlob('image/gif')` 或 `result.toDataURL('image/gif')` 會走 GIF pipeline,重新解碼所有 frame、依 selection 對每幀做像素裁切、再以 `gifenc` 重新編碼成動畫 GIF。原檔的 frame delay 與動畫長度會被保留。透過 `gif-max-colors` 與 `gif-frame-stride` 兩個 prop 可在畫質與檔案大小之間取捨。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-cropper ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------------------- | ------------------------------------------ | -------- | ------------------------------------------- | | `src`\* | `string` | — | 待裁切之來源圖檔 URL 或 dataURL(必填) | | `aspectRatio` | `number | undefined` | — | 裁切框長寬比;不指定則自由比例 | | `minZoom` | `number | undefined` | `0.1` | 縮放下限 | | `maxZoom` | `number | undefined` | `3` | 縮放上限 | | `initialZoom` | `number | undefined` | `1` | 載入後初始縮放倍率 | | `zoomable` | `boolean | undefined` | `true` | 設為 \`false\` 時隱藏縮放控制 | | `gifMaxColors` | `number | undefined` | `256` | GIF 來源編碼時最大色票數 | | `gifFrameStride` | `number | undefined` | `1` | GIF 來源編碼時跳幀間隔 | | `selectionWithin` | `AdminCropperSelectionWithin | undefined` | `"none"` | 限制裁切框可移動範圍 | | `selectionRedrawable` | `boolean | undefined` | `true` | 設為 \`false\` 時禁用重新繪製選取框互動 | | `minSelectionSize` | `AdminCropperMinSelectionSize | undefined` | — | 限制裁切框最小尺寸(避免過小);觸發時 emit \`sourceTooSmall\` | | `class` | `ClassValue` | — | 根元素之自訂 class | | `result` | `CropResult | undefined` | — | — | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ---------------- | ----------------------------------- | ---------------------------------- | | `update:result` | `CropResult | undefined` | — | | `sourceTooSmall` | `AdminCropperSourceTooSmallPayload` | 來源圖過小無法滿足 \`minSelectionSize\` 時觸發 | #### Slots | 名稱 | Bindings | 說明 | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | | `default` | `{ selectionId: string; zoom: number; zoomTo: (v: number) => void; zoomBy: (d: number) => void; minZoom: number; maxZoom: number; zoomable: boolean; }` | 預設 slot,提供 selection id、縮放控制與當前狀態 | #### Expose | 名稱 | 簽名 | 說明 | | ---------------- | -------------------------------- | ------------------------------------------- | | `reset` | `() => void` | 重置 selection 到圖片中央、zoom 回到 \`initial-zoom\` | | `zoomTo` | `(value: number) => void` | 縮放到絕對值(會被 clamp 到 min/max) | | `zoomBy` | `(delta: number) => void` | 從目前 zoom 加上 delta | | `setAspectRatio` | `(ratio: number | null) => void` | 命令式變更比例;\`null\` 表示自由比例 | :: ### admin-cropper-zoom ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | -------------------- | ------ | -- | | `zoom`\* | `number` | — | — | | `minZoom` | `number | undefined` | `0.1` | — | | `maxZoom` | `number | undefined` | `3` | — | | `step` | `number | undefined` | `0.05` | — | | `class` | `ClassValue` | — | — | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | -------- | -------- | ----------------- | | `zoomTo` | `number` | 透過 slider 設定絕對縮放值 | | `zoomBy` | `number` | 透過按鈕加減縮放 | :: ### admin-cropper-preview ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------- | -------------------- | --- | ---------------------------------------------------------- | | `selection` | `string | undefined` | — | 若省略且位於 \`\\` 內,則使用 context 的 \`selectionId\` | | `class` | `ClassValue` | — | — | :: ## 注意事項 ### Selection 行為 - **`selection-within`**:只限制**畫布內的拖動範圍**(軸對齊邊界;旋轉時取可視外包矩形),不影響 `result.region` 仍以原圖像素表達。預設 `'none'` 允許拖到圖外(適合 GIF 透明邊);要嚴格框在圖內設 `'image'`。 - **`selection-redrawable`**:`true`(預設)可在選框外暗區拖曳重畫;`false` 鎖定為只能調整現有框,避免表單誤觸。 - **`min-selection-size` 與 `aspect-ratio`**:兩者比例不一致時 dev console 會 warn(不 throw),實際能拖到的最小尺寸會被兩個限制夾住、可能比 `min` 還大。建議讓 `min` 寬高直接等於目標輸出尺寸。 ### 輸出行為 - **`toCanvas` / `toDataURL` / `toBlob` 皆為 async**,都回傳 Promise。 - **預設不降採樣**:非 GIF 路徑輸出原圖像素座標下的裁切區域,不會因畫面上 selection 較小而縮圖;要刻意縮放請傳 `{ width, height }`。 - **`toCanvas()` 對 GIF 來源只輸出當前一幀**:要保留動畫請改用 `toBlob({ mime: 'image/gif' })` 或 `toDataURL({ mime: 'image/gif' })`。 - **GIF pipeline 跑在 main thread**:解碼/量化/編碼皆同步。建議來源 < 2MB / < 50 frames,超過會凍結 UI 100ms 以上,可用 `gif-frame-stride` 跳幀緩解。 - **部分 GIF 走 lossy 重量化**:僅當來源每一幀皆為 disposal type 2(還原到背景)時才走保留原始色盤的無損裁切路徑;多數含 disposal 0/1 幀的一般 GIF 會改走 composite 後以 `gif-max-colors` 重新量化的路徑,可能出現輕微色帶。此為畫質取捨,非錯誤。 ### SSR 與 Vue 設定 - **不支援 SSR**:cropperjs v2 web components 只能在瀏覽器 register;元件殼不含 ``。Nuxt 請自行以 `` 包覆,其他 SSR 框架用等價機制;純 CSR 不需處理。見 [安裝 · SSR](https://component-registry-4d4d86.gitlab.io/docs/get-started/installation#ssr-nuxt)。 - **必須設定 `isCustomElement`**:否則 dev console 會印 `[Vue warn]: Failed to resolve component: cropper-*`。寫法見上方「安裝」章節。 #### CORS - **一般輸出**:跨域圖片需回 `Access-Control-Allow-Origin`,否則 `toCanvas` / `toDataURL` / `toBlob` 會 throw `SecurityError`。元件已加 `crossorigin="anonymous"`,picsum 等 CDN 可正常運作。 - **GIF 輸出另需 fetch CORS**:GIF pipeline 會額外 `fetch(src)` 重新取 bytes,server 同樣要回 `Access-Control-Allow-Origin`;`` 顯示成功不代表 fetch 拿得到。 ## 更新紀錄 :admin-changelog{component="AdminCropper"} # Date Picker ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/date-picker ``` ```ts import { AdminDatePicker, AdminDatePickerRange, } from '@/components/admin/date-picker' ``` ## 用法 `AdminDatePicker` 提供單選日期,`AdminDatePickerRange` 提供區間選擇。兩者共用 ark-ui DatePicker 原生組件,採共享外框 layout 與 date-fns 格式化。 ```vue ``` ## 場景 每個元件之 playground 提供完整 props 切換 UI 與即時 `modelValue` JSON 顯示。 ### 單選 ```vue ``` ### 區間 兩個 input 於單一外框內並列,共享一個 trigger 與 clear 按鈕;`modelValue` 為 `Date[]`,length 0/1/2 partial 中間態合法(第一次 click cell 之後對外可見)。啟用 `withTime` 後 calendar 下方渲染垂直堆疊之兩組時間 stepper(上 = `modelValue[0]`、下 = `modelValue[1]`),需 modelValue length === 2 才啟用 stepper。 ```vue ``` ### 錯誤狀態 ```vue ``` ```vue ``` ## API 參考 ### 組成 ```vue ``` ::alert{title="透傳上游 API" type="info"} `AdminDatePicker` / `AdminDatePickerRange` 直接以 `@ark-ui/vue` 之 [DatePicker.Input](https://ark-ui.com/vue/docs/components/date-picker){rel=""nofollow""} / `DatePicker.Trigger` / `DatePicker.ClearTrigger` 為 input 元素;下列僅列出 admin 對外承諾之 prop / event / expose。 :: ### admin-date-picker ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------------- | ----------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | `class` | `unknown` | — | — | | `placeholder` | `string | undefined` | `""` | 顯示於輸入框未填值時的提示文字 | | `disabled` | `boolean | undefined` | `false` | 設為 \`true\` 時停用整個欄位,calendar trigger 無法開啟 | | `readonly` | `boolean | undefined` | `false` | 設為 \`true\` 時禁止編輯文字但仍可開啟 calendar 檢視 | | `format`\* | `string` | — | 設定顯示與輸入解析之 date-fns 格式(如 \`yyyy/MM/dd\` 或 \`yyyy/MM/dd HH\:mm\`) | | `emitAs` | `TEmitAs | undefined` | `(() => "string") as () => TEmitAs` | 控制 \`update\:modelValue\` payload 之出口型別;\`'date'\` 回傳 \`Date\`、\`'string'\` 依 \`format\` 回傳字串、\`'timestamp'\` 回傳 epoch milliseconds | | `withTime` | `boolean | undefined` | `false` | 設為 \`true\` 時於 calendar 下方啟用時間選擇 stepper | | `enableSeconds` | `boolean | undefined` | `false` | 設為 \`true\` 時於時間 stepper 加入秒欄 | | `minDate` | `Date | null | undefined` | — | 限定可選日期下限 | | `maxDate` | `Date | null | undefined` | — | 限定可選日期上限 | | `minTime` | `TimeModel | undefined` | — | 限定可選時間下限 | | `maxTime` | `TimeModel | undefined` | — | 限定可選時間上限 | | `isError` | `boolean | undefined` | `false` | 設為 \`true\` 時切換錯誤狀態樣式並設定 aria-invalid | | `modelValue` | `DatePickerModelValue` | — | 透過 \`v-model\` 綁定當前選擇值 | | `messages` | `Partial | undefined` | — | 覆寫元件內 a11y 字串;未提供之 key fallback 至預設字典 | | `locale` | `string | undefined` | `"zh-TW"` | BCP-47 locale tag(如 \`'zh-TW'\`、\`'en-US'\`、\`'ja-JP'\`) | | `id` | `string | undefined` | — | 綁定至內部輸入元素之 \`id\`;純透傳,未提供時不自動生成 | | `name` | `string | undefined` | — | 透傳至 ark \`DatePicker\` root 之 \`name\`,產生隱藏提交欄位供原生表單提交使用 | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ------------------- | ------------------------------------------- | ------------------------------------------------------------------- | | `blur` | `FocusEvent` | 輸入框失焦且使用者真正離開元件時觸發(內部 focus 移動不觸發) | | `invalid` | `{ reason: AdminDatePickerInvalidReason; }` | 解析失敗或超出 \`minDate\` / \`maxDate\` / \`minTime\` / \`maxTime\` 範圍時觸發 | | `update:modelValue` | `DatePickerPayload` | 選擇值變更時觸發,payload 型別依 \`emitAs\` 而定 | #### Expose | 名稱 | 簽名 | 說明 | | ------- | ---------------------------------------------------------------------------- | ----------------------------------------------- | | `open` | `() => datePickerApi.value.setOpen(true)` | 開啟 calendar popover | | `close` | `() => datePickerApi.value.setOpen(false)` | 關閉 calendar popover | | `focus` | `() => { rootRef.value?.querySelector('input')?.focus() }` | 將焦點移至內部輸入框 | | `blur` | `() => { rootRef.value?.querySelector('input')?.blur() }` | 將焦點移出內部輸入框 | | `clear` | `() => datePickerApi.value.clearValue()` | 清除目前選擇值並 emit \`update\:modelValue\` 為 \`null\` | :: ### admin-date-picker-range ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------------- | -------------------------------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `class` | `unknown` | — | — | | `placeholder` | `string | undefined` | `""` | 輸入框未填值之提示文字 | | `separator` | `string | undefined` | `" - "` | 顯示時兩端之分隔字元(預設 \`' - '\`) | | `disabled` | `boolean | undefined` | `false` | 設為 \`true\` 時停用輸入框與 calendar trigger | | `readonly` | `boolean | undefined` | `false` | 設為 \`true\` 時禁止操作(可開啟 calendar 但無法選取) | | `format`\* | `string` | — | 設定顯示之 date-fns 格式(如 \`yyyy/MM/dd\` 或 \`yyyy/MM/dd HH\:mm\`) | | `emitAs` | `TEmitAs | undefined` | `(() => "string") as () => TEmitAs` | 控制 \`update\:modelValue\` 各端 payload 之出口型別;\`'date'\` 回傳 \`Date\`、\`'string'\` 依 \`format\` 回傳字串、\`'timestamp'\` 回傳 epoch milliseconds | | `withTime` | `boolean | undefined` | `false` | 設為 \`true\` 時於 calendar 下方啟用兩組垂直堆疊之時間 stepper(位置即語意:上 = start、下 = end) | | `enableSeconds` | `boolean | undefined` | `false` | 設為 \`true\` 時於時間 stepper 加入秒欄 | | `minDate` | `Date | null | undefined` | — | 限定可選日期下限 | | `maxDate` | `Date | null | undefined` | — | 限定可選日期上限 | | `minTime` | `TimeModel | undefined` | — | 限定可選時間下限 | | `maxTime` | `TimeModel | undefined` | — | 限定可選時間上限 | | `isError` | `boolean | undefined` | `false` | 設為 \`true\` 時切換錯誤狀態樣式並設定 aria-invalid | | `modelValue` | `DatePickerRangeModelValueInput | undefined` | — | 透過 \`v-model\` 綁定當前選擇值;對外形狀為 \`Date\[]\`(length 由 ark 決定,0/1/2 partial 中間態合法) | | `messages` | `Partial | undefined` | — | 覆寫元件內 a11y 字串;未提供之 key fallback 至預設字典 | | `locale` | `string | undefined` | `"zh-TW"` | BCP-47 locale tag(如 \`'zh-TW'\`、\`'en-US'\`、\`'ja-JP'\`) | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------ | | `invalid` | `{ reason: TimeInvalidReason; index: 0 | 1; }` | 解析失敗或超出時間範圍時觸發 | | `update:modelValue` | `DatePickerRangePayload` | 選擇值變更時觸發,payload 為 \`Date\[]\` / \`string\[]\` / \`number\[]\`(依 \`emitAs\` narrow,length 0/1/2) | #### Expose | 名稱 | 簽名 | 說明 | | ------- | ---------------------------------------------------------------------------- | ------------------- | | `open` | `() => datePickerApi.value.setOpen(true)` | 開啟 calendar popover | | `close` | `() => datePickerApi.value.setOpen(false)` | 關閉 calendar popover | | `focus` | `() => { rootRef.value?.querySelector('input')?.focus() }` | 將焦點移至輸入框 | | `blur` | `() => { rootRef.value?.querySelector('input')?.blur() }` | 將焦點移出輸入框 | | `clear` | `() => datePickerApi.value.clearValue()` | 清除 modelValue | :: ## 更新紀錄 :admin-changelog{component="AdminDatePicker"} # Dialog ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/dialog ``` ```ts import { AdminDialog, AdminDialogClose, AdminDialogContent, AdminDialogDescription, AdminDialogFooter, AdminDialogHeader, AdminDialogTitle, AdminDialogTrigger, } from '@/components/admin/dialog' ``` ## 用法 以 `v-model:open` 控制顯示狀態;header 與 footer 之間放主要內容,trigger 模式由 `admin-dialog-trigger` 啟動。 ```vue ``` ## 場景 ### 帶表單的對話框 搭配 vee-validate 的 `` 與 `useForm` 做欄位驗證,並以 admin-field 版型(`admin-field` / `admin-field-label` / `admin-field-content` / `admin-field-error`)排版;`` 包住欄位與 footer,透過 `handleSubmit` 攔截提交並在驗證通過後手動關閉 `open`。 ```vue ``` ### 可滾動內容 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-dialog ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------------- | --------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `open` | `boolean | undefined` | — | The controlled open state of the dialog. Can be binded as \`v-model\:open\`. | | `defaultOpen` | `boolean | undefined` | — | The open state of the dialog when it is initially rendered. Use when you do not need to control its open state. | | `modal` | `boolean | undefined` | — | The modality of the dialog When set to \`true\`, \
interaction with outside elements will be disabled and only dialog content will be visible to screen readers. | | `unmountOnHide` | `boolean | undefined` | `true` | When set to \`false\`, the dialog content will not be unmounted when closed, but instead hidden with CSS. \
Useful for SEO or when you want to improve performance by not remounting the component on every open. | | `class` | `unknown` | — | — | #### Events | 名稱 | Payload | 說明 | | ------------- | --------- | -- | | `update:open` | `boolean` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | --------------------------------------- | -- | | `default` | `{ open: boolean; close: () => void; }` | — | :: ### admin-dialog-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------------------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `disableOutsidePointerEvents` | `boolean | undefined` | — | When \`true\`, hover/focus/click interactions will be disabled on elements outside\
the \`DismissableLayer\`. Users will need to click twice on outside elements to\
interact with them: once to close the \`DismissableLayer\`, and again to trigger the element. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `showCloseButton` | `boolean | undefined` | `true` | 設為 \`false\` 時隱藏右上角關閉 X 按鈕;admin 預設內嵌 \`\\` 與 \`IconX\` | #### Events | 名稱 | Payload | 說明 | | -------------------- | --------------------------------------------- | -- | | `escapeKeyDown` | `KeyboardEvent` | — | | `pointerDownOutside` | `PointerDownOutsideEvent` | — | | `focusOutside` | `FocusOutsideEvent` | — | | `interactOutside` | `PointerDownOutsideEvent | FocusOutsideEvent` | — | | `openAutoFocus` | `Event` | — | | `closeAutoFocus` | `Event` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dialog-scroll-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------------------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `disableOutsidePointerEvents` | `boolean | undefined` | — | When \`true\`, hover/focus/click interactions will be disabled on elements outside\
the \`DismissableLayer\`. Users will need to click twice on outside elements to\
interact with them: once to close the \`DismissableLayer\`, and again to trigger the element. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `showCloseButton` | `boolean | undefined` | `true` | 設為 \`false\` 時隱藏右上角關閉 X 按鈕;admin 預設內嵌 \`\\` 與 \`IconX\` | #### Events | 名稱 | Payload | 說明 | | -------------------- | --------------------------------------------- | -- | | `escapeKeyDown` | `KeyboardEvent` | — | | `pointerDownOutside` | `PointerDownOutsideEvent` | — | | `focusOutside` | `FocusOutsideEvent` | — | | `interactOutside` | `PointerDownOutsideEvent | FocusOutsideEvent` | — | | `openAutoFocus` | `Event` | — | | `closeAutoFocus` | `Event` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dialog-close ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `unknown` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dialog-description ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dialog-footer ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dialog-header ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dialog-overlay ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dialog-title ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dialog-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `unknown` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminDialog"} # Divider ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/divider ``` ```ts import { AdminDivider } from '@/components/admin/divider' ``` ## 用法 ```vue ``` ## 場景 ### 垂直分隔線 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-divider ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | ------------------------------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `orientation` | `DataOrientation | undefined` | `"horizontal"` | Orientation of the component.\
Either \`vertical\` or \`horizontal\`. Defaults to \`horizontal\`. | | `decorative` | `boolean | undefined` | `true` | Whether or not the component is purely decorative. \
When \`true\`, accessibility-related attributes\
are updated so that that the rendered element is removed from the accessibility tree. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ## 更新紀錄 :admin-changelog{component="AdminDivider"} # Dropdown Menu ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/dropdown-menu ``` ```ts import { AdminDropdownMenu, AdminDropdownMenuCheckboxItem, AdminDropdownMenuContent, AdminDropdownMenuGroup, AdminDropdownMenuItem, AdminDropdownMenuLabel, AdminDropdownMenuRadioGroup, AdminDropdownMenuRadioItem, AdminDropdownMenuSeparator, AdminDropdownMenuShortcut, AdminDropdownMenuSub, AdminDropdownMenuSubContent, AdminDropdownMenuSubTrigger, AdminDropdownMenuTrigger, } from '@/components/admin/dropdown-menu' ``` ## 用法 點 trigger 顯示 content;items 由鍵盤 ArrowUp / ArrowDown 切換 highlight、Enter 觸發 select、Escape 關閉。 ```vue ``` ## 場景 ### 操作選單 行內 action menu,含 disabled item 與 separator 分組;常用於列表 row 右側「⋯」按鈕。 ```vue ``` ### 進階選單 checkbox item(多選)、radio group(單選)、巢狀 sub-menu、快捷鍵提示。 ```vue ``` ### 鍵盤導航 | 快捷鍵 | 行為 | | ----------------------- | --------------------------------------------- | | `ArrowDown` / `ArrowUp` | 移動 highlight 到下一個 / 上一個 item | | `Enter` / `Space` | 觸發 highlighted item 的 `select` event 並關閉 menu | | `Escape` | 關閉 menu,focus 回 trigger | | `Tab` | 關閉 menu,focus 移到下一個 tabbable 元素 | | `Home` / `End` | 跳到第一個 / 最後一個 item | | `ArrowRight` | 在 sub-trigger 上展開子選單並 focus 第一個 item(RTL 相反) | | `ArrowLeft` | 收合子選單,focus 回 sub-trigger(RTL 相反) | | 任意可印字元 | type-ahead 跳到 `textValue` 開頭符合的 item | 行為由 reka-ui `DropdownMenu` primitive 提供,本元件薄包一層樣式。 ### 與其他元件的差別 | 元件 | 適用情境 | | ----------------------- | ------------------------------------------------------------------------ | | **admin-dropdown-menu** | 觸發後彈出的「**選項列表**」,含鍵盤導航;典型用例:navigation menu、action menu、heading dropdown | | `admin-popover` | 任意 **內容浮層**(不限選項列表);沒有 roving tabindex / arrow key 導航 | | `admin-select` | 表單欄位用的 **單選**,會把選定值寫回 `` | ## API 參考 ### 組成 ```vue ``` ### admin-dropdown-menu ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | ------------------------- | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `defaultOpen` | `boolean | undefined` | — | The open state of the dropdown menu when it is initially rendered. Use when you do not need to control its open state. | | `open` | `boolean | undefined` | — | The controlled open state of the menu. Can be used as \`v-model\:open\`. | | `dir` | `Direction$4 | undefined` | — | The reading direction of the combobox when applicable.\
If omitted, inherits globally from \`ConfigProvider\` or assumes LTR (left-to-right) reading mode. | | `modal` | `boolean | undefined` | — | The modality of the dropdown menu.\
When set to \`true\`, interaction with outside elements will be disabled and only menu content will be visible to screen readers. | | `class` | `unknown` | — | — | #### Events | 名稱 | Payload | 說明 | | ------------- | --------- | -- | | `update:open` | `boolean` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------------------- | -- | | `default` | `{ open: boolean; }` | — | :: ### admin-dropdown-menu-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with item | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------------------------- | ----------------------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `loop` | `boolean | undefined` | `false` | When \`true\`, keyboard navigation will loop from last item to first, and vice versa. | | `align` | `"start" | "end" | "center" | undefined` | `"center"` | The preferred alignment against the trigger.\
May change when collisions occur. | | `sideOffset` | `number | undefined` | `4` | The distance in pixels from the trigger. | | `memoDependencies` | `unknown[] | undefined` | — | Reactive dependencies that should invalidate the memoized content subtree. | | `side` | `"top" | "right" | "bottom" | "left" | undefined` | `"bottom"` | The preferred side of the trigger to render against when open.\
Will be reversed when collisions occur and avoidCollisions\
is enabled. | | `sideFlip` | `boolean | undefined` | `true` | Flip to the opposite side when colliding with boundary. | | `alignOffset` | `number | undefined` | `0` | An offset in pixels from the \`start\` or \`end\` alignment options. | | `alignFlip` | `boolean | undefined` | `true` | Flip alignment when colliding with boundary.\
May only occur when \`prioritizePosition\` is true. | | `avoidCollisions` | `boolean | undefined` | `true` | When \`true\`, overrides the side and align preferences\
to prevent collisions with boundary edges. | | `collisionBoundary` | `Element | (Element | null)[] | null | undefined` | `[]` | The element used as the collision boundary. By default\
this is the viewport, though you can provide additional\
element(s) to be included in this check. | | `collisionPadding` | `number | Partial> | undefined` | `0` | The distance in pixels from the boundary edges where collision\
detection should occur. Accepts a number (same for all sides),\
or a partial padding object, for example: { top: 20, left: 20 }. | | `arrowPadding` | `number | undefined` | `0` | The padding between the arrow and the edges of the content.\
If your content has border-radius, this will prevent it from\
overflowing the corners. | | `hideShiftedArrow` | `boolean | undefined` | `true` | When \`true\`, hides the arrow when it cannot be centered\
to the reference element. | | `sticky` | `"partial" | "always" | undefined` | `"partial"` | The sticky behavior on the align axis. \`partial\` will keep the\
content in the boundary as long as the trigger is at least partially\
in the boundary whilst "always" will keep the content in the boundary\
regardless. | | `hideWhenDetached` | `boolean | undefined` | `false` | Whether to hide the content when the trigger becomes fully occluded. | | `positionStrategy` | `"fixed" | "absolute" | undefined` | — | The type of CSS position property to use. | | `updatePositionStrategy` | `"always" | "optimized" | undefined` | `'optimized'` | Strategy to update the position of the floating element on every animation frame. | | `disableUpdateOnLayoutShift` | `boolean | undefined` | `false` | Whether to disable the update position for the content when the layout shifted. | | `prioritizePosition` | `boolean | undefined` | `false` | Force content to be position within the viewport.\
Might overlap the reference element, which may not be desired. | | `reference` | `ReferenceElement | undefined` | — | The custom element or virtual element that will be set as the reference\
to position the floating element.\
If provided, it will replace the default anchor element. | | `class` | `ClassValue` | — | — | | `to` | `string | HTMLElement | undefined` | — | — | #### Events | 名稱 | Payload | 說明 | | -------------------- | --------------------------------------------- | -- | | `escapeKeyDown` | `KeyboardEvent` | — | | `pointerDownOutside` | `PointerDownOutsideEvent` | — | | `focusOutside` | `FocusOutsideEvent` | — | | `interactOutside` | `PointerDownOutsideEvent | FocusOutsideEvent` | — | | `closeAutoFocus` | `Event` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the item. | | `textValue` | `string | undefined` | — | Optional text used for typeahead purposes. By default the typeahead behavior will use the \`.textContent\` of the item. \
Use this when the content is complex, or you have non-textual content inside. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | | `inset` | `boolean | undefined` | `false` | — | #### Events | 名稱 | Payload | 說明 | | -------- | ------- | -- | | `select` | `Event` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-separator ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | :: ### admin-dropdown-menu-label ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | | `inset` | `boolean | undefined` | `false` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-group ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `unknown` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-checkbox-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `modelValue` | `CheckedState | undefined` | — | The controlled checked state of the item. Can be used as \`v-model\`. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the item. | | `textValue` | `string | undefined` | — | Optional text used for typeahead purposes. By default the typeahead behavior will use the \`.textContent\` of the item. \
Use this when the content is complex, or you have non-textual content inside. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | #### Events | 名稱 | Payload | 說明 | | ------------------- | --------- | -- | | `select` | `Event` | — | | `update:modelValue` | `boolean` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-radio-group ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `modelValue` | `AcceptableValue | undefined` | — | The value of the selected item in the group. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | #### Events | 名稱 | Payload | 說明 | | ------------------- | ----------------- | -- | | `update:modelValue` | `AcceptableValue` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-radio-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `value`\* | `AcceptableValue` | — | The unique value of the item. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the item. | | `textValue` | `string | undefined` | — | Optional text used for typeahead purposes. By default the typeahead behavior will use the \`.textContent\` of the item. \
Use this when the content is complex, or you have non-textual content inside. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | -------- | ------- | -- | | `select` | `Event` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-sub ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | --------------------- | --- | ---------------------------------------------------------------------------------------------------------------------- | | `defaultOpen` | `boolean | undefined` | — | The open state of the dropdown menu when it is initially rendered. Use when you do not need to control its open state. | | `open` | `boolean | undefined` | — | The controlled open state of the menu. Can be used as \`v-model\:open\`. | | `class` | `unknown` | — | — | #### Events | 名稱 | Payload | 說明 | | ------------- | --------- | -- | | `update:open` | `boolean` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-sub-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the item. | | `textValue` | `string | undefined` | — | Optional text used for typeahead purposes. By default the typeahead behavior will use the \`.textContent\` of the item. \
Use this when the content is complex, or you have non-textual content inside. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | | `inset` | `boolean | undefined` | `false` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-sub-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------------------------- | ----------------------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `loop` | `boolean | undefined` | `false` | When \`true\`, keyboard navigation will loop from last item to first, and vice versa. | | `sideOffset` | `number | undefined` | `0` | The distance in pixels from the trigger. | | `memoDependencies` | `unknown[] | undefined` | — | Reactive dependencies that should invalidate the memoized content subtree. | | `sideFlip` | `boolean | undefined` | `true` | Flip to the opposite side when colliding with boundary. | | `alignOffset` | `number | undefined` | `0` | An offset in pixels from the \`start\` or \`end\` alignment options. | | `alignFlip` | `boolean | undefined` | `true` | Flip alignment when colliding with boundary.\
May only occur when \`prioritizePosition\` is true. | | `avoidCollisions` | `boolean | undefined` | `true` | When \`true\`, overrides the side and align preferences\
to prevent collisions with boundary edges. | | `collisionBoundary` | `Element | (Element | null)[] | null | undefined` | `[]` | The element used as the collision boundary. By default\
this is the viewport, though you can provide additional\
element(s) to be included in this check. | | `collisionPadding` | `number | Partial> | undefined` | `0` | The distance in pixels from the boundary edges where collision\
detection should occur. Accepts a number (same for all sides),\
or a partial padding object, for example: { top: 20, left: 20 }. | | `arrowPadding` | `number | undefined` | `0` | The padding between the arrow and the edges of the content.\
If your content has border-radius, this will prevent it from\
overflowing the corners. | | `hideShiftedArrow` | `boolean | undefined` | `true` | When \`true\`, hides the arrow when it cannot be centered\
to the reference element. | | `sticky` | `"partial" | "always" | undefined` | `"partial"` | The sticky behavior on the align axis. \`partial\` will keep the\
content in the boundary as long as the trigger is at least partially\
in the boundary whilst "always" will keep the content in the boundary\
regardless. | | `hideWhenDetached` | `boolean | undefined` | `false` | Whether to hide the content when the trigger becomes fully occluded. | | `positionStrategy` | `"fixed" | "absolute" | undefined` | — | The type of CSS position property to use. | | `updatePositionStrategy` | `"always" | "optimized" | undefined` | `'optimized'` | Strategy to update the position of the floating element on every animation frame. | | `disableUpdateOnLayoutShift` | `boolean | undefined` | `false` | Whether to disable the update position for the content when the layout shifted. | | `prioritizePosition` | `boolean | undefined` | `false` | Force content to be position within the viewport.\
Might overlap the reference element, which may not be desired. | | `reference` | `ReferenceElement | undefined` | — | The custom element or virtual element that will be set as the reference\
to position the floating element.\
If provided, it will replace the default anchor element. | | `class` | `ClassValue` | — | — | #### Events | 名稱 | Payload | 說明 | | -------------------- | --------------------------------------------- | -- | | `escapeKeyDown` | `KeyboardEvent` | — | | `pointerDownOutside` | `PointerDownOutsideEvent` | — | | `focusOutside` | `FocusOutsideEvent` | — | | `interactOutside` | `PointerDownOutsideEvent | FocusOutsideEvent` | — | | `openAutoFocus` | `Event` | — | | `closeAutoFocus` | `Event` | — | | `entryFocus` | `Event` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-dropdown-menu-shortcut ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | -- | | `class` | `ClassValue` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminDropdownMenu"} # Field ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/field ``` ```ts import { AdminField, AdminFieldContent, AdminFieldDescription, AdminFieldDivider, AdminFieldError, AdminFieldGroup, AdminFieldLabel, AdminFieldLegend, AdminFieldSet, AdminFieldTitle, } from '@/components/admin/field' ``` ## 用法 ```vue ``` ## 場景 ### 錯誤訊息 ```vue ``` ### 水平 Orientation ```vue ``` ## API 參考 ### 組成 ```vue ``` | 元件 | 角色 | | ------------------------- | ------------------------------------------------------------ | | `admin-field-set` | 表單區塊外層,對應 HTML `
`,可巢狀使用 | | `admin-field-legend` | 區塊標題,對應 ``,視覺上為主標題 | | `admin-field-group` | 欄位群組容器,統一欄位間距與 `@container/field-group` 響應式斷點 | | `admin-field` | 單一欄位容器,控制 label / 輸入欄 / 描述 / 錯誤的排版與 `orientation` | | `admin-field-label` | 欄位 label | | `admin-field-description` | 欄位輔助說明 | | `admin-field-error` | 驗證錯誤訊息,搭配輸入欄位的 `is-error` 樣式 | | `admin-field-content` | 在橫向欄位中包住 label + description,讓控制元件(switch / checkbox 等)對齊在右側 | | `admin-field-title` | 群組內次標題,用於分段但不需 `legend` 語意時 | | `admin-field-divider` | 群組內分隔線,視覺切分不同區段 | ### admin-field ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | ----------------------------------- | --- | ------------- | | `class` | `ClassValue` | — | 根元素之自訂 class | | `orientation` | `AdminFieldOrientation | undefined` | — | 排列方向(直向 / 橫向) | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-set ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-legend ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-group ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-label ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-description ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-error ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------- | ----------------------------------------------------------------------- | --- | ------------------------------------------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | | `errors` | `(string | { message: string | undefined; } | undefined)[] | undefined` | — | 錯誤訊息陣列,可為字串或具 \`message\` 欄位之物件;單條時顯示為段落、多條時自動列表 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-title ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-field-divider ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ## 更新紀錄 :admin-changelog{component="AdminField"} # File Upload ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/file-upload ``` ```ts import { AdminFileUpload, AdminFileUploadClear, AdminFileUploadDropzone, AdminFileUploadItem, AdminFileUploadItemDelete, AdminFileUploadItemMetadata, AdminFileUploadItemPreview, AdminFileUploadItemProgress, AdminFileUploadList, AdminFileUploadTrigger, } from '@/components/admin/file-upload' ``` ## 用法 ```vue ``` ## 場景 ### 僅按鈕、不要 Dropzone ```vue ``` ### 程式寫入 URL(不經檔案選擇器) 由素材庫、過往上傳紀錄等來源直接寫入 URL 項目,跳過檔案選擇器流程。 ```vue ``` ## Type-safe 列表項目 `AdminFileUpload` 已是 generic(`TItem extends AdminFileUploadListItem`),以子型別的 ref 綁定 `v-model` 即可讓列表項目攜帶業務欄位(如後端回傳的資產 id),`update:modelValue` payload 同步收斂為該子型別。 元件自行新增的項目(使用者選檔)僅含 base 欄位(`id`/`source`);自訂欄位由呼叫端於 `upload` 事件後自行補寫。 ::alert{title="需開啟 strictVModel" type="info"} 型別檢查需開啟 `strictVModel`(若已開啟 `strictTemplates` 則已包含)。設定見 [Type-safe](https://component-registry-4d4d86.gitlab.io/docs/get-started/type-safe)。下列同時含合法綁定與刻意錯誤綁定;錯誤處以 `@vue-expect-error` 標示。 :: ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-file-upload ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------- | --------------------------------------------- | | `class` | `ClassValue` | — | 根元素之自訂 class | | `disabled` | `boolean | undefined` | `false` | 設為 \`true\` 時禁用整個上傳互動 | | `invalid` | `boolean | undefined` | `false` | 設為 \`true\` 時套用錯誤狀態樣式 | | `multiple` | `boolean | undefined` | `true` | 設為 \`false\` 時限制單檔上傳 | | `accept` | `string | undefined` | — | 可接受之檔案類型(同原生 \`\\` accept) | | `onFileValidate` | `((file: File, ctx: { index: number; accepted: number; total: number; }) => string | true | Promise) | undefined` | — | 自訂單檔驗證 hook;回傳 \`true\` 為通過,回傳字串為錯誤訊息 | | `modelValue` | `TItem[] | undefined` | `[]` | — | #### Events | 名稱 | Payload | 說明 | | ------------------- | ---------------------------------------------- | -------------------------------------- | | `fileReject` | `{ reason: string; file?: File | undefined; }` | 檔案被拒絕時觸發(驗證失敗或被 \`onFileValidate\` 拒收) | | `upload` | `{ id: string; file: File; }` | 檔案被接受並加入列表後觸發,可用於啟動實際上傳流程 | | `update:modelValue` | `TItem[]` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-file-upload-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-file-upload-list ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | --------------------------------------- | ------------ | -- | | `orientation` | `"horizontal" | "vertical" | undefined` | `"vertical"` | — | | `class` | `ClassValue` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-file-upload-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------ | --- | -- | | `itemId`\* | `string` | — | — | | `class` | `ClassValue` | — | — | *\\\* 代表必填* #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-file-upload-clear ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | ------------------------------------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | | `forceMount` | `boolean | undefined` | `false` | — | | `label` | `string | undefined` | `"Clear all"` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-file-upload-item-delete ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | | `label` | `string | undefined` | `"Remove file"` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-file-upload-item-progress ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------- | ------------------------------------------------------- | --- | -- | | `class` | `ClassValue` | — | — | | `labels` | `Partial> | undefined` | — | — | #### Slots | 名稱 | Bindings | 說明 | | -------- | ---------------------------------------------- | -- | | `status` | `{ label: string; status: FileUploadStatus; }` | — | | `icon` | `{ status: FileUploadStatus; }` | — | :: ### admin-file-upload-dropzone ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | -- | | `class` | `ClassValue` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-file-upload-item-metadata ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | -- | | `class` | `ClassValue` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-file-upload-item-preview ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | -- | | `class` | `ClassValue` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | ------------------------------------------------ | -- | | `default` | `{ item: AdminFileUploadListItem | undefined; }` | — | :: ## 注意事項 - 自訂子元件可從 `@/components/admin/file-upload` import `useFileUploadRoot()` / `useFileUploadItem()` 取得內部狀態。 - `useFileUploadRoot()` 的 `modelValue` 為寬型別 `AdminFileUploadListItem[]`;泛型收斂僅作用於 root 的 `v-model` 與 `update:modelValue`。 - 單張圖片欄位使用 [`admin-image-upload`](https://component-registry-4d4d86.gitlab.io/docs/admin/image-upload),多檔、列表進度、拖曳區使用本元件族。 ## 更新紀錄 :admin-changelog{component="AdminFileUpload"} # Image ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/image ``` ```ts import { AdminImage, AdminImageFallback, AdminImageImg, AdminImagePlaceholder, } from '@/components/admin/image' ``` ## 用法 ```vue ``` ## 場景 ### 自訂版面與裁切 ```vue ``` ### 錯誤態 fallback 故意傳入無效 `src` 觸發 `error`,顯示預設 fallback。 ```vue ``` ### 自訂 placeholder 與 fallback ::alert{title="子元件渲染條件" type="info"} `admin-image-placeholder` 僅在 `loading` 狀態渲染,`admin-image-fallback` 僅在 `error` 狀態渲染;不放對應子元件即無該狀態的視覺。 :: ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-image ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-image-img ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------------- | -------------------------------------------------- | --- | ------------------------------------- | | `src`\* | `string` | — | 圖片 URL(必填) | | `alt`\* | `string` | — | 圖片替代文字(必填) | | `loading` | `"eager" | "lazy" | undefined` | — | 原生 \`\\` 之 \`loading\` 屬性 | | `decoding` | `"auto" | "async" | "sync" | undefined` | — | 原生 \`\\` 之 \`decoding\` 屬性 | | `srcset` | `string | undefined` | — | 響應式圖片之 \`srcset\` 候選清單 | | `sizes` | `string | undefined` | — | 響應式圖片之 \`sizes\` 描述 | | `referrerpolicy` | `HTMLAttributeReferrerPolicy | undefined` | — | 原生 \`\\` 之 \`referrerpolicy\` 屬性 | | `crossorigin` | `"" | "anonymous" | "use-credentials" | undefined` | — | 原生 \`\\` 之 \`crossorigin\` 屬性 | | `class` | `ClassValue` | — | 根元素之自訂 class | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ------- | ------- | --------- | | `error` | `Event` | 圖片載入失敗時觸發 | | `load` | `Event` | 圖片載入成功時觸發 | :: ### admin-image-placeholder ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-image-fallback ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 注意事項 - **CDN 同 URL 不同檔**:若 `src` 字串完全相同但內容換了(CDN 快取),`` 不會自動重抓。父層應在 URL 後加 query string 強制更新。 - 純展示用 `admin-image`;頭像場景改用 `admin-avatar`;表單上傳改用 `admin-image-upload`。 ## 更新紀錄 :admin-changelog{component="AdminImage"} # Image Upload ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/image-upload ``` ```ts import { AdminImageUpload, AdminImageUploadLoading, AdminImageUploadMessage, AdminImageUploadPlaceholder, AdminImageUploadPreview, AdminImageUploadTrigger, } from '@/components/admin/image-upload' ``` ## 用法 ```vue ``` ## 場景 ### 與表單驗證整合 ```vue ``` > 以 vee-validate 的 `` 提供驗證,將 `errorMessage` 是否存在透過 `:is-error` 傳入元件即可;錯誤文字交由元件內建的 `AdminImageUploadMessage` 顯示,無需額外渲染 `admin-field-error`,避免訊息重複。 > > v-model 綁的是使用者新選的 `File`。已上傳完成的 URL 另外存一個 state,上傳成功後餵給 `AdminImageUploadPreview` 的 `:src`。 ### 顯示既有圖片 編輯表單的既有圖片(或上傳完成的持久化 URL)不進 v-model,改由 `AdminImageUploadPreview` 的 `src` 顯示。有選檔(`File`)時 `File` 優先,否則 fallback `src`。因為此時 v-model 為 `null`,需以 `v-if` gate 掉 `AdminImageUploadPlaceholder`,避免與既有圖重疊: ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-image-upload ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------------- | ----------------------------------------------------------------------------------------------------------------- | ----------- | ---------------------------------------------- | | `disabled` | `boolean | undefined` | `false` | 設為 \`true\` 時禁用上傳互動 | | `isError` | `boolean | undefined` | `false` | 設為 \`true\` 時套用錯誤狀態樣式 | | `status` | `"uploading" | "failed" | undefined` | — | 外部驅動之上傳狀態:\`uploading\` 顯示載入態、\`failed\` 顯示錯誤態 | | `accept` | `string | undefined` | `"image/*"` | 可接受之檔案類型(同原生 \`\\` accept) | | `onFileValidate` | `((file: File, ctx: { index: 0; accepted: 0; total: 0; }) => string | true | Promise) | undefined` | — | 自訂單檔驗證 hook;回傳 \`true\` 為通過,回傳字串為錯誤訊息 | | `class` | `ClassValue` | — | 根元素之自訂 class | | `modelValue` | `File | null | undefined` | `null` | — | #### Events | 名稱 | Payload | 說明 | | ------------------- | ---------------------------------------------- | ------------------------ | | `update:modelValue` | `File | null` | — | | `fileReject` | `{ reason: string; file?: File | undefined; }` | 檔案被拒(驗證失敗或拋錯)時觸發 | | `upload` | `{ file: File; }` | 檔案通過驗證、modelValue 已更新後觸發 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | #### Expose | 名稱 | 簽名 | 說明 | | -------------------- | ------------ | -------------------------------- | | `openFileDialog` | `() => void` | 程式化開啟系統檔案選擇對話框(disabled 時 no-op) | | `clearRejectMessage` | `() => void` | 清掉上一次拒絕的訊息 | | `clear` | `() => void` | 把 v-model 設回 null 並清掉 reject 訊息 | :: ### admin-image-upload-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-image-upload-loading ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | -- | | `class` | `ClassValue` | — | — | :: ### admin-image-upload-message ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | -- | | `class` | `ClassValue` | — | — | :: ### admin-image-upload-placeholder ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | -- | | `class` | `ClassValue` | — | — | :: ### admin-image-upload-preview ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------------------------- | --- | ------------------------------------------- | | `src` | `string | null | undefined` | — | 既有/已持久化圖片的唯讀顯示來源;有選檔(\`File\`)時 \`File\` 優先 | | `class` | `ClassValue` | — | — | :: ## 注意事項 - **v-model 只認 `File | null`**:既有/已上傳的 URL 字串不進 v-model,改由 `AdminImageUploadPreview` 的 `:src` 顯示(見「顯示既有圖片」)。 - **CDN 同 URL 不同檔**:若上傳成功後 backend 回傳的 URL 與舊圖完全相同(CDN 快取),`` 不會自動重抓。父層應在傳給 `:src` 的 URL 後加 query string(例如 `?v=timestamp`)強制更新。 - **元件不負責上傳**:`@upload` 只通知「使用者選了新檔且通過 validate」,實際 fetch / FormData / endpoint 全由父層處理。 ## 更新紀錄 :admin-changelog{component="AdminImageUpload"} # Input ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/input ``` ```ts import { AdminInput, AdminInputClear, AdminInputPasswordToggle, AdminInputWordLimit, } from '@/components/admin/input' ``` ## 用法 ```vue ``` ## 場景 ### 可清除內容 輸入框在有值時會顯示清除按鈕。 ```vue ``` ### 密碼欄位與顯示切換 ```vue ``` ### 錯誤狀態 ```vue ``` ## Type-safe 封裝 `AdminInput` 採原生 `input` 封裝,`modelValue` 為 `string | number`,不會依 `type` 在 compile-time 與 `v-model` 型別對齊。 開啟 `strictVModel` 或 `strictTemplates` 時,若以更嚴的型別(例如 `number | null`)綁定,容易出現型別錯誤。這屬原生 `input` 的型別行為,而非元件缺漏。 若需要讓 `type` 與 `v-model` 型別對齊,可自行封裝。 範例: ```vue ``` ::alert{title="number | null 需處理清空" type="warning"} 若型別為 `number | null`,runtime 仍須處理清空:原生 `type="number"` 清空時值會變成空字串 `''`,需轉成 `null`,型別才與實際行為一致。 :: ::alert{title="需開啟 strictVModel" type="info"} 型別檢查需開啟 `strictVModel`(若已開啟 `strictTemplates` 則已包含)。設定見 [Type-safe](https://component-registry-4d4d86.gitlab.io/docs/get-started/type-safe)。下列同時含合法綁定與刻意錯誤綁定;錯誤處以 `@vue-expect-error` 標示。 :: ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-input ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------- | ------------------------------------ | -------- | --------------------------------------------------- | | `defaultValue` | `string | number | undefined` | — | 初始值(非控制模式) | | `modelValue` | `string | number | undefined` | — | 受控值,以 \`v-model\` 綁定 | | `placeholder` | `string | undefined` | — | 預設提示文字 | | `disabled` | `boolean | undefined` | — | 設為 \`true\` 時禁用輸入並套用視覺停用樣式 | | `readonly` | `boolean | undefined` | — | 設為 \`true\` 時禁止編輯文字,但仍允許 focus 與 selection | | `maxlength` | `number | undefined` | — | 限制最大字元數(並由 \`admin-input-word-limit\` 顯示計數) | | `class` | `ClassValue` | — | 根元素之自訂 class | | `type` | `InputTypeHTMLAttribute | undefined` | `"text"` | HTML input type(如 \`text\`、\`password\`、\`number\`) | | `isError` | `boolean | undefined` | — | 設為 \`true\` 時套用錯誤狀態樣式與 \`aria-invalid\` | | `id` | `string | undefined` | — | 透傳至內層 \`input\` 之 \`id\`;純透傳,未提供時不自動生成 | | `name` | `string | undefined` | — | 透傳至內層 \`input\` 之 \`name\`,供原生表單提交使用 | #### Events | 名稱 | Payload | 說明 | | ------------------- | ----------------- | ------------------------------------------------- | | `blur` | `FocusEvent` | 內層 \`input\` 失焦時轉發之原生事件 | | `change` | `Event` | 內層 \`input\` 觸發原生 \`change\`(值變更並 commit)時轉發之原生事件 | | `input` | `Event` | 內層 \`input\` 觸發原生 \`input\`(每次輸入)時轉發之原生事件 | | `update:modelValue` | `string | number` | modelValue 更新時觸發 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | ------------------------------- | | `default` | `any` | 預設 slot | | `prefix` | `any` | 輸入框前綴 slot,常用於放置 icon | | `suffix` | `any` | 輸入框後綴 slot,常用於放置 icon、清除按鈕、字數計數 | #### Expose | 名稱 | 簽名 | 說明 | | ------- | ------------------------- | ------------------------------------------------------------ | | `input` | `HTMLInputElement | null` | 內部原生 input 元素之 template ref,可用於程式化 focus / blur / select 等操作 | :: ### admin-input-clear ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | #### Events | 名稱 | Payload | 說明 | | ------- | ------- | -------------- | | `clear` | — | 點擊清除按鈕、值已清空後觸發 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-input-password-toggle ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | :: ### admin-input-word-limit ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | :: ## 更新紀錄 :admin-changelog{component="AdminInput"} # Loading ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/loading ``` ```ts import { AdminLoading, vAdminLoading, } from '@/components/admin/loading' ``` ## 用法 ```vue ``` ## 場景 ### Inline 區塊 loading ```vue ``` ### 命令式全螢幕 loading 多個非同步請求共用一個全螢幕 loading:自行以 `admin-loading` 組裝;全域共享與計數由呼叫端決定。 下面這版用一個 ref-count counter:計數從 0 變 1 才顯示、從 1 變回 0 才隱藏,中間重疊的請求不會重複蓋上去。 ```vue ``` > 想讓多個元件共用同一份 loading 狀態,把 counter 包進 `createSharedComposable`(`@vueuse/core`)就行。要不要這樣做,看你。 #### 搭配 useOverlay 如果你已經用 `useOverlay` 在統一管理 overlay,也可以讓它來掛 loading。只是它的 provider 會綁 `open` 和 `after-leave`,而 `admin-loading` 只是純展示元件、沒有這些 emit,所以得先包一層 wrapper 幫它補上: ```vue [loading-overlay-wrapper.vue] ``` ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-loading ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------------------------------- | ------- | ----------------------------------------------------------------------- | | `mode` | `"fullscreen" | "inline" | undefined` | — | 顯示模式變體(\`fullscreen\` / \`inline\`);未指定時預設為 \`fullscreen\`(fixed 全螢幕遮罩) | | `label` | `string | undefined` | `"載入中"` | 顯示在 spinner 旁的文字標籤 | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------------------- | -- | | `default` | `{ class: string; }` | — | :: ## 更新紀錄 :admin-changelog{component="AdminLoading"} # Notification ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/notification ``` ```ts import { AdminNotification, errorNotification, infoNotification, successNotification, warningNotification, } from '@/components/admin/notification' ``` ## 用法 ```vue ``` ## 場景 ### 狀態變體 ```vue ``` ### 含操作按鈕 以 `action` 設定按鈕標籤與 callback,適合「復原」這類可逆操作。 ```vue ``` ## API 參考 ### 組成 ```vue ``` `admin-notification` 須在 app root(通常是 `app.vue`)掛載一次;後續以函式呼叫的方式觸發通知。 ### admin-notification ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------------------- | ------------------------------------ | --- | -- | | `id` | `string | undefined` | — | — | | `invert` | `boolean | undefined` | — | — | | `theme` | `Theme | undefined` | — | — | | `position` | `Position | undefined` | — | — | | `closeButtonPosition` | `CloseButtonPosition | undefined` | — | — | | `hotkey` | `string[] | undefined` | — | — | | `richColors` | `boolean | undefined` | — | — | | `expand` | `boolean | undefined` | — | — | | `duration` | `number | undefined` | — | — | | `gap` | `number | undefined` | — | — | | `visibleToasts` | `number | undefined` | — | — | | `closeButton` | `boolean | undefined` | — | — | | `toastOptions` | `ToastOptions | undefined` | — | — | | `class` | `string | undefined` | — | — | | `offset` | `Offset | undefined` | — | — | | `mobileOffset` | `Offset | undefined` | — | — | | `dir` | `"ltr" | "rtl" | "auto" | undefined` | — | — | | `swipeDirections` | `SwipeDirection[] | undefined` | — | — | | `icons` | `ToastIcons | undefined` | — | — | | `containerAriaLabel` | `string | undefined` | — | — | :: ## 更新紀錄 :admin-changelog{component="AdminNotification"} # Number Field ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/number-field ``` ```ts import { AdminNumberField, AdminNumberFieldContent, AdminNumberFieldDecrement, AdminNumberFieldIncrement, AdminNumberFieldInput, } from '@/components/admin/number-field' ``` ## 用法 ```vue ``` ## 場景 ### 自訂 step ```vue ``` ### 停用狀態 ```vue ``` ### 錯誤狀態 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-number-field ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `defaultValue` | `number | undefined` | — | — | | `modelValue` | `number | null | undefined` | — | — | | `min` | `number | undefined` | — | The smallest value allowed for the input. | | `max` | `number | undefined` | — | The largest value allowed for the input. | | `step` | `number | undefined` | — | The amount that the input value changes with each increment or decrement "tick". | | `stepSnapping` | `boolean | undefined` | — | When \`false\`, prevents the value from snapping to the nearest increment of the step value | | `focusOnChange` | `boolean | undefined` | — | When \`true\`, the input will be focused when the value changes. | | `formatOptions` | `Intl.NumberFormatOptions | undefined` | — | Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user. | | `locale` | `string | undefined` | — | The locale to use for formatting and currencies | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the Number Field. | | `readonly` | `boolean | undefined` | — | When \`true\`, the Number Field is read-only. | | `disableWheelChange` | `boolean | undefined` | — | When \`true\`, prevents the value from changing on wheel scroll. | | `invertWheelChange` | `boolean | undefined` | — | When \`true\`, inverts the direction of the wheel change. | | `id` | `string | undefined` | — | Id of the element | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `name` | `string | undefined` | — | The name of the field. Submitted with its owning form as part of a name/value pair. | | `required` | `boolean | undefined` | — | When \`true\`, indicates that the user must set the value before the owning form can be submitted. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `isError` | `boolean | undefined` | — | 設為 \`true\` 時掛上 \`data-is-error\` 屬性供樣式 hook | #### Events | 名稱 | Payload | 說明 | | ------------------- | -------- | -- | | `update:modelValue` | `number` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | --------------------------------------------------------------------------- | -- | | `default` | `{ modelValue: number | undefined; textValue: string; readonly: boolean; }` | — | :: ### admin-number-field-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-number-field-input ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-number-field-increment ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `disabled` | `boolean | undefined` | — | — | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-number-field-decrement ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `disabled` | `boolean | undefined` | — | — | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminNumberField"} # Overlay ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/overlay ``` ```ts import { AdminOverlayProvider, useOverlay } from '@/components/admin/overlay' ``` 於 app root(通常是 `app.vue`)掛載 `admin-overlay-provider` 一次;後續以共用 `useOverlay()` 建立的 overlay 會自動註冊到此 provider: ```vue [app.vue] ``` ## 用法 ```vue ``` ## 場景 ### 基本開啟流程 觸發 overlay 並在當下根據回傳值處理。 ```vue ``` ### 等待結果回傳 呼叫端需要等使用者 confirm/cancel 後再繼續。 ```vue ``` ### 重用同一個 overlay 並覆寫 props 多個按鈕共用同一個 overlay component、每次 `open()` 直接傳入要覆寫的 props 即可替換文案。 ```vue ``` ## API 參考 ### 組成 ```vue ``` `admin-overlay-provider` 須在 app root 掛載一次; ### admin-overlay-provider ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | :: ## 更新紀錄 :admin-changelog{component="AdminOverlay"} # Pagination ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/pagination ``` ```ts import { AdminPagination, AdminPaginationContent, AdminPaginationEllipsis, AdminPaginationFirst, AdminPaginationInfo, AdminPaginationItem, AdminPaginationLast, AdminPaginationNext, AdminPaginationPerPage, AdminPaginationPrevious, } from '@/components/admin/pagination' ``` ## 用法 ```vue ``` ## 場景 ### 完整樣式(含資訊 + 每頁筆數) ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-pagination ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `page` | `number | undefined` | — | The controlled value of the current page. Can be binded as \`v-model\:page\`. | | `defaultPage` | `number | undefined` | — | The value of the page that should be active when initially rendered.\
Use when you do not need to control the value state. | | `itemsPerPage`\* | `number` | — | Number of items per page | | `total` | `number | undefined` | — | Number of items in your list | | `siblingCount` | `number | undefined` | — | Number of sibling should be shown around the current page | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with item | | `showEdges` | `boolean | undefined` | — | When \`true\`, always show first page, last page, and ellipsis | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ------------- | -------- | -- | | `update:page` | `number` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------------------------------------- | -- | | `default` | `{ page: number; pageCount: number; }` | — | :: ### admin-pagination-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `value`\* | `number` | — | Value for the page | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | *\\\* 代表必填* #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-pagination-info ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | -------------------- | --- | ------------ | | `total` | `number | undefined` | — | 顯示總筆數 | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | ---------------------------------------------------- | -- | | `default` | `{ pageCount: number; total?: number | undefined; }` | — | :: ### admin-pagination-per-page ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------- | ----------------------------------------- | ------------------- | ---------------- | | `options` | `number[] | undefined` | `[10, 20, 50, 100]` | 每頁筆數選項 | | `labelFormat` | `((value: number) => string) | undefined` | — | 自訂選項 label 格式化函式 | | `class` | `ClassValue` | — | 根元素之自訂 class | | `modelValue`\* | `number` | — | — | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ------------------- | -------- | -- | | `update:modelValue` | `number` | — | :: ### admin-pagination-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------------------------------------------------------------------------- | -- | | `default` | `{ items: ({ type: "ellipsis"; } | { type: "page"; value: number; })[]; }` | — | :: ### admin-pagination-ellipsis ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-pagination-first ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-pagination-last ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-pagination-next ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-pagination-previous ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminPagination"} # Pdf Viewer ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/pdf-viewer ``` ```ts import { AdminPdfViewer, AdminPdfViewerFullscreen, AdminPdfViewerPageNav, AdminPdfViewerPages, AdminPdfViewerToolbar, AdminPdfViewerZoom } from '@/components/admin/pdf-viewer' ``` ## 用法 ```vue ``` ## 場景 ### 自訂 toolbar 組合 ```vue ``` ### 外部控制當前頁 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-pdf-viewer ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | -------------------- | --- | -------------------- | | `src`\* | `string` | — | PDF 檔案 URL(必填) | | `defaultPage` | `number | undefined` | `1` | uncontrolled 模式之初始頁碼 | | `defaultZoom` | `number | undefined` | — | 初始縮放百分比 | | `class` | `ClassValue` | — | 根元素之自訂 class | | `page` | `number | undefined` | — | — | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | ------------- | -------------------- | ---------------------------------- | | `error` | `Error` | 載入或渲染發生錯誤時觸發 | | `load` | `string` | PDF 載入完成時觸發,payload 為內部 documentId | | `update:page` | `number | undefined` | — | | `pageChange` | `number` | 當前頁碼變更時觸發 | | `zoomChange` | `number` | 縮放百分比變更時觸發 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-pdf-viewer-toolbar ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | ------- | -------- | -- | | `left` | `{}` | — | | `right` | `{}` | — | :: ### admin-pdf-viewer-pages ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-pdf-viewer-fullscreen ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | :: ### admin-pdf-viewer-page-nav ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | :: ### admin-pdf-viewer-zoom ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | :: ## 注意事項 - **不支援 SSR**:PDFium 引擎依賴 WebAssembly 與 Web Worker;元件殼不含 ``。Nuxt 請自行以 `` 包覆(可加 `#fallback` loading);純 CSR 不需處理。見 [安裝 · SSR](https://component-registry-4d4d86.gitlab.io/docs/get-started/installation#ssr-nuxt)。PDF 內容不會出現於 server-rendered HTML,無法 SEO。 - **首次掛載需下載 PDFium wasm**:載入時間視網路而定,預期延遲約數百毫秒到數秒;下載期間顯示既有 `admin-loading` 元件。 - **wasm 二進位來源**:PDF 解析使用 PDFium WebAssembly,預設由 EmbedPDF 官方 CDN 動態載入。若部署於離線環境、封閉內網,或資安政策禁止外部 CDN,需自行 host `.wasm` 檔並於 `usePdfiumEngine` 設定中指定來源(參數名請參考 EmbedPDF 文件)。 - **父容器需有明確寬度**:放大時 PDF 頁面可能比 viewer 寬,內部 viewport 自動水平捲動。若元件包在無寬度約束的 flex item(例如 `
`)內,PDF 寬度會推擠父容器;需在父 wrapper 加 `w-full` 或 `min-w-0` 確保 viewer 寬度受控。 ## 更新紀錄 :admin-changelog{component="AdminPdfViewer"} # Progress ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/progress ``` ```ts import { AdminProgress } from '@/components/admin/progress' ``` ## 用法 ```vue ``` ## 場景 ### 動態進度 以 interval 或事件來源更新 `model-value`,進度條會平滑過渡。 ```vue ``` ### 多項進度列表 ```vue ``` ### 不確定進度 當進度總量未知時,傳入 `model-value="null"` 進入 indeterminate 狀態:進度條顯示不確定動畫並隱藏百分比文字(此時 `show-value` 不生效)。待取得實際進度後再改回數值即可。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-progress ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------------- | ------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `modelValue` | `number | null | undefined` | `0` | The progress value. Can be bind as \`v-model\`.\
進度值。傳入 \`null\` 表示 indeterminate(進度未知),此時顯示不確定動畫並隱藏百分比文字。 | | `max` | `number | undefined` | — | The maximum progress value. | | `getValueLabel` | `((value: number | null | undefined, max: number) => string | undefined) | undefined` | — | A function to get the accessible label text in a human-readable format.\
If not provided, the value label will be read as the numeric value as a percentage of the max value. | | `getValueText` | `((value: number | null | undefined, max: number) => string | undefined) | undefined` | — | A function to get the accessible value text representing the current value in a human-readable format. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `showValue` | `boolean | undefined` | `true` | 設為 \`false\` 時隱藏中央百分比文字 | :: ## 更新紀錄 :admin-changelog{component="AdminProgress"} # Radio Group ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/radio-group ``` ```ts import { AdminRadioGroup, AdminRadioGroupItem, AdminRadioOption, } from '@/components/admin/radio-group' ``` ## 用法 ```vue ``` ## 場景 ### 多選項群組 ```vue ``` ### 停用狀態 ```vue ``` ## Type-safe 封裝 `AdminRadioGroup` 的 `modelValue` 為 reka-ui 的 `AcceptableValue`,選項則由呼叫端自行放置 `admin-radio-option`,兩者在 compile-time 不會對齊。 若需要讓 `v-model` 與選項 `value` 的 literal union 對齊,可自行封裝:傳入 `options`(建議加 `as const`),由封裝元件渲染 `admin-radio-option`。 範例: ```vue ``` ::alert{title="需開啟 strictVModel" type="info"} 型別檢查需開啟 `strictVModel`(若已開啟 `strictTemplates` 則已包含)。設定見 [Type-safe](https://component-registry-4d4d86.gitlab.io/docs/get-started/type-safe)。下列同時含合法綁定與刻意錯誤綁定;錯誤處以 `@vue-expect-error` 標示。 :: ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-radio-group ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `modelValue` | `AcceptableValue | undefined` | — | The controlled value of the radio item to check. Can be binded as \`v-model\`. | | `defaultValue` | `AcceptableValue | undefined` | — | The value of the radio item that should be checked when initially rendered.\
Use when you do not need to control the state of the radio items. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with radio items. | | `orientation` | `DataOrientation | undefined` | — | The orientation of the component. | | `dir` | `Direction | undefined` | — | The reading direction of the combobox when applicable. \
If omitted, inherits globally from \`ConfigProvider\` or assumes LTR (left-to-right) reading mode. | | `loop` | `boolean | undefined` | — | When \`true\`, keyboard navigation will loop from last item to first, and vice versa. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `name` | `string | undefined` | — | The name of the field. Submitted with its owning form as part of a name/value pair. | | `required` | `boolean | undefined` | — | When \`true\`, indicates that the user must set the value before the owning form can be submitted. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `isError` | `boolean | undefined` | — | 預留之錯誤狀態旗標(目前無對應視覺實作) | #### Events | 名稱 | Payload | 說明 | | ------------------- | ----------------- | -- | | `update:modelValue` | `AcceptableValue` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | ---------------------------------------------- | -- | | `default` | `{ modelValue: AcceptableValue | undefined; }` | — | :: ### admin-radio-group-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `id` | `string | undefined` | — | — | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `required` | `boolean | undefined` | — | When \`true\`, indicates that the user must set the value before the owning form can be submitted. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the radio item. | | `name` | `string | undefined` | — | The name of the field. Submitted with its owning form as part of a name/value pair. | | `value` | `AcceptableValue | undefined` | — | The value given as data when submitted with a \`name\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-radio-option ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `id` | `string | undefined` | — | — | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `required` | `boolean | undefined` | — | When \`true\`, indicates that the user must set the value before the owning form can be submitted. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the radio item. | | `name` | `string | undefined` | — | The name of the field. Submitted with its owning form as part of a name/value pair. | | `value` | `AcceptableValue | undefined` | — | The value given as data when submitted with a \`name\`. | | `label` | `string | undefined` | — | 顯示於選項旁之文字標籤;不設則不渲染 label | | `class` | `ClassValue` | — | 根元素之自訂 class | | `labelClass` | `ClassValue` | — | label 文字之自訂 class | :: ## 更新紀錄 :admin-changelog{component="AdminRadioGroup"} # Scroll Area ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/scroll-area ``` ```ts import { AdminScrollArea, AdminScrollBar } from '@/components/admin/scroll-area' ``` ## 用法 ```vue ``` ## 場景 ### 水平捲動 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-scroll-area ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------------- | ------------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `class` | `ClassValue` | — | 根元素之自訂 class | | `type` | `ScrollType | undefined` | — | Describes the nature of scrollbar visibility, similar to how the scrollbar preferences in MacOS control visibility of native scrollbars.\
\`auto\` - means that scrollbars are visible when content is overflowing on the corresponding orientation. \
\`always\` - means that scrollbars are always visible regardless of whether the content is overflowing.\
\`scroll\` - means that scrollbars are visible when the user is scrolling along its corresponding orientation.\
\`hover\` - when the user is scrolling along its corresponding orientation and when the user is hovering over the scroll area.\
\`glimpse\` - a hybrid approach that briefly shows scrollbars when the user enters the scroll area, then hides them until further interaction. | | `dir` | `Direction$2 | undefined` | — | The reading direction of the combobox when applicable. \
If omitted, inherits globally from \`ConfigProvider\` or assumes LTR (left-to-right) reading mode. | | `scrollHideDelay` | `number | undefined` | — | If type is set to either \`scroll\` or \`hover\`, this prop determines the length of time, in milliseconds, \
before the scrollbars are hidden after the user stops interacting with scrollbars. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-scroll-bar ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | ------------------------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `orientation` | `"horizontal" | "vertical" | undefined` | `"vertical"` | The orientation of the scrollbar | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ## 更新紀錄 :admin-changelog{component="AdminScrollArea"} # Select ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/select ``` ```ts import { AdminSelect, AdminSelectAnchor, AdminSelectCancel, AdminSelectCounter, AdminSelectEmpty, AdminSelectGroup, AdminSelectIcon, AdminSelectInput, AdminSelectItem, AdminSelectItemIndicator, AdminSelectList, AdminSelectSeparator, AdminSelectTags, AdminSelectTrigger, AdminSelectValue, AdminSelectViewport, } from '@/components/admin/select' ``` ## 用法 ```vue ``` ## 場景 ### 多選 ```vue ``` ### 可搜尋 ```vue ``` ### 錯誤狀態 ```vue ``` ### 完整組合 子元件:anchor、trigger(tags/value/counter/icon)、list、input(含 cancel)、viewport、empty、group(heading)、separator、item(含 item-indicator)。 ```vue ``` ## Type-safe 封裝 `AdminSelect` 已是 generic(`T extends AcceptableValue`),可直接以較嚴的 `v-model` 受益。若要讓 `v-model` 與選項清單的 literal union 對齊,可自行封裝:傳入 `options`(建議加 `as const`),由封裝元件以物件為 value 渲染 item,並以 `displayValue` 顯示 label。 封裝再以 `multiple` 為條件式泛型的 discriminant:`multiple` 時 `v-model` 型別收斂為選項陣列、未開時為單一選項,兩種模式共用同一個封裝元件。 範例: ```vue ``` ::alert{title="需開啟 strictVModel" type="info"} 型別檢查需開啟 `strictVModel`(若已開啟 `strictTemplates` 則已包含)。設定見 [Type-safe](https://component-registry-4d4d86.gitlab.io/docs/get-started/type-safe)。下列同時含合法綁定與刻意錯誤綁定;錯誤處以 `@vue-expect-error` 標示。 :: ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-select ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------------------- | -------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `class` | `unknown` | — | — | | `open` | `boolean | undefined` | — | The controlled open state of the Combobox. Can be binded with \`v-model\:open\`. | | `defaultOpen` | `boolean | undefined` | — | The open state of the combobox when it is initially rendered. \
Use when you do not need to control its open state. | | `resetSearchTermOnBlur` | `boolean | undefined` | `` `true` `` | Whether to reset the searchTerm when the Combobox input blurred | | `resetSearchTermOnSelect` | `boolean | undefined` | `` `true` `` | Whether to reset the searchTerm when the Combobox value is selected | | `openOnFocus` | `boolean | undefined` | `` `false` `` | Whether to open the combobox when the input is focused | | `openOnClick` | `boolean | undefined` | `` `false` `` | Whether to open the combobox when the input is clicked | | `ignoreFilter` | `boolean | undefined` | — | When \`true\`, disable the default filters | | `resetModelValueOnClear` | `boolean | undefined` | — | When \`true\` the \`modelValue\` will be reset to \`null\` (or \`\[]\` if \`multiple\`) | | `modelValue` | `TModelValue | TModelValue[] | undefined` | — | The controlled value of the listbox. Can be binded with \`v-model\`. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `required` | `boolean | undefined` | — | When \`true\`, indicates that the user must set the value before the owning form can be submitted. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with listbox | | `dir` | `Direction | undefined` | — | The reading direction of the listbox when applicable. \
If omitted, inherits globally from \`ConfigProvider\` or assumes LTR (left-to-right) reading mode. | | `defaultValue` | `TModelValue | TModelValue[] | undefined` | — | The value of the listbox when initially rendered. Use when you do not need to control the state of the Listbox | | `name` | `string | undefined` | — | The name of the field. Submitted with its owning form as part of a name/value pair. | | `multiple` | `boolean | undefined` | — | Whether multiple options can be selected or not. | | `highlightOnHover` | `boolean | undefined` | — | When \`true\`, hover over item will trigger highlight | | `by` | `string | ((a: TModelValue, b: TModelValue) => boolean) | undefined` | — | Use this to compare objects by a particular field, or pass your own comparison function for complete control over how objects are compared. | | `deselectable` | `boolean | undefined` | `true` | 已選中之選項是否可再次點擊取消選取 | | `isError` | `boolean | undefined` | `false` | 設為 \`true\` 時為 trigger 套用錯誤狀態邊框 | | `displayValue` | `((value: TModelValue) => string) | undefined` | — | 將已選 value 轉成 trigger/tags 顯示文案;未提供時 fallback 為 \`String(value)\` | #### Events | 名稱 | Payload | 說明 | | ------------------- | ------------------------------------------------------- | -- | | `update:modelValue` | `TModelValue` | — | | `update:open` | `boolean` | — | | `highlight` | `{ ref: HTMLElement; value: TModelValue; } | undefined` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | ------------------------------------------------------------- | -- | | `default` | `{ open: boolean; modelValue: TModelValue | TModelValue[]; }` | — | :: ### admin-select-anchor ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `reference` | `ReferenceElement | undefined` | — | The reference (or anchor) element that is being referred to for positioning.\
If not provided will use the current component as anchor. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-select-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with item | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-select-value ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | -------------------- | --- | ------------- | | `placeholder` | `string | undefined` | — | 未選取選項時顯示之提示文字 | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-select-icon ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-select-list ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------------------------- | ----------------------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `position` | `"inline" | "popper" | undefined` | `"popper"` | The positioning mode to use, \
\`inline\` is the default and you can control the position using CSS. \
\`popper\` positions content in the same way as our other primitives, for example \`Popover\` or \`DropdownMenu\`. | | `bodyLock` | `boolean | undefined` | — | The document.body will be lock, and scrolling will be disabled. | | `hideWhenEmpty` | `boolean | undefined` | `false` | When \`true\`, hides the content when there are no items matching the filter. | | `memoDependencies` | `unknown[] | undefined` | — | Reactive dependencies that should invalidate the memoized content subtree. | | `side` | `"top" | "right" | "bottom" | "left" | undefined` | `"bottom"` | The preferred side of the trigger to render against when open.\
Will be reversed when collisions occur and avoidCollisions\
is enabled. | | `sideOffset` | `number | undefined` | `4` | The distance in pixels from the trigger. | | `sideFlip` | `boolean | undefined` | `true` | Flip to the opposite side when colliding with boundary. | | `align` | `"start" | "end" | "center" | undefined` | `"start"` | The preferred alignment against the trigger.\
May change when collisions occur. | | `alignOffset` | `number | undefined` | `0` | An offset in pixels from the \`start\` or \`end\` alignment options. | | `alignFlip` | `boolean | undefined` | `true` | Flip alignment when colliding with boundary.\
May only occur when \`prioritizePosition\` is true. | | `avoidCollisions` | `boolean | undefined` | `true` | When \`true\`, overrides the side and align preferences\
to prevent collisions with boundary edges. | | `collisionBoundary` | `Element | (Element | null)[] | null | undefined` | `[]` | The element used as the collision boundary. By default\
this is the viewport, though you can provide additional\
element(s) to be included in this check. | | `collisionPadding` | `number | Partial> | undefined` | `0` | The distance in pixels from the boundary edges where collision\
detection should occur. Accepts a number (same for all sides),\
or a partial padding object, for example: { top: 20, left: 20 }. | | `arrowPadding` | `number | undefined` | `0` | The padding between the arrow and the edges of the content.\
If your content has border-radius, this will prevent it from\
overflowing the corners. | | `hideShiftedArrow` | `boolean | undefined` | `true` | When \`true\`, hides the arrow when it cannot be centered\
to the reference element. | | `sticky` | `"partial" | "always" | undefined` | `"partial"` | The sticky behavior on the align axis. \`partial\` will keep the\
content in the boundary as long as the trigger is at least partially\
in the boundary whilst "always" will keep the content in the boundary\
regardless. | | `hideWhenDetached` | `boolean | undefined` | `false` | Whether to hide the content when the trigger becomes fully occluded. | | `positionStrategy` | `"fixed" | "absolute" | undefined` | — | The type of CSS position property to use. | | `updatePositionStrategy` | `"always" | "optimized" | undefined` | `'optimized'` | Strategy to update the position of the floating element on every animation frame. | | `disableUpdateOnLayoutShift` | `boolean | undefined` | `false` | Whether to disable the update position for the content when the layout shifted. | | `prioritizePosition` | `boolean | undefined` | `false` | Force content to be position within the viewport.\
Might overlap the reference element, which may not be desired. | | `reference` | `ReferenceElement | undefined` | — | The custom element or virtual element that will be set as the reference\
to position the floating element.\
If provided, it will replace the default anchor element. | | `dir` | `Direction | undefined` | — | The reading direction of the popper content when applicable. \
If omitted, inherits globally from \`ConfigProvider\` or assumes LTR (left-to-right) reading mode. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `disableOutsidePointerEvents` | `boolean | undefined` | — | When \`true\`, hover/focus/click interactions will be disabled on elements outside\
the \`DismissableLayer\`. Users will need to click twice on outside elements to\
interact with them: once to close the \`DismissableLayer\`, and again to trigger the element. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `to` | `string | HTMLElement | undefined` | — | 指定 ComboboxPortal 之掛載目標 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-select-viewport ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `nonce` | `string | undefined` | — | Will add \`nonce\` attribute to the style tag which can be used by Content Security Policy. \
If omitted, inherits globally from \`ConfigProvider\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-select-input ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `displayValue` | `((val: any) => string) | undefined` | — | The display value of input for selected item. Does not work with \`multiple\`. | | `modelValue` | `string | undefined` | — | The controlled value of the filter. Can be binded with v-model. | | `autoFocus` | `boolean | undefined` | — | Focus on element when mounted. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with item | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `placeholder` | `string | undefined` | — | 搜尋輸入框之提示文字 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `icon` | `{}` | — | | `default` | `{}` | — | :: ### admin-select-cancel ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-select-empty ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-select-group ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `heading` | `string | undefined` | — | 群組標題;提供時於群組頂部渲染 ComboboxLabel | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-select-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------- | ------------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `textValue` | `string | undefined` | — | A string representation of the item contents.\
If the children are not plain text, then the \`textValue\` prop must also be set to a plain text representation, which will be used for autocomplete in the ComboBox. | | `value`\* | `AcceptableValue` | — | The value given as data when submitted with a \`name\`. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the item. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | *\\\* 代表必填* #### Events | 名稱 | Payload | 說明 | | -------- | -------------------------------- | -- | | `select` | `SelectEvent$3` | — | #### Slots | 名稱 | Bindings | 說明 | | ----------- | -------- | -- | | `default` | `{}` | — | | `indicator` | `{}` | — | :: ### admin-select-item-indicator ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-select-separator ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-select-tags ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------ | --- | ---------------- | | `class` | `ClassValue` | — | 根元素之自訂 class | | `tagClass` | `ClassValue` | — | 單一 tag 之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------------------------------------------------- | -- | | `default` | `{ option: AcceptableValue; remove: () => void; }` | — | :: ### admin-select-counter ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | -------------------- | ---- | ------------ | | `max` | `number | undefined` | `99` | 顯示計數之上限數字 | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ## 注意事項 - **trigger 需以 `` 包覆**:anchor 為 popper 定位錨點,list 的展開位置與寬度以 anchor 為參考;欲設定下拉寬度請把寬度 class 下在 `` 上。 - **搜尋輸入固定於 list 頂部**:`` 放在 `` 內、`` 之外時會固定不隨清單捲動;item 清單放入 `` 提供捲動。 - **物件 value 請設 `by`**:`v-model` 綁 option 物件時,建議 `by="value"`(或自訂比較函式),並以 `:display-value` 決定 trigger/tags 文案。 - **單選的 `deselectable`**:預設 `true`,再次點擊已選項目會清空選擇並關閉下拉;不需此行為時於 root 設 `deselectable=false`。 - **搜尋過濾的 label 來源**:過濾依據是每顆 `` 的 `textContent`;若 item 內嵌入 icon / 圖片等非文字節點,建議透過 `text-value` prop 顯式指定可被過濾的字串。 ## 更新紀錄 :admin-changelog{component="AdminSelect"} # Side Menu ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/side-menu ``` ```ts import { AdminSideMenu, AdminSideMenuContent, AdminSideMenuFooter, AdminSideMenuGroup, AdminSideMenuGroupAction, AdminSideMenuGroupContent, AdminSideMenuGroupLabel, AdminSideMenuHeader, AdminSideMenuInput, AdminSideMenuInset, AdminSideMenuList, AdminSideMenuListAction, AdminSideMenuListBadge, AdminSideMenuListButton, AdminSideMenuListButtonChild, AdminSideMenuListItem, AdminSideMenuListSkeleton, AdminSideMenuListSub, AdminSideMenuListSubButton, AdminSideMenuListSubItem, AdminSideMenuProvider, AdminSideMenuRail, AdminSideMenuSeparator, AdminSideMenuTrigger, useSideMenu, } from '@/components/admin/side-menu' ``` ## 用法 外層需先以 `admin-side-menu-provider` 提供 context,再以 `admin-side-menu` 結合 group / list / item / button 組合導覽結構。 ```vue ``` ## 場景 ### 基本結構 ```vue ``` ### 完整組成 header/footer/group-label/group-action/list-badge/list-action/separator/input/skeleton。 ```vue ``` ### 變體與收合 `variant`:`default`/`floating`/`inset`;`collapsible`:`icon`/`offcanvas`。以 `admin-side-menu-trigger` 或 `admin-side-menu-rail` 切換展開/收合。 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-side-menu ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | ---------------------------------------------- | ----------- | -------------------------------- | | `side` | `"right" | "left" | undefined` | `"left"` | 側選單對齊方向 | | `variant` | `"default" | "inset" | "floating" | undefined` | `"default"` | 視覺樣式變體 | | `collapsible` | `"none" | "icon" | "offcanvas" | undefined` | `"icon"` | 收合行為(offcanvas / icon / none 之一) | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | --------------------------------------------------------- | -- | | `default` | `{ isMobile: boolean; state: "expanded" | "collapsed"; }` | — | :: ### admin-side-menu-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------------------------------------- | -- | | `default` | `{ state: "expanded" | "collapsed"; }` | — | :: ### admin-side-menu-group ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-inset ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list-button ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `isActive` | `boolean | undefined` | `false` | 設為 \`true\` 時套用 active 狀態樣式 | | `class` | `ClassValue` | — | 根元素之自訂 class | | `tooltip` | `string | globalThis.Component | undefined` | — | 收合狀態(collapsed icon-only)時顯示之 tooltip 文字或元件 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list-button-child ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `isActive` | `boolean | undefined` | — | 設為 \`true\` 時套用 active 狀態樣式 | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list-sub ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list-sub-button ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"a"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `isActive` | `boolean | undefined` | — | 設為 \`true\` 時套用 active 狀態樣式 | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list-sub-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-provider ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | --------------------- | ------ | --------------------------------------------------------------------------------------------------- | | `defaultOpen` | `boolean | undefined` | `true` | uncontrolled 模式之初始開啟狀態 | | `open` | `boolean | undefined` | — | controlled 模式之開啟狀態(以 \`v-model\:open\` 綁定) | | `mobileSheet` | `boolean | undefined` | `true` | 手機(\`< 768px\`)是否以 Sheet 渲染;設為 \`false\` 時關閉手機 Sheet,所有 variant/collapsible 在全寬度維持電腦版樣式,預設 \`true\` | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Events | 名稱 | Payload | 說明 | | ------------- | --------- | --------- | | `update:open` | `boolean` | 開啟狀態變更時觸發 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-rail ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-header ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-footer ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-group-label ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-group-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-group-action ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list-action ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | ------------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"button"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `showOnHover` | `boolean | undefined` | `false` | 設為 \`true\` 時僅在項目 hover / focus / 開啟狀態顯示 | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-list-badge ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-side-menu-input ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-side-menu-separator ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | ------------ | --- | ------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ### admin-side-menu-list-skeleton ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | --------------------- | ------- | ------------------------------------- | | `showIcon` | `boolean | undefined` | `false` | 是否顯示前置 icon 佔位 | | `width` | `string | undefined` | `"70%"` | 文字佔位寬度(固定值,避免 SSR hydration mismatch) | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ## 更新紀錄 :admin-changelog{component="AdminSideMenu"} # Stepper ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/stepper ``` ```ts import { AdminStepper, AdminStepperDescription, AdminStepperIndicator, AdminStepperItem, AdminStepperSeparator, AdminStepperTitle, AdminStepperTrigger, } from '@/components/admin/stepper' ``` ## 用法 ```vue ``` ## 場景 ### 線性三步驟 ```vue ``` ### 停用尚未開放的步驟 ```vue ``` ### 步驟附說明文字 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-stepper ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------- | ------------------------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `defaultValue` | `number | undefined` | — | The value of the step that should be active when initially rendered. Use when you do not need to control the state of the steps. | | `orientation` | `DataOrientation | undefined` | `horizontal` | The orientation the steps are laid out.\
Mainly so arrow navigation is done accordingly (left & right vs. up & down). | | `dir` | `Direction | undefined` | — | The reading direction of the combobox when applicable. \
If omitted, inherits globally from \`ConfigProvider\` or assumes LTR (left-to-right) reading mode. | | `modelValue` | `number | undefined` | — | The controlled value of the step to activate. Can be bound as \`v-model\`. | | `linear` | `boolean | undefined` | — | Whether or not the steps must be completed in order. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Events | 名稱 | Payload | 說明 | | ------------------- | -------------------- | -- | | `update:modelValue` | `number | undefined` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-stepper-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ----------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `step`\* | `number` | — | A unique value that associates the stepper item with an index | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the step. | | `completed` | `boolean | undefined` | — | Shows whether the step is completed. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | *\\\* 代表必填* #### Slots | 名稱 | Bindings | 說明 | | --------- | -------------------------- | -- | | `default` | `{ state: StepperState; }` | — | :: ### admin-stepper-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-stepper-indicator ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | ------------------- | -- | | `default` | `{ step: number; }` | — | :: ### admin-stepper-title ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-stepper-description ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-stepper-separator ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `orientation` | `DataOrientation | undefined` | — | Orientation of the component.\
Either \`vertical\` or \`horizontal\`. Defaults to \`horizontal\`. | | `decorative` | `boolean | undefined` | — | Whether or not the component is purely decorative. \
When \`true\`, accessibility-related attributes\
are updated so that that the rendered element is removed from the accessibility tree. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | :: ## 更新紀錄 :admin-changelog{component="AdminStepper"} # Switch ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/switch ``` ```ts import { AdminSwitch } from '@/components/admin/switch' ``` ## 用法 ```vue ``` ## 場景 ### 帶文字標籤 ```vue ``` ### 停用狀態 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-switch ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `defaultValue` | `boolean | undefined` | — | The state of the switch when it is initially rendered. Use when you do not need to control its state. | | `modelValue` | `boolean | null | undefined` | — | The controlled state of the switch. Can be bind as \`v-model\`. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the switch. | | `id` | `string | undefined` | — | — | | `value` | `string | undefined` | — | The value given as data when submitted with a \`name\`. | | `trueValue` | `boolean | undefined` | — | The value used when the switch is on. Defaults to \`true\`. | | `falseValue` | `boolean | undefined` | — | The value used when the switch is off. Defaults to \`false\`. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `name` | `string | undefined` | — | The name of the field. Submitted with its owning form as part of a name/value pair. | | `required` | `boolean | undefined` | — | When \`true\`, indicates that the user must set the value before the owning form can be submitted. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `checkedText` | `string | undefined` | — | 開啟狀態顯示的文字(亦可用 \`#checkedText\` slot) | | `uncheckedText` | `string | undefined` | — | 關閉狀態顯示的文字(亦可用 \`#uncheckedText\` slot) | | `isError` | `boolean | undefined` | — | 設為 \`true\` 時套用錯誤狀態樣式(顯示 \`data-is-error\` 屬性供樣式 hook) | #### Events | 名稱 | Payload | 說明 | | ------------------- | --------- | -- | | `update:modelValue` | `boolean` | — | #### Slots | 名稱 | Bindings | 說明 | | --------------- | -------------------------- | --------------------------------------- | | `checkedText` | `any` | 自訂開啟狀態文字內容(取代 \`checkedText\` prop) | | `uncheckedText` | `any` | 自訂關閉狀態文字內容(取代 \`uncheckedText\` prop) | | `thumb` | `{ modelValue: boolean; }` | 自訂 thumb 內容,bindings 含當前 \`modelValue\` | :: ## 更新紀錄 :admin-changelog{component="AdminSwitch"} # Tabs ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/tabs ``` ```ts import { AdminTabs, AdminTabsContent, AdminTabsList, AdminTabsTrigger, } from '@/components/admin/tabs' ``` ## 用法 ```vue ``` ## 場景 ### 受控模式 ```vue ``` ## Type-safe 封裝 `AdminTabs` 已是 generic(`T extends StringOrNumber`),以較嚴的 ref 綁定 `v-model` 即可收斂為 tab value 的 literal union。若要讓 value 與清單對齊、並讓每個 tab 的內容仍保有完整彈性,可自行封裝:傳入 `items`(建議加 `as const`),由封裝元件以 `items` 為單一事實來源渲染各 trigger 與 content shell,content 由使用端以 `#panel-` 具名 slot 填入。 如此 `items` 即聯集來源,各 trigger 的 `value` 結構上不可能越界;型別安全落在 `v-model` 與 `defaultValue` 必須對齊 `items` 的 value union(允許 `undefined` 表未選)。封裝再以 `defineSlots` 將 content slot 收斂為 `panel-` 聯集,填入不在清單內的 slot 名亦會編譯期報錯。 > 此食譜刻意精簡,未透出 trigger 的 `badge`/`badgeValue`;需要時可自行 fork 擴充。封裝元件僅為文件示範,不屬 registry 安裝產物。 ```vue ``` ::alert{title="需開啟 strictVModel" type="info"} 型別檢查需開啟 `strictVModel`(若已開啟 `strictTemplates` 則已包含)。設定見 [Type-safe](https://component-registry-4d4d86.gitlab.io/docs/get-started/type-safe)。下列同時含合法綁定與刻意錯誤綁定;錯誤處以 `@vue-expect-error` 標示。 :: ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-tabs ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------------- | ------------------------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `class` | `ClassValue` | — | 根元素之自訂 class | | `defaultValue` | `TModelValue | undefined` | — | The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs | | `orientation` | `DataOrientation | undefined` | `horizontal` | The orientation the tabs are laid out.\
Mainly so arrow navigation is done accordingly (left & right vs. up & down) | | `dir` | `Direction | undefined` | — | The reading direction of the combobox when applicable. \
If omitted, inherits globally from \`ConfigProvider\` or assumes LTR (left-to-right) reading mode. | | `activationMode` | `"automatic" | "manual" | undefined` | `automatic` | Whether a tab is activated automatically (on focus) or manually (on click). | | `modelValue` | `TModelValue | undefined` | — | The controlled value of the tab to activate. Can be bind as \`v-model\`. | | `unmountOnHide` | `boolean | undefined` | `` `true` `` | When \`true\`, the element will be unmounted on closed state. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `size` | `"xs" | "sm" | undefined` | `"xs"` | tabs trigger 尺寸(透過 context 傳遞給所有 trigger) | #### Events | 名稱 | Payload | 說明 | | ------------------- | ------------- | -- | | `update:modelValue` | `TModelValue` | — | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-tabs-list ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | --------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `loop` | `boolean | undefined` | — | When \`true\`, keyboard navigation will loop from last tab to first, and vice versa. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-tabs-trigger ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `value`\* | `StringOrNumber` | — | A unique value that associates the trigger with a content. | | `disabled` | `boolean | undefined` | — | When \`true\`, prevents the user from interacting with the tab. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | | `badge` | `boolean | undefined` | `false` | 設為 \`true\` 時於 trigger 右側顯示 badge | | `badgeValue` | `number | undefined` | — | badge 顯示的數字(搭配 \`badge: true\` 使用) | *\\\* 代表必填* #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-tabs-content ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------ | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `value`\* | `StringOrNumber` | — | A unique value that associates the content with a trigger. | | `forceMount` | `boolean | undefined` | — | Used to force mounting when more control is needed. Useful when\
controlling animation with Vue animation libraries. | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"div"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `class` | `ClassValue` | — | 根元素之自訂 class | *\\\* 代表必填* #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminTabs"} # Tag ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/tag ``` ```ts import { AdminTag } from '@/components/admin/tag' ``` ## 用法 ```vue ``` ## 場景 ### 圓角變體 ```vue ``` ### 搭配 icon ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-tag ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ---------------------------------------------- | --- | --------------------- | | `class` | `ClassValue` | — | 根元素之自訂 class | | `rounded` | `"round-filled" | "square-filled" | undefined` | — | 圓角樣式變體 | | `closable` | `boolean | undefined` | — | 設為 \`true\` 時顯示右側關閉按鈕 | #### Events | 名稱 | Payload | 說明 | | ------- | ------- | ----------- | | `close` | — | 點擊右側關閉按鈕時觸發 | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ## 更新紀錄 :admin-changelog{component="AdminTag"} # Textarea ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/textarea ``` ```ts import { AdminTextarea, AdminTextareaWordLimit, } from '@/components/admin/textarea' ``` ## 用法 ```vue ``` ## 場景 ### 帶字數限制 ```vue ``` ### 停用狀態 ```vue ``` ### 錯誤狀態 ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-textarea ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------------- | --------------------- | ------- | ---------------------------------------------- | | `defaultValue` | `string | undefined` | — | 初始值(非控制模式) | | `modelValue` | `string | undefined` | — | 受控值,以 \`v-model\` 綁定 | | `placeholder` | `string | undefined` | — | 預設提示文字 | | `disabled` | `boolean | undefined` | — | 設為 \`true\` 時禁用輸入並套用視覺停用樣式 | | `maxlength` | `number | undefined` | — | 限制最大字元數(並由 \`admin-textarea-word-limit\` 顯示計數) | | `class` | `ClassValue` | — | 根元素之自訂 class | | `isError` | `boolean | undefined` | `false` | 設為 \`true\` 時套用錯誤狀態樣式與 \`aria-invalid\` | | `id` | `string | undefined` | — | 透傳至內層 \`textarea\` 之 \`id\`;純透傳,未提供時不自動生成 | | `name` | `string | undefined` | — | 透傳至內層 \`textarea\` 之 \`name\`,供原生表單提交使用 | #### Events | 名稱 | Payload | 說明 | | ------------------- | ------------ | ---------------------------------------------------- | | `blur` | `FocusEvent` | 內層 \`textarea\` 失焦時轉發之原生事件 | | `change` | `Event` | 內層 \`textarea\` 觸發原生 \`change\`(值變更並 commit)時轉發之原生事件 | | `input` | `Event` | 內層 \`textarea\` 觸發原生 \`input\`(每次輸入)時轉發之原生事件 | | `update:modelValue` | `string` | — | #### Slots | 名稱 | Bindings | 說明 | | -------- | -------- | -- | | `footer` | `{}` | — | #### Expose | 名稱 | 簽名 | 說明 | | ------------- | ---------------------------- | --------------------------------------------------------------- | | `textareaRef` | `HTMLTextAreaElement | null` | 內部原生 textarea 元素之 template ref,可用於程式化 focus / blur / select 等操作 | :: ### admin-textarea-word-limit ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------- | --------- | --- | -- | | `class` | `unknown` | — | — | :: ## 更新紀錄 :admin-changelog{component="AdminTextarea"} # Timeline ## 安裝 ```bash [Terminal] icon=i-lucide-terminal pnpm dlx shadcn-vue add @admin/timeline ``` ```ts import { AdminTimeline, AdminTimelineContent, AdminTimelineDate, AdminTimelineHeader, AdminTimelineIndicator, AdminTimelineItem, AdminTimelineSeparator, AdminTimelineTitle, } from '@/components/admin/timeline' ``` ## 用法 ```vue ``` ## 場景 ### 自訂 indicator(icon) ```vue ``` ### 水平 orientation ```vue ``` ## API 參考 ### 組成 ```vue ``` ### admin-timeline ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ------------- | --------------------------------- | ------------ | ------------ | | `orientation` | `TimelineOrientation | undefined` | `"vertical"` | 時間軸方向 | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-timeline-item ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | -------- | -------------------------------- | ----------- | --------------------------------------- | | `status` | `TimelineItemStatus | undefined` | `"pending"` | 該 item 的狀態;決定 indicator 與 separator 的配色 | | `class` | `ClassValue` | — | 根元素之自訂 class | #### Slots | 名稱 | Bindings | 說明 | | --------- | -------- | -- | | `default` | `{}` | — | :: ### admin-timeline-date ::div{data-admin-api-table=""} #### Props | 名稱 | 型別 | 預設值 | 說明 | | ---------- | ------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `asChild` | `boolean | undefined` | — | Change the default rendered element for the one passed as a child, merging their props and behavior.\
Read our \[Composition]\(https\://www\.reka-ui.com/docs/guides/composition) guide for more details. | | `as` | `globalThis.Component | AsTag | undefined` | `"time"` | The element or component this component should render as. Can be overwritten by \`asChild\`. | | `datetime` | `string | undefined` | — | 對應 \`\