refactor(morfo): commit-clear → commit-reset across 10 components (cluster clear resolved)

User directive: clearing a field is `commit.reset` per book cap. 23
("vuelve a estado inicial") — fits all 10 components in the cluster
since each goes back to empty-initial-state, not discarding meaningful
defaults.

Components updated (morfo + soma trigger + sema cascade + test):
- color-picker, date-field, date-picker, date-range-picker
- file-upload, range-calendar, tag-group, tags-input
- time-picker, time-range-picker

range-calendar.commit-clear was declaring `verb: 'remove'` — corrected
to `'reset'` along with the name change.

All event names now: `commit-reset` (family commit, verb reset, intent
neutral). No variant suffix needed; no ambiguity of multiple resets in
any single component.

words.commit-clear excluded — separate dev track.

Doc updated: src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.md C.1 marked as
RESUELTO with author's disposition.

Verification:
- morfo:vocabulary: warns 35 → 25 (-10), EXIT 0
- vitest src/uix/sema src/uix/morfo + tag-group tests: 199/199 pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 5 months ago
parent 670c54177d
commit 1582572e9b

@ -155,17 +155,13 @@ Estos verbos están en `src/uix/sema/verbs.ts:SEMA_VERBS` pero NO aparecen en la
Hoy ~35 events siguen como warns en `morfo:vocabulary` porque el verbo declarado es canónico pero el `name` no parsea a `{family}-{verb}`. Detrás de los renames cosméticos hay PREGUNTAS DOCTRINALES: Hoy ~35 events siguen como warns en `morfo:vocabulary` porque el verbo declarado es canónico pero el `name` no parsea a `{family}-{verb}`. Detrás de los renames cosméticos hay PREGUNTAS DOCTRINALES:
### C.1 "Clear" como concepto ### C.1 "Clear" como concepto — RESUELTO como `commit.reset`
- **10 componentes** usan eventos llamados `commit-clear`: color-picker, date-field, date-picker, date-range-picker, file-upload, range-calendar, tag-group, tags-input, time-picker, time-range-picker. - **Status**: Resuelto por el autor el 2026-05-25. Los 10 componentes ahora emiten `commit-reset` con `verb: 'reset'` canónico del libro.
- **Libro Cap 23 §5** lista para "revocación/cancelación": `cancel, reset, discard, expire`. **`clear` no aparece.** - **10 componentes** afectados: color-picker, date-field, date-picker, date-range-picker, file-upload, range-calendar, tag-group, tags-input, time-picker, time-range-picker.
- **Posibles mapeos**: - **Libro Cap 23 §5** lista `reset` como verbo canónico ("vuelve a estado inicial"). Encaja para todos los casos del cluster: cada uno está volviendo a estado vacío inicial (no defaults significativos que se descartan).
- `reset` = volver a estado inicial (date-field con default vuelve al default) - **Decisión tomada**: `commit.reset` con name canónico `commit-reset` (sin variant — no hay ambigüedad de múltiples resets en ningún componente del cluster). Verbo `'remove'` mal-declarado en range-calendar también corregido a `'reset'`.
- `discard` = tirar el valor actual (tag-group con tags se queda sin tags) - **Decisión pendiente para el libro**: ninguna. La doctrina del libro literal cubre exactamente el caso. Se podría añadir mención explícita de "clear de un campo" como ejemplo de `commit.reset` en una próxima edición.
- `cancel` = revocar operación en curso (no encaja para clear)
- **Pregunta para el libro**:
- (a) ¿Añadir `clear` como verbo canónico distinto de reset/discard?
- (b) ¿Mantener tres verbos y obligar a consumidores a elegir reset vs discard según contexto?
### C.2 "Unselect" como concepto ### C.2 "Unselect" como concepto

