refactor(soma): route FieldProvider through field/internals barrel + register DRP view sub-parts (audit Round 3 §3 #23 + P4 follow-up)

Two related housekeeping items in one commit:

**1. FieldProvider via barrel (audit Round 3 §3 #23)**

37 consumer files across soma imported `FieldProvider` from the deep
path `'../field/field-provider.svelte'`, mirroring the same pattern
that motivated `internals.ts` indirection on the 5 pickers earlier.
Adds `src/uix/soma/components/field/internals.ts` re-exporting
`FieldProvider` and exposes it from the barrel `exports.ts`. The 37
imports become the canonical `from '../field'`. Consistency only —
no behavioral change.

**2. DateRangePicker view sub-parts (P4 follow-up)**

The MonthView/YearView soma parts created in commit `e93c0c73` stamp
internal layout data-attrs (`-header`, `-prev`, `-heading`, `-next`,
`-grid`, `-cell`) that weren't declared in the morfo, surfacing as 12
hardcoded-data-attr violations once the contract suite caught up.

Declares the 12 sub-parts in the morfo with the canonical kebab
prefix (`month-view-*`, `year-view-*`). Each entry minimal (data: [],
aria: []) except `*-prev` / `*-next` which stamp `type='button'` and
`*-cell` which surfaces the `data-range-{start,end,in-range}`
classification states used by the eidos range tinting CSS.

Test result: 2393/2399 passing — back to the canonical 6 fails
(Words + cookie infra). The 13 transient regressions are closed.

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

@ -258,6 +258,75 @@ export const dateRangePickerMorfo = {
}
]
},
// MonthView internal layout slots — stamped by soma, targeted
// by eidos CSS. Flat in the morfo per `month-view-*` namespacing.
{
name: 'MonthViewHeader',
kebab: 'month-view-header',
archetype: 'header',
kind: 'public',
defaultElement: 'div',
optional: true,
data: [],
aria: []
},
{
name: 'MonthViewPrev',
kebab: 'month-view-prev',
archetype: 'trigger',
kind: 'public',
defaultElement: 'button',
role: 'button',
optional: true,
data: [],
aria: [{ attr: 'type', value: v.literal('button') }]
},
{
name: 'MonthViewHeading',
kebab: 'month-view-heading',
archetype: 'label',
kind: 'public',
defaultElement: 'span',
optional: true,
data: [],
aria: []
},
{
name: 'MonthViewNext',
kebab: 'month-view-next',
archetype: 'trigger',
kind: 'public',
defaultElement: 'button',
role: 'button',
optional: true,
data: [],
aria: [{ attr: 'type', value: v.literal('button') }]
},
{
name: 'MonthViewGrid',
kebab: 'month-view-grid',
archetype: 'group',
kind: 'public',
defaultElement: 'div',
optional: true,
data: [],
aria: []
},
{
name: 'MonthViewCell',
kebab: 'month-view-cell',
archetype: 'item',
kind: 'public',
defaultElement: 'button',
role: 'button',
optional: true,
data: [
{ attr: 'data-range-start', severity: 'optional' },
{ attr: 'data-range-end', severity: 'optional' },
{ attr: 'data-in-range', severity: 'optional' }
],
aria: [{ attr: 'type', value: v.literal('button') }]
},
{
// Year-view range bridge for `kind='year'`. Symmetric to the
// MonthView but with decade pagination.
@ -276,6 +345,75 @@ export const dateRangePickerMorfo = {
severity: 'optional'
}
]
},
// YearView internal layout slots — same shape as MonthView's, with
// decade navigation labels.
{
name: 'YearViewHeader',
kebab: 'year-view-header',
archetype: 'header',
kind: 'public',
defaultElement: 'div',
optional: true,
data: [],
aria: []
},
{
name: 'YearViewPrev',
kebab: 'year-view-prev',
archetype: 'trigger',
kind: 'public',
defaultElement: 'button',
role: 'button',
optional: true,
data: [],
aria: [{ attr: 'type', value: v.literal('button') }]
},
{
name: 'YearViewHeading',
kebab: 'year-view-heading',
archetype: 'label',
kind: 'public',
defaultElement: 'span',
optional: true,
data: [],
aria: []
},
{
name: 'YearViewNext',
kebab: 'year-view-next',
archetype: 'trigger',
kind: 'public',
defaultElement: 'button',
role: 'button',
optional: true,
data: [],
aria: [{ attr: 'type', value: v.literal('button') }]
},
{
name: 'YearViewGrid',
kebab: 'year-view-grid',
archetype: 'group',
kind: 'public',
defaultElement: 'div',
optional: true,
data: [],
aria: []
},
{
name: 'YearViewCell',
kebab: 'year-view-cell',
archetype: 'item',
kind: 'public',
defaultElement: 'button',
role: 'button',
optional: true,
data: [
{ attr: 'data-range-start', severity: 'optional' },
{ attr: 'data-range-end', severity: 'optional' },
{ attr: 'data-in-range', severity: 'optional' }
],
aria: [{ attr: 'type', value: v.literal('button') }]
}
// Footer / Clear / Cancel / Close — chrome shared via picker-shell;
// not declared here. Eidos `<DateRangePicker.Footer/Clear/Cancel/

