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/src/uix/morfo/components/skeleton.ts

48 lines
1.4 KiB

feat(eidos): add Skeleton and Spinner loader primitives Two pure-eidos loader components with morfos at scope `['eidos']` (no soma backing, no semantic events). Skeleton — content placeholder: - 3 shapes: rect (default), circle, text (multi-line with staggered widths) - 5 sizes (xs..xl), 8 color accents - Optional shimmer animation via CSS `background-position` keyframes - Single `<div role="status" aria-busy="true">` with translated aria-label - Reduced-motion freezes animation, keeps visual Spinner — indeterminate progress: - 3 variants: ring (rotating arc), dots (bouncing), bars (stretching) - 5 sizes, 8 colors - Optional inline label via children snippet - `role="status"` + `aria-live="polite"` for SR announcements - Reduced-motion freezes animation, keeps visual Files: - morfo: skeleton.ts, spinner.ts (scope eidos, no events) - eidos: full component + types + css + langs + index per component - langs: skeleton/spinner under componentLangs barrel - demos: canonical 6-tab depth + composition examples (avatar+text card) - layout: sidebar additions under Status group Note: also includes responsive shell additions to web/routes/uix/uix.css that surfaced from an external session — same file, leaving them in. Reference libraries reviewed (Mantine, Chakra v3, Radix Themes, MUI): all expose the same shape/variant/size/color surface. shadcn Skeleton uses the same pulse animation. No surprises in our API. svelte-check: 0 errors in skeleton/spinner files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
import type { Morfo } from '../types';
import { v } from '../types';
/**
* Skeleton — content placeholder shown while data loads.
*
* Eidos-native primitive: pure visual / a11y surface, no behavior, no
* state, no events. Renders a single `<div role="status">` carrying an
* `aria-label` so SR users get "loading" announced. Shape (rect / circle /
* text) toggles CSS recipe geometry via `data-shape`.
*
* Justification for 0-event surface: Skeleton has no commit/emerge/shift
* semantic — it disappears when the consumer swaps it for real content.
* Adding events would manufacture meaning the primitive doesn't carry.
* Same precedent as AspectRatio / Box / Flex / Grid.
*/
export const skeletonMorfo = {
name: 'Skeleton',
kebab: 'skeleton',
scope: ['eidos'],
texts: {
label: '#?components.skeleton.label|Loading'
},
parts: [
{
name: 'Provider',
kebab: 'provider',
archetype: 'provider',
kind: 'public',
defaultElement: 'div',
role: 'status',
optional: false,
data: [
{ attr: 'data-shape', value: v.propRef('shape'), severity: 'optional' },
{ attr: 'data-animated', value: v.propRef('animated'), severity: 'optional' }
],
aria: [
{
attr: 'aria-label',
value: v.translationRef('#?components.skeleton.label|Loading'),
severity: 'recommended'
},
{ attr: 'aria-busy', value: v.literal('true') }
]
}
]
} as const satisfies Morfo;

Powered by TurnKey Linux.