Files
KArtSell.Aegis/frontend/src/shared/@kbx/composables/useKbxDirtyState.ts
T
kjh2064 889212d643 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>
2026-08-15 10:43:10 +09:00

105 lines
2.1 KiB
TypeScript

/**
* useKbxDirtyState — v60
* Track unsaved changes in forms
*/
import { ref, computed } from 'vue'
export interface DirtyState {
[key: string]: boolean
}
export function useKbxDirtyState(initialState: DirtyState = {}) {
const dirtyFields = ref<DirtyState>(initialState)
/**
* Check if form is dirty (has unsaved changes)
*/
const dirty = computed(() => Object.values(dirtyFields.value).some(v => v))
/**
* Check if specific field is dirty
*/
const isFieldDirty = (field: string): boolean => {
return dirtyFields.value[field] ?? false
}
/**
* Mark field as dirty
*/
const markFieldDirty = (field: string): void => {
dirtyFields.value[field] = true
}
/**
* Mark field as clean
*/
const markFieldClean = (field: string): void => {
dirtyFields.value[field] = false
}
/**
* Mark all fields as clean
*/
const markAllClean = (): void => {
Object.keys(dirtyFields.value).forEach(key => {
dirtyFields.value[key] = false
})
}
/**
* Mark all fields as dirty
*/
const markAllDirty = (): void => {
Object.keys(dirtyFields.value).forEach(key => {
dirtyFields.value[key] = true
})
}
/**
* Reset to initial state
*/
const reset = (newInitialState: DirtyState = {}): void => {
dirtyFields.value = newInitialState
}
/**
* Touch field (mark as visited)
*/
const touchField = (field: string): void => {
if (!(field in dirtyFields.value)) {
dirtyFields.value[field] = false
}
}
/**
* Get dirty field names
*/
const getDirtyFields = (): string[] => {
return Object.entries(dirtyFields.value)
.filter(([, isDirty]) => isDirty)
.map(([field]) => field)
}
/**
* Set dirty state of multiple fields
*/
const setDirtyFields = (fields: DirtyState): void => {
dirtyFields.value = { ...dirtyFields.value, ...fields }
}
return {
dirty,
dirtyFields,
isFieldDirty,
markFieldDirty,
markFieldClean,
markAllClean,
markAllDirty,
touchField,
getDirtyFields,
setDirtyFields,
reset,
}
}