Data State Model
interlace-ui/data-state-modelFreeComponent
Nothing in this file imports React, touches the DOM, or renders anything. It is the part of the absence contract that can be *proved* — the union, the precedence order, the announcement each state owes a screen reader, and the class set that paints it — so…
Install it
npx shadcn@latest add https://ds.interlace.tools/r/data-state-model.jsonSource
1export const DATA_STATES = [2 'loading',3 'error',4 'not-applicable',5 'not-counted',6 'empty',7 'partial',8 'truncated',9 'first-measurement',10 'idle',11] as const;1213export type DataStateName = (typeof DATA_STATES)[number];1415/**16 * States that REPLACE the body — there is no value to render underneath them.17 *18 * The complement (`partial`, `truncated`, `first-measurement`) qualifies a body19 * that does render. `idle` is neither, and is excluded from both.20 */21export const REPLACING_STATES = new Set<DataStateName>([22 'loading',23 'error',24 'not-applicable',25 'not-counted',26 'empty',27]);2829/** States that annotate a body which still renders. */30export const QUALIFYING_STATES = new Set<DataStateName>([31 'partial',32 'truncated',33 'first-measurement',34]);3536/** True when this state swaps out the content rather than annotating it. */37export const replacesBody = (state: DataStateName): boolean =>38 REPLACING_STATES.has(state);3940/**41 * The caller's flags, one per absence.42 *43 * `error` is `unknown` rather than `boolean` so a caught value can be passed44 * through untouched — the value is never rendered from here, only its45 * truthiness is read.46 *47 * Deliberately NOT a single `state` enum prop: the whole point is that these48 * co-occur. A partially-covered, truncated list is two facts, and an enum49 * would force the caller to pick one and drop the other on the floor.50 */51export interface DataStateFlags {52 loading?: boolean;53 error?: unknown;54 empty?: boolean;55 /** Some sources did not report. Every count below is a FLOOR, not a total. */56 partial?: boolean;57 /** The list is cut short. It must never become a denominator. */58 truncated?: boolean;59 /** The metric has no meaning for this subject. Not zero — inapplicable. */60 notApplicable?: boolean;61 /** No run happened. Not zero — unmeasured. This is the hatch. */62 notCounted?: boolean;63 /** A reading exists but no prior does. Never render this as `+0%`. */64 firstMeasurement?: boolean;65}6667/** Flag key → state name, in the same order as `DATA_STATES`. */68const FLAG_ORDER: readonly (readonly [keyof DataStateFlags, DataStateName])[] = [69 ['loading', 'loading'],70 ['error', 'error'],71 ['notApplicable', 'not-applicable'],72 ['notCounted', 'not-counted'],73 ['empty', 'empty'],74 ['partial', 'partial'],75 ['truncated', 'truncated'],76 ['firstMeasurement', 'first-measurement'],77];7879/**80 * Context for the spoken sentence.81 *82// … truncated
More from interlace-ui
All 140 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| A11y Startera11y-starter | interlace-ui | Components | Free | no deps | |
| Accordionaccordion | interlace-ui | Components | Free | no deps | |
| Alertalert | interlace-ui | Components | Free | no deps | |
| Alert Dialogalert-dialog | interlace-ui | Components | Free | no deps | |
| Animated Gradient Textanimated-gradient-text | interlace-ui | Components | Free | no deps | |
| Animated Grid Patternanimated-grid-pattern | interlace-ui | Components | Free | no deps | |
| Animated Listanimated-list | interlace-ui | Components | Free | no deps | |
| Article Cardarticle-card | interlace-ui | Components | Free | no deps |
