docs(soma,morfo): fix dead $lib/util aliases + stale morfo count

9 soma component READMEs imported from the removed $lib/util/dias and
$lib/util/colors aliases → $libs/days / $libs/color (matches what the code
actually imports). morfo/README.md said "All 66 morfos" (real count ~116) →
reworded to "Every morfo in the codebase" to drop the brittle number.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
active-uix
dev 4 months ago
parent 145e5b020c
commit 5c18a892a0

@ -380,7 +380,7 @@ The `as const satisfies Morfo` pattern is **mandatory**, not cosmetic. It does t
- **`as const`** preserves the literal types (`kebab: 'dialog'`, not `string`). This is what lets `createAttrs(dialogMorfo)` return `{ provider: 'data-dialog'; trigger: 'data-dialog-trigger'; ... }` with autocomplete and typo detection in every provider that consumes the morfo.
- **`satisfies Morfo`** validates that the object conforms to the `Morfo` interface without widening it. If a field is missing or mistyped, TypeScript reports it at the declaration — same safety as `: Morfo =` annotation, without the type widening.
A morfo annotated `: Morfo =` still works at runtime but yields `createAttrs(...): Record<string, string>` — no autocomplete, `attrs.trigerr` compiles. All 66 morfos in the codebase use `as const satisfies Morfo`; new morfos must do the same.
A morfo annotated `: Morfo =` still works at runtime but yields `createAttrs(...): Record<string, string>` — no autocomplete, `attrs.trigerr` compiles. Every morfo in the codebase use `as const satisfies Morfo`; new morfos must do the same.
---
@ -857,7 +857,7 @@ attrs.trigerr; // compile error — no such part
attrs.trigger; // typed as 'data-dialog-trigger'
```
All 66 morfos in the codebase use the `as const satisfies Morfo` form. This is mandatory, not stylistic.
Every morfo in the codebase use the `as const satisfies Morfo` form. This is mandatory, not stylistic.
**Duplicate kebab in the tree.** `item` in one part and `item` in another = error. Rename one.

@ -167,7 +167,7 @@ No mainstream headless library packs all channels into a single segmented field
```svelte
<script lang="ts">
import { ColorField, Field } from '$soma/components';
import type { ColorValue } from '$lib/util/colors';
import type { ColorValue } from '$libs/color';
let color = $state<ColorValue | undefined>();
let format = $state<'hex' | 'rgb' | 'hsl'>('hex');

@ -273,7 +273,7 @@ The precedent for this split in the broader ecosystem is the common "display for
```svelte
<script lang="ts">
import { ColorPicker, Field } from '$soma/components';
import type { ColorValue } from '$lib/util/colors';
import type { ColorValue } from '$libs/color';
let color = $state<ColorValue | undefined>();
const presets = ['#ef4444', '#f97316', '#22c55e', '#3b82f6', '#a855f7'];

@ -174,8 +174,8 @@ When composed inside `Field.Provider`, DateField:
```svelte
<script lang="ts">
import { DateField } from '$soma/components';
import { today, getLocalTimeZone, CalendarDate } from '$lib/util/dias';
import type { DateValue } from '$lib/util/dias';
import { today, getLocalTimeZone, CalendarDate } from '$libs/days';
import type { DateValue } from '$libs/days';
const t = today(getLocalTimeZone());
const min = new CalendarDate(t.year, t.month, t.day);

@ -163,8 +163,8 @@ All Provider props in `types.ts` with JSDoc. Summary:
```svelte
<script lang="ts">
import { DatePicker } from '$soma/components';
import { today, getLocalTimeZone, CalendarDate } from '$lib/util/dias';
import type { DateValue } from '$lib/util/dias';
import { today, getLocalTimeZone, CalendarDate } from '$libs/days';
import type { DateValue } from '$libs/days';
const t = today(getLocalTimeZone());
const min = new CalendarDate(t.year, t.month, t.day);

@ -139,8 +139,8 @@ The range validator runs when both endpoints are set and fires `onInvalid` with
```svelte
<script lang="ts">
import { DateRangeField } from '$soma/components';
import { today, getLocalTimeZone, CalendarDate } from '$lib/util/dias';
import type { DateRange } from '$lib/util/dias';
import { today, getLocalTimeZone, CalendarDate } from '$libs/days';
import type { DateRange } from '$libs/days';
const t = today(getLocalTimeZone());
const ref = new CalendarDate(t.year, t.month, t.day);

@ -143,8 +143,8 @@ Full surface in `types.ts`. Groups:
```svelte
<script lang="ts">
import { DateRangePicker } from '$soma/components';
import { today, getLocalTimeZone, CalendarDate } from '$lib/util/dias';
import type { DateRange } from '$lib/util/dias';
import { today, getLocalTimeZone, CalendarDate } from '$libs/days';
import type { DateRange } from '$libs/days';
const t = today(getLocalTimeZone());
const ref = new CalendarDate(t.year, t.month, t.day);

@ -124,8 +124,8 @@ Wrap in `Field.Provider` to inherit `disabled` / `readonly` / `required` / `inva
```svelte
<script lang="ts">
import { TimeField } from '$soma/components';
import { Time } from '$lib/util/dias';
import type { TimeValue } from '$lib/util/dias';
import { Time } from '$libs/days';
import type { TimeValue } from '$libs/days';
let value = $state<TimeValue | undefined>(new Time(9, 0));
</script>

@ -128,8 +128,8 @@ Most headless libraries expose a `DateRangeField` but not a dedicated **time** r
```svelte
<script lang="ts">
import { TimeRangeField } from '$soma/components';
import { Time } from '$lib/util/dias';
import type { TimeRange } from '$lib/util/dias';
import { Time } from '$libs/days';
import type { TimeRange } from '$libs/days';
let range = $state<TimeRange>({ start: undefined, end: undefined });
</script>

@ -162,8 +162,8 @@ No mainstream library ships a dedicated time-range picker — they collapse it i
```svelte
<script lang="ts">
import { TimeRangePicker } from '$soma/components';
import { Time } from '$lib/util/dias';
import type { TimeRange } from '$lib/util/dias';
import { Time } from '$libs/days';
import type { TimeRange } from '$libs/days';
let range = $state<TimeRange>({ start: undefined, end: undefined });
let open = $state(false);

Loading…
Cancel
Save

Powered by TurnKey Linux.