@ -98,7 +98,7 @@ export const colorPickerMorfo = {
} }
}, },
{ {
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -21,7 +21,7 @@ export const dateFieldMorfo = {
} }
}, },
{ {
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -116,7 +116,7 @@ export const datePickerMorfo = {
}, },
{ {
// User cleared the date (explicit clear button or backspace). // User cleared the date (explicit clear button or backspace).
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -122,7 +122,7 @@ export const dateRangePickerMorfo = {
}, },
{ {
// User cleared the range (explicit clear button or backspace). // User cleared the range (explicit clear button or backspace).
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -53,7 +53,7 @@ export const fileUploadMorfo = {
} }
}, },
{ {
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -34,10 +34,10 @@ export const rangeCalendarMorfo = {
} }
}, },
{ {
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'remove', verb: 'reset',
target: v.partRef('day'), target: v.partRef('day'),
intent: 'neutral', intent: 'neutral',
sequence: 'post' sequence: 'post'

@ -41,7 +41,7 @@ export const tagGroupMorfo = {
} }
}, },
{ {
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -42,7 +42,7 @@ export const tagsInputMorfo = {
} }
}, },
{ {
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -119,7 +119,7 @@ export const timePickerMorfo = {
} }
}, },
{ {
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -120,7 +120,7 @@ export const timeRangePickerMorfo = {
} }
}, },
{ {
name: 'commit-clear', name: 'commit-reset',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'reset', verb: 'reset',

@ -15,7 +15,7 @@ export const dateFieldSema: Sema = {
haptic: { kind: 'tap' } haptic: { kind: 'tap' }
}, },
{ {
selector: onProvider({ eventName: 'commit-clear' }), selector: onProvider({ eventName: 'commit-reset' }),
sound: soundTuning('form.commit.subtle', { sound: soundTuning('form.commit.subtle', {
contour: 'descending', contour: 'descending',
pitch: { op: 'add', value: -80 } pitch: { op: 'add', value: -80 }

@ -42,7 +42,7 @@ export const fileUploadSema: Sema = {
haptic: { kind: 'tap' } haptic: { kind: 'tap' }
}, },
{ {
selector: onProvider({ eventName: 'commit-clear' }), selector: onProvider({ eventName: 'commit-reset' }),
sound: soundTuning('form.commit.subtle', { sound: soundTuning('form.commit.subtle', {
contour: 'descending', contour: 'descending',
pitch: { op: 'add', value: -100 } pitch: { op: 'add', value: -100 }

@ -31,7 +31,7 @@ export const tagGroupSema: Sema = {
haptic: { kind: 'tap' } haptic: { kind: 'tap' }
}, },
{ {
selector: onProvider({ eventName: 'commit-clear' }), selector: onProvider({ eventName: 'commit-reset' }),
sound: soundTuning('form.commit.subtle', { sound: soundTuning('form.commit.subtle', {
contour: 'descending', contour: 'descending',
pitch: { op: 'add', value: -100 } pitch: { op: 'add', value: -100 }

@ -37,7 +37,7 @@ export const tagsInputSema: Sema = {
haptic: { kind: 'tap' } haptic: { kind: 'tap' }
}, },
{ {
selector: onProvider({ eventName: 'commit-clear' }), selector: onProvider({ eventName: 'commit-reset' }),
sound: soundTuning('form.commit.subtle', { sound: soundTuning('form.commit.subtle', {
contour: 'descending', contour: 'descending',
pitch: { op: 'add', value: -100 } pitch: { op: 'add', value: -100 }

@ -781,7 +781,7 @@ export class DateFieldProvider {
} }
const nextValue = this.opts.value.current?.toString(); const nextValue = this.opts.value.current?.toString();
if (previousValue !== nextValue) { if (previousValue !== nextValue) {
void this.runtime.trigger(nextValue === undefined ? 'commit-clear' : 'commit-set'); void this.runtime.trigger(nextValue === undefined ? 'commit-reset' : 'commit-set');
} }
} }

@ -206,7 +206,7 @@ export class FileUploadProvider {
if (this.isDisabled) return; if (this.isDisabled) return;
this.opts.files.current = []; this.opts.files.current = [];
this.opts.onFilesChange.current?.([]); this.opts.onFilesChange.current?.([]);
void this.runtime.trigger('commit-clear', target ? { fallbackTarget: target } : undefined); void this.runtime.trigger('commit-reset', target ? { fallbackTarget: target } : undefined);
} }
readonly props = $derived.by(() => readonly props = $derived.by(() =>

@ -408,7 +408,7 @@ export class RangeCalendarProvider {
this.anchor = undefined; this.anchor = undefined;
this.previewDate = undefined; this.previewDate = undefined;
this.opts.value.current = { start: undefined, end: undefined }; this.opts.value.current = { start: undefined, end: undefined };
void this.runtime.trigger('commit-clear', target ? { fallbackTarget: target } : undefined); void this.runtime.trigger('commit-reset', target ? { fallbackTarget: target } : undefined);
} }
private clearEndSelection(target?: HTMLElement): void { private clearEndSelection(target?: HTMLElement): void {
@ -421,7 +421,7 @@ export class RangeCalendarProvider {
this.anchor = start; this.anchor = start;
this.previewDate = undefined; this.previewDate = undefined;
this.opts.value.current = { start, end: undefined }; this.opts.value.current = { start, end: undefined };
void this.runtime.trigger('commit-clear', target ? { fallbackTarget: target } : undefined); void this.runtime.trigger('commit-reset', target ? { fallbackTarget: target } : undefined);
} }
private clearStartSelection(target?: HTMLElement): void { private clearStartSelection(target?: HTMLElement): void {
@ -434,7 +434,7 @@ export class RangeCalendarProvider {
this.anchor = end; this.anchor = end;
this.previewDate = undefined; this.previewDate = undefined;
this.opts.value.current = { start: undefined, end }; this.opts.value.current = { start: undefined, end };
void this.runtime.trigger('commit-clear', target ? { fallbackTarget: target } : undefined); void this.runtime.trigger('commit-reset', target ? { fallbackTarget: target } : undefined);
} }
private commit(a: DateValue, b: DateValue, target?: HTMLElement): void { private commit(a: DateValue, b: DateValue, target?: HTMLElement): void {

@ -368,7 +368,7 @@ describe('TagGroupProvider', () => {
await Promise.resolve(); await Promise.resolve();
expect(sem.calls.at(-1)).toMatchObject({ expect(sem.calls.at(-1)).toMatchObject({
target: root, target: root,
name: 'commit-clear', name: 'commit-reset',
family: 'commit', family: 'commit',
intent: 'neutral' intent: 'neutral'
}); });

@ -152,7 +152,7 @@ export class TagGroupProvider {
if (this.opts.value.current.length === 0) return; if (this.opts.value.current.length === 0) return;
this.opts.value.current = []; this.opts.value.current = [];
this.opts.onValueChange.current?.([]); this.opts.onValueChange.current?.([]);
void this.runtime.trigger('commit-clear', target ? { fallbackTarget: target } : undefined); void this.runtime.trigger('commit-reset', target ? { fallbackTarget: target } : undefined);
} }
// ── Keyboard ──────────────────────────────────────────────────────────── // ── Keyboard ────────────────────────────────────────────────────────────

@ -157,7 +157,7 @@ export class TagsInputProvider {
if (this.opts.value.current.length === 0) return; if (this.opts.value.current.length === 0) return;
this.opts.value.current = []; this.opts.value.current = [];
this.highlightedIndex = -1; this.highlightedIndex = -1;
void this.runtime.trigger('commit-clear', { void this.runtime.trigger('commit-reset', {
fallbackTarget: target ?? this.opts.ref?.current ?? undefined fallbackTarget: target ?? this.opts.ref?.current ?? undefined
}); });
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.