@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 `pending` carries no data, so nothing can be found empty in it, and "No results"
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": "20.2.1",
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": "20.2.1",
52
- "@ultimat3/i18n": "20.2.1",
53
- "@ultimat3/money": "20.2.1",
54
- "@ultimat3/time": "20.2.1"
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, type AsyncState, asyncBranch, isBusyBranch } from './async-branch';
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. A STATE, never a query: `@ultimat3/ui` is tier 4 and may
8
- * not import `query`, `action` or `realtime`, so a live-query accessor, a `createResource` and a
9
- * plain signal all arrive here as the same four shapes.
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
- export type AsyncState<T> =
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 the union above makes it unconstructible
27
- * rather than merely discouraged: `pending` holds no data, so nothing can be found empty in it.
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' }
package/src/index.ts CHANGED
@@ -51,7 +51,6 @@ export { shellIds, shellLandmarks } from './components/app-shell-view';
51
51
  export type {
52
52
  AsyncBranch,
53
53
  AsyncFlags,
54
- AsyncState,
55
54
  ReserveBox,
56
55
  } from './components/async-branch';
57
56
  export {