uix: date-picker + date-range-picker components + component audit infra
Two new Eidos components shipped end-to-end (wrapper + recipe + demo +
Soma provider hardening) plus a checklist-driven audit pipeline that
scores all 67 morfo components against doctrinal completion criteria.
New components:
- date-picker: full popover-anchored picker over date-field + calendar,
with calendar/content/trigger parts and demo route.
- date-range-picker: standalone wrapper with own calendar/grid/segment
surface, demo route, and recipe CSS.
- Both wrappers follow Option C disciplined (root + parts attached via
explicit assignment, no Object.assign).
Supporting Soma changes:
- range-calendar provider tightened (211 LOC of behavior, 167 LOC of
tests), README brought up to component doctrine.
- date-field, date-picker, date-range-field, date-range-picker Soma
providers + READMEs updated for new wrappers.
- popover provider/close gain props needed by the picker wrappers.
Morfo updates:
- date-picker / date-range-picker / range-calendar morfos refined for
the new APIs (parts, events, ARIA).
Audit infrastructure (new):
- src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across
morfo / eidos wrapper / recipe CSS / demo / README / cross-layer
scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION
and DEMO_AUTHORING_GUIDE.
- scripts/component-audit.ts + `npm run component:audit` — regex parser
over all 67 components, emits tmp/component-audit.md with summary
scoreboard + per-component findings. Validates against canonical
SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS.
- Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip,
date-range-picker). Top systemic gaps: translations.label (49),
README Gaps/Comparativa/Baseline sections (87 combined), keyboard
/event ratio under-declaration (15), apg URL absent (19).
Misc:
- src/uix/kimi-audit-eidos.md — supplementary audit notes.
- .gitignore: ignore .codex-* agent scratch artifacts at repo root.
- continue.md + READMEs updated through the migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
[data-date-picker] {
|
|
|
|
|
--_date-field-height: var(--date-field-height-md);
|
|
|
|
|
--_date-field-px: var(--date-field-px-md);
|
|
|
|
|
--_date-field-gap: var(--date-field-gap-md);
|
|
|
|
|
--_date-field-segment-px: var(--date-field-segment-px-md);
|
|
|
|
|
--_date-field-font-size: var(--date-field-font-size-md);
|
|
|
|
|
--_date-field-accent-border: var(--color-primary-border);
|
|
|
|
|
--_date-field-accent-track: var(--color-primary-track);
|
|
|
|
|
--_date-field-accent-text: var(--color-primary-text);
|
|
|
|
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: var(--date-field-stack-gap);
|
|
|
|
|
inline-size: 100%;
|
|
|
|
|
min-inline-size: 0;
|
|
|
|
|
color: var(--date-field-color);
|
|
|
|
|
font-family: var(--date-field-font-family);
|
|
|
|
|
font-size: var(--_date-field-font-size);
|
|
|
|
|
line-height: var(--date-field-line-height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-size='xs'] {
|
|
|
|
|
--_date-field-height: var(--date-field-height-xs);
|
|
|
|
|
--_date-field-px: var(--date-field-px-xs);
|
|
|
|
|
--_date-field-gap: var(--date-field-gap-xs);
|
|
|
|
|
--_date-field-segment-px: var(--date-field-segment-px-xs);
|
|
|
|
|
--_date-field-font-size: var(--date-field-font-size-xs);
|
|
|
|
|
}
|
|
|
|
|
|
uix: date-picker + date-range-picker components + component audit infra
Two new Eidos components shipped end-to-end (wrapper + recipe + demo +
Soma provider hardening) plus a checklist-driven audit pipeline that
scores all 67 morfo components against doctrinal completion criteria.
New components:
- date-picker: full popover-anchored picker over date-field + calendar,
with calendar/content/trigger parts and demo route.
- date-range-picker: standalone wrapper with own calendar/grid/segment
surface, demo route, and recipe CSS.
- Both wrappers follow Option C disciplined (root + parts attached via
explicit assignment, no Object.assign).
Supporting Soma changes:
- range-calendar provider tightened (211 LOC of behavior, 167 LOC of
tests), README brought up to component doctrine.
- date-field, date-picker, date-range-field, date-range-picker Soma
providers + READMEs updated for new wrappers.
- popover provider/close gain props needed by the picker wrappers.
Morfo updates:
- date-picker / date-range-picker / range-calendar morfos refined for
the new APIs (parts, events, ARIA).
Audit infrastructure (new):
- src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across
morfo / eidos wrapper / recipe CSS / demo / README / cross-layer
scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION
and DEMO_AUTHORING_GUIDE.
- scripts/component-audit.ts + `npm run component:audit` — regex parser
over all 67 components, emits tmp/component-audit.md with summary
scoreboard + per-component findings. Validates against canonical
SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS.
- Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip,
date-range-picker). Top systemic gaps: translations.label (49),
README Gaps/Comparativa/Baseline sections (87 combined), keyboard
/event ratio under-declaration (15), apg URL absent (19).
Misc:
- src/uix/kimi-audit-eidos.md — supplementary audit notes.
- .gitignore: ignore .codex-* agent scratch artifacts at repo root.
- continue.md + READMEs updated through the migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
[data-date-picker][data-size='sm'] {
|
|
|
|
|
--_date-field-height: var(--date-field-height-sm);
|
|
|
|
|
--_date-field-px: var(--date-field-px-sm);
|
|
|
|
|
--_date-field-gap: var(--date-field-gap-sm);
|
|
|
|
|
--_date-field-segment-px: var(--date-field-segment-px-sm);
|
|
|
|
|
--_date-field-font-size: var(--date-field-font-size-sm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-size='lg'] {
|
|
|
|
|
--_date-field-height: var(--date-field-height-lg);
|
|
|
|
|
--_date-field-px: var(--date-field-px-lg);
|
|
|
|
|
--_date-field-gap: var(--date-field-gap-lg);
|
|
|
|
|
--_date-field-segment-px: var(--date-field-segment-px-lg);
|
|
|
|
|
--_date-field-font-size: var(--date-field-font-size-lg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-color='secondary'] {
|
|
|
|
|
--_date-field-accent-border: var(--color-secondary-border);
|
|
|
|
|
--_date-field-accent-track: var(--color-secondary-track);
|
|
|
|
|
--_date-field-accent-text: var(--color-secondary-text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-color='neutral'] {
|
|
|
|
|
--_date-field-accent-border: var(--color-neutral-border);
|
|
|
|
|
--_date-field-accent-track: var(--color-neutral-track);
|
|
|
|
|
--_date-field-accent-text: var(--color-neutral-text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-color='affirm'] {
|
|
|
|
|
--_date-field-accent-border: var(--color-affirm-border);
|
|
|
|
|
--_date-field-accent-track: var(--color-affirm-track);
|
|
|
|
|
--_date-field-accent-text: var(--color-affirm-text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-color='fulfill'] {
|
|
|
|
|
--_date-field-accent-border: var(--color-fulfill-border);
|
|
|
|
|
--_date-field-accent-track: var(--color-fulfill-track);
|
|
|
|
|
--_date-field-accent-text: var(--color-fulfill-text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-color='risk'] {
|
|
|
|
|
--_date-field-accent-border: var(--color-risk-border);
|
|
|
|
|
--_date-field-accent-track: var(--color-risk-track);
|
|
|
|
|
--_date-field-accent-text: var(--color-risk-text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-color='threat'] {
|
|
|
|
|
--_date-field-accent-border: var(--color-threat-border);
|
|
|
|
|
--_date-field-accent-track: var(--color-threat-track);
|
|
|
|
|
--_date-field-accent-text: var(--color-threat-text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-color='loss'] {
|
|
|
|
|
--_date-field-accent-border: var(--color-loss-border);
|
|
|
|
|
--_date-field-accent-track: var(--color-loss-track);
|
|
|
|
|
--_date-field-accent-text: var(--color-loss-text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-variant='outline'] [data-date-field-input] {
|
|
|
|
|
background: transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-variant='ghost'] [data-date-field-input] {
|
|
|
|
|
border-color: transparent;
|
|
|
|
|
background: transparent;
|
|
|
|
|
padding-inline: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-invalid] [data-date-field-input] {
|
|
|
|
|
border-color: var(--date-field-border-invalid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker][data-disabled] {
|
|
|
|
|
opacity: var(--date-field-disabled-opacity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Trigger chrome (flush affordance, hover / focus states, size) is shared —
|
|
|
|
|
see field/field-control-trigger.css (`[data-field-control-trigger]`, the
|
|
|
|
|
eidos marker on the trigger). */
|
|
|
|
|
|
uix: date-picker + date-range-picker components + component audit infra
Two new Eidos components shipped end-to-end (wrapper + recipe + demo +
Soma provider hardening) plus a checklist-driven audit pipeline that
scores all 67 morfo components against doctrinal completion criteria.
New components:
- date-picker: full popover-anchored picker over date-field + calendar,
with calendar/content/trigger parts and demo route.
- date-range-picker: standalone wrapper with own calendar/grid/segment
surface, demo route, and recipe CSS.
- Both wrappers follow Option C disciplined (root + parts attached via
explicit assignment, no Object.assign).
Supporting Soma changes:
- range-calendar provider tightened (211 LOC of behavior, 167 LOC of
tests), README brought up to component doctrine.
- date-field, date-picker, date-range-field, date-range-picker Soma
providers + READMEs updated for new wrappers.
- popover provider/close gain props needed by the picker wrappers.
Morfo updates:
- date-picker / date-range-picker / range-calendar morfos refined for
the new APIs (parts, events, ARIA).
Audit infrastructure (new):
- src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across
morfo / eidos wrapper / recipe CSS / demo / README / cross-layer
scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION
and DEMO_AUTHORING_GUIDE.
- scripts/component-audit.ts + `npm run component:audit` — regex parser
over all 67 components, emits tmp/component-audit.md with summary
scoreboard + per-component findings. Validates against canonical
SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS.
- Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip,
date-range-picker). Top systemic gaps: translations.label (49),
README Gaps/Comparativa/Baseline sections (87 combined), keyboard
/event ratio under-declaration (15), apg URL absent (19).
Misc:
- src/uix/kimi-audit-eidos.md — supplementary audit notes.
- .gitignore: ignore .codex-* agent scratch artifacts at repo root.
- continue.md + READMEs updated through the migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
[data-popover-content]:has([data-date-picker-calendar]) {
|
|
|
|
|
--_popover-content-width-override: max-content;
|
|
|
|
|
--_popover-content-min-width-override: max-content;
|
|
|
|
|
--_popover-content-max-width-override: calc(100vw - var(--space-4));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker-calendar][data-calendar] {
|
|
|
|
|
padding: 0;
|
|
|
|
|
border-color: transparent;
|
|
|
|
|
background: transparent;
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-date-picker-calendar][data-calendar][data-invalid] {
|
|
|
|
|
border-color: transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
date-picker: kind derives segments at soma layer + year/month views
User correctly pointed out: the input segments depend on the kind of
calendar — they're *derived* values, not independently controlled.
Filtering segments in the demo snippet (commit A) was wrong; the
derivation belongs in the DateField provider.
This commit refactors the contract + lands the year/month-grid views
(combining commit B + C into one).
Architecture fix (segments derive from kind):
- DateFieldProvider opts gain `kind: 'date' | 'month' | 'year'`.
- `segmentContents` filters `allSegmentContent.arr` by a derived
`visibleDatePartsByKind` set, collapsing runs of literals and
trimming leading/trailing separators. Time segments (hour/minute/
second/dayPeriod) are passed through untouched — `kind` is
orthogonal to `granularity`.
- DateField root component accepts `kind` prop and threads it.
- DatePicker root forwards its `kind` to the DateField provider it
creates internally.
- DateRangeField passes `kind: 'date'` as a constant for now; range
propagation lands in commit D.
- Test fixtures extended with the new opt.
New Eidos parts (commit B + C in one shot):
- `<DatePicker.YearView>`: 3×4 decade grid centred on placeholder's
decade boundary. Header shows the decade range with prev/next
decade buttons. Click on a year sets value to (year, 1, 1) and
calls handleDateSelect (closes if closeOnDateSelect=true inline).
- `<DatePicker.MonthView>`: 3×4 month grid for the placeholder's
year. Localised month names via DateFormatter. Header shows the
year with prev/next year buttons. Click sets (year, month, 1).
- CSS for both: shared 3-column grid layout, hover surface-overlay
background, selected cell uses primary-solid + content-on-solid.
focus-visible outline. prefers-reduced-motion honoured.
Demo wiring:
- Removed the local `filterByKind` helper — soma derives it now.
- The snippet just iterates `segments` as it comes.
- The popover content branches on `kind`: Calendar for 'date',
MonthView for 'month', YearView for 'year'. The Footer renders in
all three branches.
- An $effect re-opens the popover whenever `kind` changes (clicking
the chip outside the popover would otherwise close it in inline
mode).
What this commit DOES NOT do (commit D):
- Propagate `kind` to date-range-picker (start + end inputs + the
range-calendar popover view-mode).
- date-range-field consumes `kind: 'date'` only for now.
Verification: 0 type errors, 11/11 date-field + date-picker tests,
67/67 component:audit PASS. Browser confirmed:
- kind=date → MM/DD/YYYY input + day calendar
- kind=month → MM/YYYY input + month grid (2026)
- kind=year → YYYY input + year grid (2020 – 2031)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
/* ── Year-view + Month-view (kind='year' / 'month') ──────────────────────── */
|
refactor(date-picker): MonthView / YearView delegate to MonthGrid / YearGrid
date-picker-month-view.svelte and date-picker-year-view.svelte previously
rolled their own 3×4 grids with custom data-date-picker-{month,year}-view-*
markers and ~90 lines of selection / nav / formatter logic. They now
render the standalone MonthGrid / YearGrid primitives (introduced in #70)
and bridge a thin DatePickerProvider context adapter:
- value: CalendarDate ↔ {year, month?} / {year}
- placeholder: CalendarDate ↔ {year}
- onValueChange → new CalendarDate(year, month, 1) + handleDateSelect
- onPlaceholderChange → mutate provider.placeholder.year
- forwards locale / disabled / readonly straight from the provider
CSS: removed the data-date-picker-{month,year}-view-* selector block
(~90 lines of dead code). Visuals now come from month-grid.css /
year-grid.css, which means the views also inherit the size='xs' work,
roving tabindex, RTL keyboard flip and sema events for free.
Verified in browser at /uix/components/date-picker:
- kind='month' → MonthGrid renders 12 cells (Jan..Dec) inside the popover
- click Mar → value becomes 2026-03-01, input segments update to 03/2026
- kind='year' → YearGrid renders the 2016–2027 page
- svelte-check --threshold error → 0 errors / 0 warnings / 4572 files
date-range-picker MonthView / YearView left untouched — their range
state machine (start/end/in-range markers, complete-vs-pending swap) is
not modelled by the standalone grids.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
/* DatePicker.MonthView and DatePicker.YearView now delegate to the
|
|
|
|
|
standalone MonthGrid / YearGrid primitives, so their visuals come from
|
|
|
|
|
`month-grid.css` and `year-grid.css`. */
|
|
|
|
|
|
|
|
|
|
/* The popover content uses a size-based base width (popover-min-width-{sm,md,…})
|
|
|
|
|
that can be narrower than the picker-shell footer's intrinsic content
|
|
|
|
|
(Clear / Cancel / Save buttons + gaps). Let the popover grow to max-content
|
|
|
|
|
when it hosts a date-picker calendar / grid so the inner row never overflows
|
|
|
|
|
and produces a horizontal scrollbar. */
|
|
|
|
|
[data-popover-content]:has(
|
|
|
|
|
> [data-date-picker-calendar],
|
|
|
|
|
> [data-month-grid],
|
|
|
|
|
> [data-year-grid]
|
|
|
|
|
) {
|
|
|
|
|
inline-size: max-content;
|
|
|
|
|
min-inline-size: max-content;
|
|
|
|
|
}
|