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.
48 lines
1.4 KiB
48 lines
1.4 KiB
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;
|