feat(10-03): tabs, toggles, relation fields, form lifecycle and settings pages
- FormTabs groups fields by tab (untabbed fields in the default tab) as a
segmented tablist; a tab holding invalid fields after a 422 shows a
count badge and the form switches to the first invalid field
- switch, checkbox and relation join the renderer registry: toggle cards
(role=switch, 20px checkbox) keep a numeric value numeric; relation
fields are read-only labels from meta.labels, a searchable single
select over fields/{field}/options with emptyOption first, or ordered
removable chips with an appending search (300 ms debounce, 20 per
page, more on scroll or the more action)
- FormView gets the back button, record title and update subtitle, a
sticky footer (Usuń with deleteConfirm then DELETE, Anuluj, Zapisz i
zamknij to the mapped redirectClose, Zapisz), and asks before leaving a
dirty form on any route change plus a beforeunload guard
- Settings: the rail pins Ustawienia to the bottom when /settings is
non-empty; /settings lists pages by category; /settings/:code renders
the settings schema through FormGrid and the registry, PUTs the values
and maps a 422 like the record form
- New backend::lang keys (form.more_options, tab_default, discard,
settings.back); form and settings smoke tests; boardwalk/dist rebuilt
This commit is contained in:
@@ -5,6 +5,30 @@ import { isRegistered } from './registry'
|
||||
|
||||
export type FormMode = 'create' | 'update'
|
||||
|
||||
/** One form tab: the YAML tab label, or the default tab for untabbed fields. */
|
||||
export interface TabItem {
|
||||
key: string
|
||||
label: string
|
||||
errors: number
|
||||
}
|
||||
|
||||
/** Key of the tab that holds fields without a `tab`. */
|
||||
export const DEFAULT_TAB = 'default'
|
||||
|
||||
/** Tab key of a field: its tab label, or the default tab. */
|
||||
export function tabOf(field: FormField): string {
|
||||
return field.tab ? `tab:${field.tab}` : DEFAULT_TAB
|
||||
}
|
||||
|
||||
/** DOM ids of the tab button and its panel, by tab position. */
|
||||
export function tabDomId(prefix: string, index: number): string {
|
||||
return `${prefix}-tab-${index}`
|
||||
}
|
||||
|
||||
export function panelDomId(prefix: string, index: number): string {
|
||||
return `${prefix}-panel-${index}`
|
||||
}
|
||||
|
||||
/** Winter `context:` semantics: no context shows the field everywhere. */
|
||||
export function contextAllows(field: FormField, mode: FormMode): boolean {
|
||||
const context = field.context
|
||||
|
||||
Reference in New Issue
Block a user