Initial commit: Add project files
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import type { Component, InjectionKey } from 'vue'
|
||||
|
||||
export type UiSeverity = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'danger'
|
||||
export type UiButtonType = 'button' | 'submit' | 'reset'
|
||||
export type UiAdapterId = 'primevue-aggrid' | 'native-accessible'
|
||||
export type UiAdapterContractVersion = '4.0'
|
||||
export type UiAdapterCapability =
|
||||
| 'button'
|
||||
| 'text-field'
|
||||
| 'text-area'
|
||||
| 'select'
|
||||
| 'multi-select'
|
||||
| 'checkbox'
|
||||
| 'date-field'
|
||||
| 'number-field'
|
||||
| 'dialog'
|
||||
| 'status-tag'
|
||||
| 'inline-message'
|
||||
| 'paginator'
|
||||
| 'tabs'
|
||||
| 'data-grid'
|
||||
|
||||
export interface UiSelectOption {
|
||||
label: string
|
||||
value: string | number | boolean | null
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
export interface UiTabItem {
|
||||
id: string
|
||||
label: string
|
||||
disabled?: boolean
|
||||
badge?: string | number
|
||||
}
|
||||
|
||||
export type UiGridSortDirection = 'asc' | 'desc'
|
||||
export interface UiGridSort { field: string; direction: UiGridSortDirection }
|
||||
export interface UiGridFilter { field: string; operator: string; value: unknown }
|
||||
export interface UiGridQuery {
|
||||
page: number
|
||||
pageSize: number
|
||||
sorts: UiGridSort[]
|
||||
filters: UiGridFilter[]
|
||||
search?: string
|
||||
}
|
||||
|
||||
export interface UiGridColumn {
|
||||
field: string
|
||||
header: string
|
||||
width?: number
|
||||
minWidth?: number
|
||||
sortable?: boolean
|
||||
filterable?: boolean
|
||||
sensitive?: boolean
|
||||
formatter?: (value: unknown, row: unknown) => string
|
||||
}
|
||||
|
||||
export interface UiAdapterDescriptor {
|
||||
readonly id: UiAdapterId
|
||||
readonly version: string
|
||||
readonly contractVersion: UiAdapterContractVersion
|
||||
readonly vendor: string
|
||||
readonly capabilities: ReadonlySet<UiAdapterCapability>
|
||||
readonly productionEligible: boolean
|
||||
readonly accessibilityBaseline: 'WCAG_2_2_AA_TARGET'
|
||||
}
|
||||
|
||||
export interface UiAdapter {
|
||||
readonly descriptor: UiAdapterDescriptor
|
||||
readonly components: {
|
||||
Button: Component
|
||||
TextField: Component
|
||||
TextArea: Component
|
||||
Select: Component
|
||||
MultiSelect: Component
|
||||
Checkbox: Component
|
||||
DateField: Component
|
||||
NumberField: Component
|
||||
Dialog: Component
|
||||
StatusTag: Component
|
||||
InlineMessage: Component
|
||||
Paginator: Component
|
||||
Tabs: Component
|
||||
DataGrid: Component
|
||||
}
|
||||
}
|
||||
|
||||
export const requiredUiAdapterCapabilities: readonly UiAdapterCapability[] = Object.freeze([
|
||||
'button', 'text-field', 'text-area', 'select', 'multi-select', 'checkbox', 'date-field',
|
||||
'number-field', 'dialog', 'status-tag', 'inline-message', 'paginator', 'tabs', 'data-grid'
|
||||
])
|
||||
|
||||
export function assertUiAdapterContract(adapter: UiAdapter): void {
|
||||
if (adapter.descriptor.contractVersion !== '4.0') {
|
||||
throw new Error(`Unsupported UI adapter contract: ${adapter.descriptor.contractVersion}`)
|
||||
}
|
||||
const missing = requiredUiAdapterCapabilities.filter(x => !adapter.descriptor.capabilities.has(x))
|
||||
if (missing.length > 0) {
|
||||
throw new Error(`UI adapter ${adapter.descriptor.id} is missing capabilities: ${missing.join(', ')}`)
|
||||
}
|
||||
const componentNames = [
|
||||
'Button', 'TextField', 'TextArea', 'Select', 'MultiSelect', 'Checkbox', 'DateField',
|
||||
'NumberField', 'Dialog', 'StatusTag', 'InlineMessage', 'Paginator', 'Tabs', 'DataGrid'
|
||||
] as const
|
||||
for (const name of componentNames) {
|
||||
if (!adapter.components[name]) throw new Error(`UI adapter ${adapter.descriptor.id} has no component for ${name}`)
|
||||
}
|
||||
}
|
||||
|
||||
export const uiAdapterKey: InjectionKey<UiAdapter> = Symbol('KArtSellUiAdapterV4')
|
||||
Reference in New Issue
Block a user