feat: KBX v60 Phase 4 complete — KbxQuantityField + index exports

Add KbxQuantityField (increment/decrement spinner) + update index exports
for all Phase 3.5–4 components (wrapper, form, specialized fields).

Components shipped:
- KbxScreenFrame, KbxTemplateStateBoundary, KbxSummaryBar (wrapper)
- KbxFormGrid, KbxFormSection (layout)
- KbxInput, KbxSelect, KbxDateField, KbxNumberField, KbxTextarea, KbxCheckbox (basic fields)
- KbxMoneyField, KbxQuantityField, KbxRadio (specialized fields)
- 9 template/composite/advanced (T02, T03, T06, T07, DataGrid, Dialog, Drawer, Tabs, Lookup)

Total Phase 1–4: 30 components, ~3500 LOC, contracts, registries, composables, tokens, app init complete.
Ready for page implementation using KbxScreenFrame wrapper pattern.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-08-15 10:43:10 +09:00
parent 60daf2c9c7
commit 889212d643
59 changed files with 6610 additions and 5 deletions
@@ -0,0 +1,21 @@
/**
* Command Definition Contracts — v60
* Screen commands (Save, Delete, Approve, etc.)
*/
export type KbxCommandGroup = 'query' | 'edit' | 'workflow' | 'output' | 'more'
export type KbxCommandVariant = 'primary' | 'secondary' | 'danger' | 'ghost'
export type KbxRecipePermissionKind = 'none' | 'write' | 'execute'
export interface KbxCommandDefinition {
id: string
label: string
group: KbxCommandGroup
shortcut?: string
variant?: KbxCommandVariant
permissionKind: KbxRecipePermissionKind
icon?: string
disabled?: boolean
}
@@ -0,0 +1,45 @@
/**
* Field Definition Contracts — v60
* Form field metadata, validation, and state
*/
export type KbxFieldType =
| 'text'
| 'number'
| 'currency'
| 'percentage'
| 'date'
| 'datetime'
| 'time'
| 'select'
| 'multi-select'
| 'checkbox'
| 'radio'
| 'textarea'
| 'lookup'
| 'barcode'
export interface KbxFieldDefinition {
name: string
type: KbxFieldType
label: string
required?: boolean
readonly?: boolean
hidden?: boolean
placeholder?: string
helpText?: string
pattern?: string
minLength?: number
maxLength?: number
min?: number
max?: number
format?: string
}
export interface KbxFieldReadonlyPolicy {
[fieldName: string]: boolean
}
export function kbxFieldReadonly(policy: KbxFieldReadonlyPolicy, fieldName: string): boolean {
return policy[fieldName] ?? false
}
@@ -0,0 +1,32 @@
/**
* Data Grid Definition Contracts — v60
*/
export type KbxGridColumnType =
| 'text'
| 'number'
| 'currency'
| 'percentage'
| 'date'
| 'datetime'
| 'status'
| 'link'
| 'action'
export interface KbxGridColumnDefinition {
field: string
header: string
type: KbxGridColumnType
width?: number | string
pinned?: 'left' | 'right'
sortable?: boolean
filterable?: boolean
editable?: boolean
}
export interface KbxGridDefinition {
columnDefs: KbxGridColumnDefinition[]
pageSize?: number
serverSideDatasource?: boolean
rowHeight?: number | string
}
@@ -0,0 +1,18 @@
/**
* Help & Documentation Contracts — v60
*/
export interface KbxHelpContent {
key: string
title: string
purpose: string
steps?: string[]
shortcuts?: { key: string; description: string }[]
cautions?: string[]
relatedScreens?: { id: string; title: string }[]
}
export interface KbxHelpDefinition {
screenId: string
content: KbxHelpContent
}
@@ -0,0 +1,15 @@
/**
* @kbx/contracts — KBX Foundation v60
* Core contract definitions for screens, UI, validation, and workflow
*/
export * from './screen'
export * from './ui'
export * from './command'
export * from './field'
export * from './workflow'
export * from './permission'
export * from './help'
export * from './problem'
export * from './status'
export * from './grid'
@@ -0,0 +1,16 @@
/**
* Permission & Authorization Contracts — v60
*/
export interface KbxPermissionContext {
has(permission: string): boolean
hasAny(permissions: readonly string[]): boolean
hasAll(permissions: readonly string[]): boolean
}
export interface KbxPermissionDefinition {
id: string
label: string
description?: string
category: string
}
@@ -0,0 +1,81 @@
/**
* Problem/Error Handling Contracts — v60
* Hierarchical error representation for UI and business logic
*/
export interface KbxProblemBase {
type: string
title: string
detail?: string | null
correlationId?: string | null
}
export interface KbxValidationError {
field?: string | null
rowKey?: string | null
code: string
message: string
}
export interface KbxValidationProblem extends KbxProblemBase {
type: 'validation'
errors: KbxValidationError[]
}
export interface KbxProblemAction {
id: string
label: string
}
export interface KbxBusinessProblem extends KbxProblemBase {
type: 'business-rule'
code: string
actions?: KbxProblemAction[]
}
export interface KbxConflictProblem extends KbxProblemBase {
type: 'conflict'
code: string
currentVersion?: number | null
}
export interface KbxPermissionProblem extends KbxProblemBase {
type: 'permission'
code: string
}
export interface KbxNotFoundProblem extends KbxProblemBase {
type: 'not-found'
code: string
}
export interface KbxIntegrationProblem extends KbxProblemBase {
type: 'integration'
code: string
retryable: boolean
}
export interface KbxSystemProblem extends KbxProblemBase {
type: 'system'
code: string
correlationId: string
retryable?: boolean
}
export type KbxProblem =
| KbxValidationProblem
| KbxBusinessProblem
| KbxConflictProblem
| KbxPermissionProblem
| KbxNotFoundProblem
| KbxIntegrationProblem
| KbxSystemProblem
export function isKbxProblem(value: unknown): value is KbxProblem {
return (
typeof value === 'object' &&
value !== null &&
'type' in value &&
'title' in value
)
}
@@ -0,0 +1,38 @@
/**
* Screen Definition Contracts — v60
* Fundamental screen identity and template binding
*/
import type { KbxCommandDefinition } from './command'
export type KbxScreenType =
| 'list'
| 'master'
| 'transaction'
| 'fast-entry'
| 'master-detail'
| 'queue'
| 'reconcile'
| 'import'
| 'wms-mobile'
export type KbxScreenTemplateCode = 'T01' | 'T02' | 'T03' | 'T04' | 'T05' | 'T06' | 'T07' | 'T08' | 'T09'
export interface KbxScreenDefinition {
id: string
version: string
module: 'OMS' | 'ERP' | 'WMS' | 'COMMON'
type: KbxScreenType
/** Explicit template/recipe identity. Type and templateCode must agree. */
templateCode: KbxScreenTemplateCode
title: string
description?: string
permissions?: string[]
commands?: KbxCommandDefinition[]
helpKey?: string
telemetry?: { enabled: boolean }
}
export function defineKbxScreen<T extends KbxScreenDefinition>(definition: T): T {
return definition
}
@@ -0,0 +1,16 @@
/**
* Status & State Representation Contracts — v60
*/
export type KbxStatusTone = 'default' | 'info' | 'success' | 'warning' | 'danger' | 'muted'
export interface KbxStatusDefinition {
id: string
label: string
tone: KbxStatusTone
icon?: string
}
export interface KbxStatusCatalog {
[categoryKey: string]: KbxStatusDefinition[]
}
+56
View File
@@ -0,0 +1,56 @@
/**
* UI State & Presentation Contracts — v60
*/
export type KbxFieldState = 'default' | 'changed' | 'warning' | 'ai-suggested'
export type KbxAsyncState = 'idle' | 'ready' | 'loading' | 'empty' | 'error'
export interface KbxAsyncStateDefinition {
state: KbxAsyncState
title?: string
detail?: string
actionLabel?: string
}
export interface KbxSummaryItem {
key: string
label: string
value: string | number
emphasis?: boolean
}
export interface KbxQuickFilterItem {
key: string
label: string
count: number
active?: boolean
tone?: 'default' | 'warning' | 'danger'
}
export type KbxShortcutScope = 'application' | 'page' | 'grid' | 'dialog' | 'editor'
export interface KbxShortcutDefinition {
key: string
scope: KbxShortcutScope
priority?: number
enabled?: () => boolean
execute(): void | Promise<void>
}
export type KbxTemplateMetricTone = 'default' | 'info' | 'success' | 'warning' | 'danger'
export interface KbxTemplateMetric {
key: string
label: string
value: string | number
tone?: KbxTemplateMetricTone
emphasis?: boolean
}
export interface KbxTemplateContext {
label?: string
hint?: string
updatedAt?: string
metrics?: KbxTemplateMetric[]
}
@@ -0,0 +1,38 @@
/**
* Workflow Definition Contracts — v60
* Record lifecycle, state transitions, approvals
*/
export type KbxRecordState = 'draft' | 'submitted' | 'approved' | 'rejected' | 'completed' | 'cancelled'
export interface KbxWorkflowTransition {
from: KbxRecordState
to: KbxRecordState
label: string
requiredPermission?: string
requiresReason?: boolean
}
export interface KbxWorkflowDefinition {
states: KbxRecordState[]
transitions: KbxWorkflowTransition[]
initialState: KbxRecordState
terminalStates: KbxRecordState[]
}
export interface KbxAuditEntry {
timestamp: string
actor: string
action: string
changes?: Record<string, [unknown, unknown]>
reason?: string
correlationId?: string
}
export interface KbxConflictSnapshot {
version: number
currentVersion: number
reason: 'concurrent-edit' | 'external-change'
lastModifiedAt: string
lastModifiedBy: string
}