You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/audit/components/time-range-picker.md

7.0 KiB

Audit: time-range-picker

audit-version: 1 audited-at: 2026-06-26 scope: soma + sema only; eidos dir exists → SYS-1 scope-drift (SCOPE-DRIFT → SYS-1) method: adversarially-verified workflow (analyze → refute); HIGH/CRITICAL personally re-verified by the lead. Batch-3 ground-truth: each picker fires trigger(close) (close NOT inert), but open/commit-reset ARE inert; calendar/range-calendar are MID-REFACTOR (uncommitted view-switch work). provider: src/uix/soma/components/time-range-picker/time-range-picker-provider.svelte.ts

Summary

Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 2. systemic hits: SYS-1: scope-drift (morfo scope omits eidos when eidos dir exists). composition (A27): Composes. Trigger wraps PopoverTriggerProvider.create(). Provider wires PopoverProvider + TimeRangeFieldProvider via shared writableActive refs. Clock composes Slider parts (range/thumb/tick re-exported, not re-implemented). All per-endpoint sliders delegate to SliderProvider. Trigger + Clock + sliders via eidos wrap soma components — A27 composition pattern correct.

Findings

MEDIUM: SYS-1: scope-drift — time-range-picker-001

  • dimension: A
  • rule: SYS-1: scope-drift
  • location: src/uix/morfo/components/time-range-picker.ts:13
  • evidence: morfo declares scope: ['soma', 'sema'] but eidos recipe directory exists at src/uix/eidos/components/time-range-picker/ with 13 component files (time-range-picker.svelte, index.ts, time-range-picker.css, etc.)
  • impact: morfo scope declaration is incomplete. Consumers expecting eidos provider will not find it listed, creating discovery/contract mismatch.
  • proposed-fix: Update morfo scope: scope: ['soma', 'sema', 'eidos']
  • verify: [confirmed] CONFIRMED — SYS-1 scope-drift. morfo line 13: scope: ['soma', 'sema'], omits 'eidos', yet a full eidos recipe dir exists at src/uix/eidos/components/time-range-picker/ (14 files: time-range-picker.css 392 lines, .svelte parts, index.ts, types.ts, README.md). This is the known systemic SYS-1 pattern (MEDIUM). The eidos layer genuinely materializes this component (CSS targets [data-time-range-picker]*) so the scope array is incomplete. Confidence high, severity MEDIUM as baselined.
  • fix-status: fixed (212624e0)

LOW: Magic literals in CSS (gap/spacing/block-size) — time-range-picker-002

  • dimension: E-bis
  • rule: Magic literals in CSS (gap/spacing/block-size)
  • location: src/uix/eidos/components/time-range-picker/time-range-picker.css:235,241,254,265,266,329,339
  • evidence: Lines 235 gap: 2px, 241 block-size: 0.875rem, 254 gap: 1px, 265 inline-size: 1px, 266 block-size: 4px, 329 padding: 2px, 339 min-inline-size: 2.25rem. These are literal measurements, not token references.
  • impact: Hardcoded values prevent consistent scaling via design tokens. Updates to spacing/sizing token system won't cascade to these edge cases.
  • proposed-fix: Extract to --space-* and --radius-* tokens or --_time-range-picker-* local vars. E.g., gap: var(--space-px) or gap: var(--_scale-tick-gap, 2px) as fallback.
  • verify: [downgraded] DOWNGRADED MEDIUM→LOW. Re-read the cited lines: 235 gap: 2px (.time-range-picker-slider), 241 block-size: 0.875rem (.time-range-picker-scale), 254 gap: 1px (.time-range-picker-scale-tick), 265 inline-size: 1px + 266 block-size: 4px (.time-range-picker-scale-mark — a hairline ruler tick mark), 329 padding: 2px (.day-period-toggle inner padding), 339 min-inline-size: 2.25rem (.day-period-item min width). These are decorative RULER geometry on plain .time-range-picker-* HELPER classes (not morfo data-attr selectors) — sub-pixel tick/mark dimensions that are intrinsic hairline geometry, not layout on the design-token rhythm. The 2px toggle padding and 2.25rem item width are borderline tokenizable but cosmetic and decorative-scaffold scoped. Note 0.875rem == --font-size-xs value but used as a block-size for a ruler band, not a font. MEDIUM overstates user/contract impact; this is LOW token-hygiene on ornamental ruler chrome.
  • fix-status: open

LOW: Magic literal: min-inline-size breakpoint + font-size literal — time-range-picker-003

  • dimension: E-bis
  • rule: Magic literal: min-inline-size breakpoint + font-size literal
  • location: src/uix/eidos/components/time-range-picker/time-range-picker.css:197,102,152
  • evidence: Line 197 @media (max-width: 40rem) + lines 102/152 flex: 1 1 7rem (field width). Line 241 block-size: 0.875rem (scale height). No token references.
  • impact: Responsive breakpoint and sizing coupled to hardcoded values. Violates token-driven design consistency.
  • proposed-fix: Use responsive size tokens or --space-* family. E.g., --_endpoint-input-basis: var(--space-28, 7rem). Align breakpoints to canonical design system.
  • verify: [downgraded] DOWNGRADED MEDIUM→LOW. Line 197 @media (max-width: 40rem) is a local responsive breakpoint collapsing the 2-col clock grid to 1-col; lines 102 flex: 1 1 7rem ([data-time-range-field-input]) and 152 flex: 1 1 7rem... (actually 102 is flex: 1 1 7rem, 152 is inline-size: calc(var(--_time-field-height) - var(--space-2)) which IS token-based). The real literal is the 7rem flex-basis (endpoint input min width) and the 40rem media query. These are component-local layout tuning, not on the spacing/size token scale, and there is no canonical responsive-token primitive for arbitrary flex-basis. Same family as 002 — LOW token-hygiene, not MEDIUM. The 152 part of the cited evidence is actually correct token usage (var(--_time-field-height) - var(--space-2)), so the evidence is partly inaccurate.
  • fix-status: open

No-findings dimensions

C, D, F

Theming facts (E-bis)

  • magic z-index: none
  • magic literals: gap: 2px | block-size: 0.875rem | gap: 1px | inline-size: 1px | block-size: 4px | padding: 2px | min-inline-size: 2.25rem | flex: 1 1 7rem | max-width: 40rem | min-inline-size: 28rem | min-inline-size: 14rem | line-height: 1 | transform: translateX(-50%) | border-radius: calc(var(--radius-md) - 2px)
  • undeclared parts: none
  • roles clean: true · variants clean: true

Tests (F)

  • exists: true · env: jsdom
  • covers: provider part registration; placeholder resolution per endpoint; per-endpoint value writes; 12-hour cycle mapping; hour/minute/second/day-period getters/setters; readonly segments filtering; close-on-range-complete behavior
  • untested: grid keyboard routes (N/A, not a grid); focus trap / dismissal; popover integration end-to-end; eidos visual composition; clock surface interactions; slider drag behavior

Style observations (non-blocking)

  • CSS structure mirrors TimePicker recipe (time-field tokens reused for field portion, popover surface tokens for clock body). Per-channel accent palette (Hour=primary, Minute=secondary, Second=neutral) is intentional design (documented in comments 279-284). Color-mix() for end-endpoint muting is elegant (line 321).
  • Endpoint layout (start/end columns) via flex wrapper .time-range-picker-endpoint — no grid, clean separation.

Powered by TurnKey Linux.