@nadicodeai/ui 6.6.2 → 7.1.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/AGENTS.md +4 -4
- package/LICENSES/LOBEHUB-ICONS-MIT.txt +21 -0
- package/NOTICE +14 -0
- package/dist/components/activity-orb.d.ts +1 -1
- package/dist/components/activity-orb.d.ts.map +1 -1
- package/dist/components/brand-icons/claude.d.ts +18 -0
- package/dist/components/brand-icons/claude.d.ts.map +1 -0
- package/dist/components/brand-icons/claude.js +22 -0
- package/dist/components/brand-icons/deepseek.d.ts +18 -0
- package/dist/components/brand-icons/deepseek.d.ts.map +1 -0
- package/dist/components/brand-icons/deepseek.js +22 -0
- package/dist/components/brand-icons/gemini.d.ts +18 -0
- package/dist/components/brand-icons/gemini.d.ts.map +1 -0
- package/dist/components/brand-icons/gemini.js +25 -0
- package/dist/components/brand-icons/grok.d.ts +18 -0
- package/dist/components/brand-icons/grok.d.ts.map +1 -0
- package/dist/components/brand-icons/grok.js +22 -0
- package/dist/components/brand-icons/meta.d.ts +18 -0
- package/dist/components/brand-icons/meta.d.ts.map +1 -0
- package/dist/components/brand-icons/meta.js +25 -0
- package/dist/components/brand-icons/mistral.d.ts +18 -0
- package/dist/components/brand-icons/mistral.d.ts.map +1 -0
- package/dist/components/brand-icons/mistral.js +22 -0
- package/dist/components/brand-icons/moonshot.d.ts +18 -0
- package/dist/components/brand-icons/moonshot.d.ts.map +1 -0
- package/dist/components/brand-icons/moonshot.js +22 -0
- package/dist/components/brand-icons/openai.d.ts +18 -0
- package/dist/components/brand-icons/openai.d.ts.map +1 -0
- package/dist/components/brand-icons/openai.js +22 -0
- package/dist/components/brand-icons/qwen.d.ts +18 -0
- package/dist/components/brand-icons/qwen.d.ts.map +1 -0
- package/dist/components/brand-icons/qwen.js +25 -0
- package/dist/components/brand-icons.d.ts +9 -0
- package/dist/components/brand-icons.d.ts.map +1 -1
- package/dist/components/brand-icons.js +9 -0
- package/dist/components/chart-breakdown-table.d.ts +26 -6
- package/dist/components/chart-breakdown-table.d.ts.map +1 -1
- package/dist/components/chart-breakdown-table.js +4 -4
- package/dist/components/chart-time-series.d.ts +68 -2
- package/dist/components/chart-time-series.d.ts.map +1 -1
- package/dist/components/chart-time-series.js +112 -11
- package/dist/components/chart.d.ts +2 -1
- package/dist/components/chart.d.ts.map +1 -1
- package/dist/components/chart.js +11 -2
- package/dist/components/model-mark.d.ts +19 -0
- package/dist/components/model-mark.d.ts.map +1 -0
- package/dist/components/model-mark.js +66 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/docs/activity.md +4 -5
- package/docs/contract.md +48 -5
- package/package.json +3 -7
- package/dist/components/threshold/canvas-budget.d.ts +0 -10
- package/dist/components/threshold/canvas-budget.d.ts.map +0 -1
- package/dist/components/threshold/canvas-budget.js +0 -54
- package/dist/components/threshold/index.d.ts +0 -6
- package/dist/components/threshold/index.d.ts.map +0 -1
- package/dist/components/threshold/index.js +0 -5
- package/dist/components/threshold/orb.d.ts +0 -14
- package/dist/components/threshold/orb.d.ts.map +0 -1
- package/dist/components/threshold/orb.js +0 -17
- package/dist/components/threshold/presence.d.ts +0 -27
- package/dist/components/threshold/presence.d.ts.map +0 -1
- package/dist/components/threshold/presence.js +0 -159
- package/dist/components/threshold/room.d.ts +0 -33
- package/dist/components/threshold/room.d.ts.map +0 -1
- package/dist/components/threshold/room.js +0 -168
- package/dist/components/threshold/threshold.css +0 -228
- package/dist/components/threshold/typed-line.d.ts +0 -8
- package/dist/components/threshold/typed-line.d.ts.map +0 -1
- package/dist/components/threshold/typed-line.js +0 -43
- package/dist/components/threshold/use-reduced-motion.d.ts +0 -10
- package/dist/components/threshold/use-reduced-motion.d.ts.map +0 -1
- package/dist/components/threshold/use-reduced-motion.js +0 -32
- package/dist/threshold.d.ts +0 -2
- package/dist/threshold.d.ts.map +0 -1
- package/dist/threshold.js +0 -13
- package/docs/threshold.md +0 -221
package/docs/threshold.md
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
# The threshold primitives
|
|
2
|
-
|
|
3
|
-
`@nadicodeai/ui/threshold` holds the four primitives a threshold is drawn from. A
|
|
4
|
-
threshold is the moment before the product is usable: a first run, a sign-in, a
|
|
5
|
-
repair. The Nadia desktop app draws its room, presence, status orb and typed line
|
|
6
|
-
from here, so the brand logic has one home.
|
|
7
|
-
|
|
8
|
-
The entry ships no screen and no state machine. Which view is on, what the
|
|
9
|
-
words are, and when a threshold ends belong to the consuming app.
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { NadiaPresence, Orb, ThresholdRoom, TypedLine } from "@nadicodeai/ui/threshold";
|
|
13
|
-
import "@nadicodeai/ui/threshold.css";
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## What each part is for
|
|
17
|
-
|
|
18
|
-
| Part | Its one job | Never |
|
|
19
|
-
| --- | --- | --- |
|
|
20
|
-
| `ThresholdRoom` | the place: a verde field on true black | inside the working app |
|
|
21
|
-
| `NadiaPresence` | the host: her arrival is the progress | a loader, a ring, a bar |
|
|
22
|
-
| `Orb` | system work underway, through the shared activity renderer | reporting a failed operation or waiting on a person as ongoing work |
|
|
23
|
-
| `TypedLine` | what Nadia is saying while you wait | a control or state machine |
|
|
24
|
-
|
|
25
|
-
The logo is not on this list. It belongs to window chrome, the tray and the
|
|
26
|
-
About row, never to a threshold.
|
|
27
|
-
|
|
28
|
-
## The stylesheet
|
|
29
|
-
|
|
30
|
-
`@nadicodeai/ui/threshold.css` is a separate import rather than a part of
|
|
31
|
-
`globals.css`, because the surface that needs it most does not load Tailwind:
|
|
32
|
-
the Nadia desktop shell takes this file and the design-system token layer and
|
|
33
|
-
nothing else from this package. A Tailwind consumer imports it beside
|
|
34
|
-
`@nadicodeai/ui/globals.css`.
|
|
35
|
-
|
|
36
|
-
Both the stylesheet and the room need the design-system tokens above them, from
|
|
37
|
-
`@nadicodeai/ui/globals.css` or `@nadicodeai/design-system/css`. Without that
|
|
38
|
-
cascade there is no palette, and the room paints its still field rather than
|
|
39
|
-
guessing a colour.
|
|
40
|
-
|
|
41
|
-
## `ThresholdRoom`
|
|
42
|
-
|
|
43
|
-
```tsx
|
|
44
|
-
<div className="relative isolate overflow-hidden">
|
|
45
|
-
<ThresholdRoom energy={arriving ? 1 : 0} dimmed={repairing} ready={connected} />
|
|
46
|
-
{/* the presence and the words, above it */}
|
|
47
|
-
</div>
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
| Prop | Type | Default | Meaning |
|
|
51
|
-
| --- | --- | --- | --- |
|
|
52
|
-
| `dimmed` | `boolean` | `false` | a repair or an error quiets the room to 22 percent |
|
|
53
|
-
| `energy` | `number` | `0` | how much of the room's pace runs, 0 to 1 |
|
|
54
|
-
| `ready` | `boolean` | `false` | success: the field takes verde vivo |
|
|
55
|
-
| `className` | `string` | — | added to the root |
|
|
56
|
-
|
|
57
|
-
The room paints absolutely inside its own relative, isolated parent and never
|
|
58
|
-
against the viewport, so a bounded surface can hold one without covering the
|
|
59
|
-
page. It is `aria-hidden`, takes no pointer events, and carries no words.
|
|
60
|
-
|
|
61
|
-
**The recipe.** Paper Shaders 0.0.78 `meshGradientFragmentShader`, its published
|
|
62
|
-
Ink preset adapted to two colours and slowed: `u_colors` are
|
|
63
|
-
`--nc-identity-verde` and `--nc-identity-ink`, `u_colorsCount` 2, `u_distortion`
|
|
64
|
-
1, `u_swirl` 0.2, `u_rotation` 90, `u_grainMixer` and `u_grainOverlay` 0, fit
|
|
65
|
-
contain, scale 1. Mount speed is 0.22 at energy 1, starting frame 12000, minimum
|
|
66
|
-
pixel ratio 1, maximum pixel count 1,024,000, canvas opacity 0.65. The room is
|
|
67
|
-
masked with `radial-gradient(ellipse 65% 58% at 50% 35%, black 10%, transparent
|
|
68
|
-
95%)`. The two colours are shader uniforms, never CSS.
|
|
69
|
-
|
|
70
|
-
`energy` is a scalar so a screen can decide. The captured recipe is energy 1;
|
|
71
|
-
Nadia's first run holds it there while she is still arriving and drops it to 0
|
|
72
|
-
when she has, which stills the field. Sign-in, success and every repair state
|
|
73
|
-
pass 0.
|
|
74
|
-
|
|
75
|
-
**One canvas per window.** While `NadiaPresence` is painting her arrival with
|
|
76
|
-
water, the room mounts nothing and shows this same still field; the moment the
|
|
77
|
-
water leaves, at reveal 1 or when it cannot paint, the room's canvas mounts.
|
|
78
|
-
The budget lives in the package, so a surface that composes both, as first run
|
|
79
|
-
does, keeps the register's one shader canvas without doing anything.
|
|
80
|
-
|
|
81
|
-
**No GPU, no tokens, or a lost context.** The room keeps its still field: a
|
|
82
|
-
token-built radial gradient that needs no WebGL. It carries `data-surface`,
|
|
83
|
-
`"shader"` while the canvas paints and `"still"` otherwise, and a mount that
|
|
84
|
-
fails leaves no dead canvas covering the fallback. A `webglcontextlost` event
|
|
85
|
-
returns it to the still field rather than to a black rectangle.
|
|
86
|
-
|
|
87
|
-
**Reduced motion.** Speed 0: the shader paints frame 12000 once and stops. The
|
|
88
|
-
room still has its colour and its shape; it just holds one frame.
|
|
89
|
-
|
|
90
|
-
## `NadiaPresence`
|
|
91
|
-
|
|
92
|
-
```tsx
|
|
93
|
-
<NadiaPresence label={t("install.progress")} reveal={fraction} src={portrait} state="arriving" />
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
| Prop | Type | Meaning |
|
|
97
|
-
| --- | --- | --- |
|
|
98
|
-
| `label` | `string` | the accessible name of the arrival |
|
|
99
|
-
| `reveal` | `number` | 0 behind the field, 1 standing clear |
|
|
100
|
-
| `src` | `string` | the portrait master's URL |
|
|
101
|
-
| `state` | `"arriving" \| "present" \| "ready" \| "error"` | which threshold she is in |
|
|
102
|
-
|
|
103
|
-
`src` is a prop rather than an import because this package imports no binary
|
|
104
|
-
asset of its own; the consuming surface resolves
|
|
105
|
-
`@nadicodeai/design-system/assets/nadia-solid-surface` with its own bundler and
|
|
106
|
-
passes the URL. Keeping it out of the library is what lets a Node or a
|
|
107
|
-
bundler-free consumer load the module at all.
|
|
108
|
-
|
|
109
|
-
**The arrival.** Opacity is `0.025 + 0.975 × reveal^1.25`, exported as
|
|
110
|
-
`arrivalOpacity` so a screen can read the same curve. At the start she is a
|
|
111
|
-
trace, which gives the arrival somewhere to go. Her lower edge dissolves into
|
|
112
|
-
the room with `linear-gradient(black 55%, transparent 98%)` instead of ending on
|
|
113
|
-
a rectangle. The `error` state multiplies her by 0.62.
|
|
114
|
-
|
|
115
|
-
**The water.** While `state` is `arriving`, `reveal` is below 1 and motion is
|
|
116
|
-
allowed, the portrait is painted by Paper's `waterFragmentShader` at a
|
|
117
|
-
restrained intensity: `caustic`, `edges` and `waves` are `0.35`, `0.4` and `0.3`
|
|
118
|
-
scaled by how much of the arrival is left, with `layering` 0.4 and `highlights`
|
|
119
|
-
0.12, `colorBack` fully transparent and `colorHighlight` on
|
|
120
|
-
`--nc-identity-verde`. Every amplitude reaches zero as she arrives, so her
|
|
121
|
-
geometry holds and the water is gone by the time she stands clear. At reveal 1,
|
|
122
|
-
and in every other state, this is the plain portrait.
|
|
123
|
-
|
|
124
|
-
While the water is wanted it is the window's one shader canvas: the presence
|
|
125
|
-
holds the canvas budget from the moment it asks for the water until the water
|
|
126
|
-
is torn down, and the room keeps its still field for exactly that long.
|
|
127
|
-
|
|
128
|
-
The water canvas is masked to her own silhouette. Water adds its highlight term
|
|
129
|
-
to the whole frame rather than only to the sampled image, so an unmasked canvas
|
|
130
|
-
paints a faintly lit rectangle over the room; the mask matches the shader's own
|
|
131
|
-
contain fit and centred origin.
|
|
132
|
-
|
|
133
|
-
**Reduced motion, no GPU, or an image that will not decode.** The plain
|
|
134
|
-
portrait, at the same reveal. The figure carries `data-surface`, `"water"` or
|
|
135
|
-
`"portrait"`.
|
|
136
|
-
|
|
137
|
-
**Success.** `state="ready"` runs one 360 ms verde vivo beat over her silhouette
|
|
138
|
-
on `--nc-ease-out-strong`, opacity 0 to 0.22 at 35 percent and back to 0, once.
|
|
139
|
-
Verde vivo is Nadia's presence accent and this is the only place a threshold
|
|
140
|
-
spends it, which is why the buttons beside it stay neutral. Reduced motion
|
|
141
|
-
suppresses the beat.
|
|
142
|
-
|
|
143
|
-
**Assistive technology.** A hidden `progressbar` carries `label` and the floored
|
|
144
|
-
percentage, so it reaches 100 only when the arrival is actually finished. The
|
|
145
|
-
portrait itself is decorative; the words are the typed line's.
|
|
146
|
-
|
|
147
|
-
## `Orb`
|
|
148
|
-
|
|
149
|
-
```tsx
|
|
150
|
-
<Orb label={t("install.working")} state="working" />
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
| Prop | Type | Default | Meaning |
|
|
154
|
-
| --- | --- | --- | --- |
|
|
155
|
-
| `label` | `string` | — | what the orb means, in the Customer's language |
|
|
156
|
-
| `size` | `88 \| 64 \| 20` | `88` | CSS pixels: threshold, region, or inline operation; see `activity.md` |
|
|
157
|
-
| `state` | `"working" \| "connecting" \| "absent"` | — | see below |
|
|
158
|
-
|
|
159
|
-
The threshold adapter preserves its public states: `working` selects the
|
|
160
|
-
shared `processing` activity, `connecting` selects `connecting`, and `absent`
|
|
161
|
-
renders nothing. The threshold defaults to fixed dark ink; `theme="auto"`
|
|
162
|
-
inherits the surrounding product's ink and `theme="light"` fixes light-surface
|
|
163
|
-
ink. There is one renderer, `ActivityOrb`, rather than a second threshold orb.
|
|
164
|
-
|
|
165
|
-
[System activity](activity.md) owns the motion recipes, colour treatment,
|
|
166
|
-
optical sizes, reduced-motion behaviour and connection-versus-person-waiting
|
|
167
|
-
rule. Applications retain their operation state machines and copy.
|
|
168
|
-
|
|
169
|
-
## `TypedLine`
|
|
170
|
-
|
|
171
|
-
```tsx
|
|
172
|
-
<TypedLine text={t("install.step.1")} />
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
| Prop | Type | Default |
|
|
176
|
-
| --- | --- | --- |
|
|
177
|
-
| `cadenceMs` | `number` | `44` |
|
|
178
|
-
| `text` | `string` | — |
|
|
179
|
-
| `className` | `string` | — |
|
|
180
|
-
|
|
181
|
-
The line types itself at 44 ms per character, the cadence the rendered
|
|
182
|
-
comparisons selected for a first-run pause. Three things it does that a naive
|
|
183
|
-
typewriter does not:
|
|
184
|
-
|
|
185
|
-
- the count comes from elapsed time, not from how many callbacks arrived, so a
|
|
186
|
-
software renderer or a busy main thread cannot stretch a one second sentence
|
|
187
|
-
into five;
|
|
188
|
-
- a hidden copy of the whole sentence reserves its width, so the orb beside it
|
|
189
|
-
does not travel sideways with each character;
|
|
190
|
-
- the live region receives the complete sentence at once, so a screen reader is
|
|
191
|
-
never read one letter at a time.
|
|
192
|
-
|
|
193
|
-
A new `text` retypes from a cleared line. The caret is steady while typing and
|
|
194
|
-
hidden afterwards.
|
|
195
|
-
|
|
196
|
-
**Reduced motion.** The whole line at once, and no caret.
|
|
197
|
-
|
|
198
|
-
## Tokens, and the one fixed presentation
|
|
199
|
-
|
|
200
|
-
Everything visual comes from design-system tokens. A threshold is a fixed dark
|
|
201
|
-
surface: it is true black in every theme, so the text ladder reads
|
|
202
|
-
`--nc-dark-ink`, `--nc-dark-body` and `--nc-dark-muted` directly instead of
|
|
203
|
-
branching on the app's mode. That is the fixed-presentation escape
|
|
204
|
-
[`contract.md`](contract.md) names, taken once and coherently for the whole
|
|
205
|
-
surface.
|
|
206
|
-
|
|
207
|
-
The room's two colours are the exception that proves it: they are shader
|
|
208
|
-
uniforms read off `--nc-identity-verde` and `--nc-identity-ink` at mount, not
|
|
209
|
-
CSS values.
|
|
210
|
-
|
|
211
|
-
## Motion budget
|
|
212
|
-
|
|
213
|
-
The foundation's: `--nc-duration-open` for a room fading in or out,
|
|
214
|
-
`--nc-duration-confirm` for the presence, `--nc-ease-emphasized` and
|
|
215
|
-
`--nc-ease-out-strong`. The success beat is the one
|
|
216
|
-
duration written here rather than taken from a token, 360 ms, because it is an
|
|
217
|
-
envelope rather than a state change.
|
|
218
|
-
|
|
219
|
-
Under `prefers-reduced-motion: reduce` the room holds one frame, the water is
|
|
220
|
-
not mounted, the presence jumps to its value, the beat does not run, the orb
|
|
221
|
-
draws once and the line appears whole.
|