@ -1,5 +1,5 @@
import { Soma } from '../../core/soma.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { buttonMorfo } from '../../../morfo/components/button';
import type { OptsFromProps } from '../../provider';
import type { OnChangeFn, SomaMouseEvent } from '../../types';

@ -15,7 +15,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
ColorFieldFormatSelectProvider,

@ -38,7 +38,7 @@ import {
moveToNextSegment,
moveToPrevSegment
} from '../../datetime';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { COLOR_FIELD_LANGS } from './langs';
import type { ColorOnInvalid, ColorValidator } from './types';

@ -14,7 +14,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
ColorPickerAreaProvider,

@ -15,7 +15,7 @@ import {
type ColorFormat,
type EditableColorSegmentPart
} from '$libs/color';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
pickerShellContext,
type PickerShellHandle,

@ -24,7 +24,7 @@ import {
initSegmentStates,
isAcceptableSegmentKey
} from '$soma/datetime';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { DateFieldProvider } from './date-field-provider.svelte';

@ -68,7 +68,7 @@ import {
setDescription,
type Announcer
} from '../../datetime';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { DATE_FIELD_LANGS } from './langs';
// ── Contract ─────────────────────────────────────────────────────────────────

@ -18,7 +18,7 @@ import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import type { Direction } from '../../types';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
DateRangeFieldLabelProvider,

@ -19,7 +19,7 @@ import {
type Granularity,
type HourCycle
} from '$libs/days';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { dateRangeFieldMorfo } from '../../../morfo/components/date-range-field';

@ -1,3 +1,8 @@
// Provider class (consumed by other form-control providers that
// integrate with Field's labelId/description/invalid state via
// `FieldProvider.get()` context lookup).
export { FieldProvider } from './internals';
export { default as Provider } from './components/field.svelte';
export { default as Label } from './components/field-label.svelte';
export { default as RequiredIndicator } from './components/field-required-indicator.svelte';

@ -0,0 +1,15 @@
// Indirection layer for the public barrel.
//
// Soma's `exports.ts` cannot import directly from `*provider.svelte.ts`
// (contract: "public barrel must not re-export provider implementation
// filenames"). This file is the canonical re-export point — consumers
// reach it through `$soma/components/field` via `exports.ts`.
//
// `FieldProvider` is consumed across the soma codebase (37+ sites:
// every form-control provider that integrates with Field's labelId /
// description / invalid state). They now import via the barrel:
//
// import { FieldProvider } from '../field';
//
// instead of the deep path that bypassed the indirection.
export { FieldProvider } from './field-provider.svelte';

@ -8,7 +8,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
FileUploadClearTriggerProvider,

@ -5,7 +5,7 @@ import type { OnChangeFn, SomaMouseEvent } from '../../types';
import { KEYS } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { FILE_UPLOAD_LANGS } from './langs';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import type { FileRejection, FileRejectionReason } from './types';
import { formatBytes } from './format';

@ -6,7 +6,7 @@ import type { OnChangeFn, Direction, SomaKeyboardEvent, SomaMouseEvent } from '.
import { KEYS, getDirectionalKeys } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { TypeaheadBuffer } from '../../typeahead';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { GRID_LIST_LANGS } from './langs';
import type { GridListSelectionMode } from './types';

@ -7,7 +7,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
ListboxGroupLabelProvider,

