refactor(ui): better with types

This commit is contained in:
Neko Ayaka
2026-07-22 02:59:43 +08:00
parent f2313e0070
commit 5228f94123
14 changed files with 475 additions and 139 deletions
@@ -1,6 +1,8 @@
<script setup lang="ts" generic="T extends AcceptableValue">
import type { AcceptableValue } from 'reka-ui'
import type { ComboboxOptionGroupItem, ComboboxOptionItem } from './types'
import {
ComboboxAnchor,
ComboboxContent,
@@ -18,19 +20,6 @@ import {
} from 'reka-ui'
import { computed } from 'vue'
interface ComboboxOptionItem<T extends AcceptableValue> {
label: string
value: T
description?: string
disabled?: boolean
icon?: string
}
interface ComboboxOptionGroupItem<T extends AcceptableValue> {
groupLabel?: string
children?: ComboboxOptionItem<T>[]
}
const props = withDefaults(defineProps<{
options: ComboboxOptionItem<T>[] | ComboboxOptionGroupItem<T>[]
placeholder?: string
@@ -1 +1,2 @@
export { default as Combobox } from './combobox.vue'
export type { ComboboxOptionGroupItem, ComboboxOptionItem } from './types'
@@ -0,0 +1,31 @@
import type { AcceptableValue } from 'reka-ui'
/**
* Option rendered by {@link Combobox}.
*
* @param T Value type accepted by the underlying Reka combobox item.
*/
export interface ComboboxOptionItem<T extends AcceptableValue> {
/** User-visible label shown in the input and option row. */
label: string
/** Value passed through `v-model` when this option is selected. */
value: T
/** Optional secondary text shown below the label. */
description?: string
/** Prevents the option from being selected when true. */
disabled?: boolean
/** Iconify class name rendered before the label. */
icon?: string
}
/**
* Option group accepted by {@link Combobox}.
*
* @param T Value type shared by the group's child options.
*/
export interface ComboboxOptionGroupItem<T extends AcceptableValue> {
/** Optional group heading rendered above child options. */
groupLabel?: string
/** Options rendered within this group. */
children?: ComboboxOptionItem<T>[]
}
@@ -1,21 +1,10 @@
<script setup lang="ts" generic="T extends AcceptableValue">
import type { AcceptableValue } from 'reka-ui'
import type { SelectOptionGroupItem, SelectOptionItem } from '../select'
import { Select } from '../select'
interface SelectOptionItem<T extends AcceptableValue> {
label: string
value: T
description?: string
disabled?: boolean
icon?: string
}
interface SelectOptionGroupItem<T extends AcceptableValue> {
groupLabel?: string
children?: SelectOptionItem<T>[]
}
const props = withDefaults(defineProps<{
label: string
description?: string
@@ -1 +1,2 @@
export { default as SelectTab } from './select-tab.vue'
export type { SelectTabOption } from './types'
@@ -1,16 +1,11 @@
<script setup lang="ts" generic="T extends string | number">
import type { SelectTabOption } from './types'
import { RadioGroupItem, RadioGroupRoot } from 'reka-ui'
import { computed } from 'vue'
interface SelectTabOption {
label: string
value: T
description?: string
icon?: string
}
const props = withDefaults(defineProps<{
options: SelectTabOption[]
options: SelectTabOption<T>[]
disabled?: boolean
readonly?: boolean
size?: 'xs' | 'sm' | 'md' | 'w-xs' | 'w-sm' | 'w-md'
@@ -0,0 +1,15 @@
/**
* Option rendered by {@link SelectTab}.
*
* @param T String or number value emitted through the tab group's `v-model`.
*/
export interface SelectTabOption<T extends string | number> {
/** User-visible tab label. */
label: string
/** Value passed through `v-model` when this tab is selected. */
value: T
/** Optional secondary text reserved for consumers that render richer tab content. */
description?: string
/** Iconify class name rendered before the label. */
icon?: string
}
@@ -1,2 +1,3 @@
export { default as SelectOption } from './select-option.vue'
export { default as Select } from './select.vue'
export type { SelectOptionGroupItem, SelectOptionItem } from './types'
@@ -1,20 +1,14 @@
<script setup lang="ts" generic="T extends AcceptableValue">
import type { AcceptableValue } from 'reka-ui'
import type { SelectOptionItem } from './types'
import {
SelectItem,
SelectItemIndicator,
SelectItemText,
} from 'reka-ui'
interface SelectOptionItem<T extends AcceptableValue> {
label: string
value: T
description?: string
disabled?: boolean
icon?: string
}
const props = defineProps<{
option: SelectOptionItem<T>
}>()
@@ -1,6 +1,8 @@
<script setup lang="ts" generic="T extends AcceptableValue">
import type { AcceptableValue } from 'reka-ui'
import type { SelectOptionGroupItem, SelectOptionItem } from './types'
import {
SelectArrow,
SelectContent,
@@ -18,19 +20,6 @@ import { computed } from 'vue'
import SelectOption from './select-option.vue'
interface SelectOptionItem<T extends AcceptableValue> {
label: string
value: T
description?: string
disabled?: boolean
icon?: string
}
interface SelectOptionGroupItem<T extends AcceptableValue> {
groupLabel?: string
children?: SelectOptionItem<T>[]
}
const props = withDefaults(defineProps<{
options: SelectOptionItem<T>[] | SelectOptionGroupItem<T>[]
placeholder?: string
@@ -0,0 +1,31 @@
import type { AcceptableValue } from 'reka-ui'
/**
* Option rendered by {@link Select} and {@link SelectOption}.
*
* @param T Value type accepted by the underlying Reka select item.
*/
export interface SelectOptionItem<T extends AcceptableValue> {
/** User-visible label shown in the trigger and option row. */
label: string
/** Value passed through `v-model` when this option is selected. */
value: T
/** Optional secondary text shown below the label. */
description?: string
/** Prevents the option from being selected when true. */
disabled?: boolean
/** Iconify class name rendered before the label. */
icon?: string
}
/**
* Option group accepted by {@link Select}.
*
* @param T Value type shared by the group's child options.
*/
export interface SelectOptionGroupItem<T extends AcceptableValue> {
/** Optional group heading rendered above child options. */
groupLabel?: string
/** Options rendered within this group. */
children?: SelectOptionItem<T>[]
}
+1
View File
@@ -4,3 +4,4 @@
*/
@import './fallback.css';
@import './lamp-flicker.css';
@import './style.css';
+9
View File
@@ -0,0 +1,9 @@
/*
* NOTICE:
* This file is a source-time placeholder for @proj-airi/ui/style.css.
* The production build writes the real generated UnoCSS output to dist/style.css.
* Docs dev aliases @proj-airi/ui to packages/ui/src, so package CSS imports need this
* file to resolve before build output exists.
* Remove this file only if docs dev no longer aliases @proj-airi/ui to source or if
* @proj-airi/ui ships a real source CSS entry.
*/
+374 -84
View File
File diff suppressed because it is too large Load Diff