@ultimat3/ui 20.2.1 → 21.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md
CHANGED
|
@@ -45,7 +45,8 @@ Tier 4 (moved 5 → 4 on 2026-08-19, when the `admin → ui` exception was delet
|
|
|
45
45
|
(`src/components/async-branch.ts`) is the ONLY place the `(pending, failed, empty, data)` decision
|
|
46
46
|
is made — `AsyncRegion` renders it and `DataTable` calls it, so a table and a card list cannot
|
|
47
47
|
disagree about what "loading with stale rows" looks like. The property is structural: an
|
|
48
|
-
`AsyncState` in `
|
|
48
|
+
`AsyncState` (declared in `@ultimat3/core` since 21.0.0 — imported here, never re-exported, so
|
|
49
|
+
it has one import path) in `pending` carries no data, so nothing can be found empty in it, and "No results"
|
|
49
50
|
for one frame before the first page arrives is unconstructible rather than discouraged.
|
|
50
51
|
`<AsyncRegion>`'s `empty` and `ready` are REQUIRED props, so forgetting the empty state is a type
|
|
51
52
|
error. `refreshing` CARRIES the previous data — a refetch dims what is on screen (`aria-busy`) and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "21.0.0",
|
|
4
4
|
"description": "SolidJS design system: semantic design tokens, dark/RTL-ready SCSS modules, a11y primitives",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"icons": "bun run src/icons/build-icons.ts"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@ultimat3/core": "
|
|
52
|
-
"@ultimat3/i18n": "
|
|
53
|
-
"@ultimat3/money": "
|
|
54
|
-
"@ultimat3/time": "
|
|
51
|
+
"@ultimat3/core": "21.0.0",
|
|
52
|
+
"@ultimat3/i18n": "21.0.0",
|
|
53
|
+
"@ultimat3/money": "21.0.0",
|
|
54
|
+
"@ultimat3/time": "21.0.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"solid-js": "^1.9.0"
|
|
@@ -7,14 +7,13 @@
|
|
|
7
7
|
// placeholder is derived from `reserve` so it cannot mismatch the loaded box, and the failure
|
|
8
8
|
// renders through `ErrorState`, which is the one thing allowed to phrase an error.
|
|
9
9
|
|
|
10
|
-
import { finiteCount } from '@ultimat3/core';
|
|
10
|
+
import { type AsyncState, finiteCount } from '@ultimat3/core';
|
|
11
11
|
import type { JSX } from 'solid-js';
|
|
12
12
|
import { ariaBool } from '../a11y';
|
|
13
13
|
import { cx } from '../cx';
|
|
14
14
|
import styles from './AsyncRegion.module.scss';
|
|
15
15
|
import {
|
|
16
16
|
type AsyncBranch,
|
|
17
|
-
type AsyncState,
|
|
18
17
|
asyncBranch,
|
|
19
18
|
isBusyBranch,
|
|
20
19
|
type ReserveBox,
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
// table and a card list cannot disagree about what "loading with stale rows" looks like. Only the
|
|
7
7
|
// PLACEHOLDER is local, because a table's is table-shaped: rows of cells, not lines of text.
|
|
8
8
|
|
|
9
|
-
import { finiteCount } from '@ultimat3/core';
|
|
9
|
+
import { type AsyncState, finiteCount } from '@ultimat3/core';
|
|
10
10
|
import type { JSX } from 'solid-js';
|
|
11
11
|
import { ariaBool } from '../a11y';
|
|
12
12
|
import { cx } from '../cx';
|
|
13
13
|
import { UI_KEYS } from '../i18n-keys';
|
|
14
14
|
import { useUi } from '../theme/context';
|
|
15
|
-
import { type AsyncBranch,
|
|
15
|
+
import { type AsyncBranch, asyncBranch, isBusyBranch } from './async-branch';
|
|
16
16
|
import styles from './DataTable.module.scss';
|
|
17
17
|
import { EmptyState } from './EmptyState';
|
|
18
18
|
import { ErrorState } from './ErrorState';
|
|
@@ -4,18 +4,11 @@
|
|
|
4
4
|
// unreachable until a result has arrived, and a refetch keeps the previous data on screen.
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* What a caller hands an async region
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `refreshing` is the one that makes search feel fast — it CARRIES the previous data, so a refetch
|
|
12
|
-
* re-renders what is already on screen instead of tearing it down to a skeleton.
|
|
7
|
+
* What a caller hands an async region is `AsyncState` from `@ultimat3/core` — declared at tier 0
|
|
8
|
+
* because realtime's read hooks (tier 3) return it and ui (tier 4) consumes it, and neither may
|
|
9
|
+
* import the other that way. Imported, never re-exported: one home, one import path.
|
|
13
10
|
*/
|
|
14
|
-
|
|
15
|
-
| { readonly status: 'pending' }
|
|
16
|
-
| { readonly status: 'refreshing'; readonly data: T }
|
|
17
|
-
| { readonly status: 'ready'; readonly data: T }
|
|
18
|
-
| { readonly status: 'failed'; readonly error: unknown };
|
|
11
|
+
import type { AsyncState } from '@ultimat3/core';
|
|
19
12
|
|
|
20
13
|
/**
|
|
21
14
|
* The branch a region renders. `empty` and `ready` carry `busy`; `pending` and `failed` do not,
|
|
@@ -23,8 +16,9 @@ export type AsyncState<T> =
|
|
|
23
16
|
*
|
|
24
17
|
* There is no `{ kind: 'empty' }` reachable from `{ status: 'pending' }` — that is the whole
|
|
25
18
|
* point of this module. "No results" rendered for one frame before the first page arrives is the
|
|
26
|
-
* most common agent-authored UX bug in a list screen, and
|
|
27
|
-
* rather than merely discouraged: `pending` holds no data, so nothing can be found
|
|
19
|
+
* most common agent-authored UX bug in a list screen, and `AsyncState`'s union makes it
|
|
20
|
+
* unconstructible rather than merely discouraged: `pending` holds no data, so nothing can be found
|
|
21
|
+
* empty in it.
|
|
28
22
|
*/
|
|
29
23
|
export type AsyncBranch<T> =
|
|
30
24
|
| { readonly kind: 'pending' }
|