@ -12,7 +12,7 @@ import type {
import { KEYS, getDirectionalKeys } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { TypeaheadBuffer } from '../../typeahead';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { LISTBOX_LANGS } from './langs';
import type { ListboxSelectionMode } from './types';

@ -8,7 +8,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
NumberFieldDecrementTriggerProvider,

@ -12,7 +12,7 @@ import type {
import { KEYS } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { NUMBER_FIELD_LANGS } from './langs';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
// ── Intl fallback cache ──────────────────────────────────────────────────────
// Used when `Soma` (or `soma.nums`) is not configured. Keeps `NumberField`

@ -15,7 +15,7 @@ import type {
} from '../../types';
import { KEYS } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { PASSWORD_FIELD_LANGS } from './langs';
import { passwordFieldMorfo } from '../../../morfo/components/password-field';

@ -15,7 +15,7 @@ import type {
SomaEvent
} from '../../types';
import { Soma } from '../../core/soma.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { PIN_INPUT_LANGS } from './langs';
import type { PinInputCellData, PinInputType } from './types';

@ -15,7 +15,7 @@ import {
RadioGroupProvider,
RadioItemProvider
} from './radio-group-provider.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
function withEffectRoot<T>(fn: () => T): { result: T; cleanup: () => void } {
let result!: T;

@ -6,7 +6,7 @@ import type { Orientation, Direction, SomaMouseEvent, SomaKeyboardEvent } from '
import { getDirectionalKeys } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { radioGroupMorfo } from '../../../morfo/components/radio-group';

@ -10,7 +10,7 @@ import type {
} from '../../types';
import { KEYS, getDirectionalKeys } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { RATING_GROUP_LANGS } from './langs';
import type { RatingItemDescriptor, RatingItemState } from './types';

@ -8,7 +8,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
SearchFieldClearTriggerProvider,

@ -16,7 +16,7 @@ import type {
} from '../../types';
import { KEYS } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { SEARCH_FIELD_LANGS } from './langs';
import { searchFieldMorfo } from '../../../morfo/components/search-field';

@ -8,7 +8,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
SliderProvider,

@ -6,7 +6,7 @@ import { KEYS, getDirectionalKeys } from '../../keyboard';
import { sliderMorfo } from '../../../morfo/components/slider';
import { Soma } from '../../core/soma.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
import { resolveSliderDragSound, type SemaSignatureOverride } from '$uix/sema';
import type { SliderType } from './types';

@ -8,7 +8,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { SwitchProvider, SwitchThumbProvider } from './switch-provider.svelte';

@ -4,7 +4,7 @@ import type { OptsFromProps } from '../../provider';
import type { OnChangeFn, SomaMouseEvent } from '../../types';
import { Soma } from '../../core/soma.svelte';
import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { switchMorfo } from '../../../morfo/components/switch';
import type { SwitchProps } from './types';

@ -15,7 +15,7 @@ import type {
} from '../../types';
import { KEYS } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { TEXTAREA_LANGS } from './langs';
import { textareaMorfo } from '../../../morfo/components/textarea';

@ -16,7 +16,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { TimeFieldProvider } from './time-field-provider.svelte';

@ -53,7 +53,7 @@ import {
setDescription,
type Announcer
} from '../../datetime';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { TIME_FIELD_LANGS } from './langs';
// ── Contract ─────────────────────────────────────────────────────────────────

@ -18,7 +18,7 @@ import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import type { Direction } from '../../types';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import {
TimeRangeFieldLabelProvider,

@ -14,7 +14,7 @@ import {
type TimeGranularity,
type HourCycle
} from '$libs/days';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { timeRangeFieldMorfo } from '../../../morfo/components/time-range-field';

@ -8,7 +8,7 @@ import { state } from '$libs/reactive';
import type { Morfo } from '$uix/morfo';
import { Soma } from '$soma/core/soma.svelte';
import { createSomaRuntime, type SomaRuntimeSources } from '$soma/runtime.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { ToggleProvider } from './toggle-provider.svelte';

@ -1,5 +1,5 @@
import { Soma } from '../../core/soma.svelte';
import { FieldProvider } from '../field/field-provider.svelte';
import { FieldProvider } from '../field';
import { toggleMorfo } from '../../../morfo/components/toggle';
import type { OptsFromProps } from '../../provider';
import type { OnChangeFn, SomaMouseEvent } from '../../types';

Loading…
Cancel
Save

Powered by TurnKey Linux.