inline-chat-kit 0.59.2 → 0.61.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/CHANGELOG.md +129 -0
- package/README.md +17 -1
- package/dist/Button/KitButton.d.ts +28 -0
- package/dist/Button/hostButtonChecks.d.ts +15 -0
- package/dist/ChatExperience/ChatExperience.d.ts +11 -1
- package/dist/{ChatExperience-umh3nGe_.js → ChatExperience-BQgjY0-K.js} +1639 -1338
- package/dist/ChatExperience-BQgjY0-K.js.map +1 -0
- package/dist/ChatHeader/ChatHeader.d.ts +7 -0
- package/dist/ChatInput/AddCardsOverlay.d.ts +3 -1
- package/dist/ChatInput/ChatInput.d.ts +7 -0
- package/dist/ChatInput/useComposerControl.d.ts +18 -0
- package/dist/ChatTurnRow/ChatTurnRow.d.ts +23 -1
- package/dist/components/components.d.ts +102 -0
- package/dist/demo.js +10 -10
- package/dist/index.d.ts +2 -0
- package/dist/inline-chat-kit.css +1 -1
- package/dist/inline-chat-kit.js +8 -8
- package/dist/inline-chat-kit.js.map +1 -1
- package/package.json +1 -1
- package/theming.md +198 -0
- package/dist/ChatExperience-umh3nGe_.js.map +0 -1
package/theming.md
CHANGED
|
@@ -245,6 +245,204 @@ paper and one acid yellow. Six tokens turn that into a palette:
|
|
|
245
245
|
The markdown gaps are in `em` rather than pixels, so they scale with whatever
|
|
246
246
|
size the answer is set at instead of drifting away from it.
|
|
247
247
|
|
|
248
|
+
## Buttons
|
|
249
|
+
|
|
250
|
+
Every button the kit draws is one of five variants, and each variant is painted
|
|
251
|
+
from its own `--ick-btn-<variant>-*` tokens — so a host's primary is set once,
|
|
252
|
+
in its own stylesheet, rather than matched by a hashed class name:
|
|
253
|
+
|
|
254
|
+
```css
|
|
255
|
+
:root {
|
|
256
|
+
--ick-btn-radius: 10px;
|
|
257
|
+
--ick-btn-primary-bg: #1d4ed8;
|
|
258
|
+
--ick-btn-primary-ink: #fff;
|
|
259
|
+
--ick-btn-primary-border: transparent;
|
|
260
|
+
--ick-btn-primary-shadow: none;
|
|
261
|
+
--ick-btn-primary-shadow-hover: 0 2px 6px rgb(29 78 216 / 0.35);
|
|
262
|
+
--ick-btn-primary-shadow-press: none;
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
| Variant | Tokens |
|
|
267
|
+
| --- | --- |
|
|
268
|
+
| `primary` | `-bg` `-ink` `-border` `-shadow` `-shadow-hover` `-shadow-press` |
|
|
269
|
+
| `secondary` | `-bg` `-ink` `-bg-hover` `-border-hover` `-shadow-hover` `-shadow-press` |
|
|
270
|
+
| `outline` | `-bg` `-ink` `-border` `-bg-hover` `-border-hover` `-bg-press` |
|
|
271
|
+
| `ghost` | `-ink` `-ink-hover` `-bg-hover` `-bg-press` |
|
|
272
|
+
| `glass` | `-bg` `-ink` `-bg-hover` `-ink-hover` `-bg-press` — its rim and shadows are the glass tokens |
|
|
273
|
+
|
|
274
|
+
A state that does not change a property by default has no token for it, and
|
|
275
|
+
keeps the resting value: set `--ick-btn-primary-bg` and the hover is that
|
|
276
|
+
colour too, rather than turning back into glass.
|
|
277
|
+
|
|
278
|
+
**Every button also says what it is for**, in `data-ick-role`, and what it is
|
|
279
|
+
in `data-ick-variant`. Set the same tokens on a role and only that role
|
|
280
|
+
changes:
|
|
281
|
+
|
|
282
|
+
```css
|
|
283
|
+
[data-ick-role="stop"] { --ick-btn-primary-bg: #dc2626; }
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
| Role | Where |
|
|
287
|
+
| --- | --- |
|
|
288
|
+
| `send`, `stop`, `save` | The composer's glyph — three roles, not one button with three labels |
|
|
289
|
+
| `add`, `dictate`, `cancel-edit`, `add-close` | The composer's other controls |
|
|
290
|
+
| `read-more`, `message-action` | On a sent message (`data-ick-action`: `copy`, `edit`) |
|
|
291
|
+
| `answer-action` | Under an answer (`data-ick-action`: `copy`, `regenerate`, `up`, `down`) |
|
|
292
|
+
| `suggestion` | The openers in an empty conversation |
|
|
293
|
+
| `back`, `header-action`, `header-more`, `header-menu-item` | The header; an action carries its `id` as `data-ick-action` |
|
|
294
|
+
| `approval-once`, `approval-always`, `approval-deny` | An approval |
|
|
295
|
+
| `question-next` | A question card |
|
|
296
|
+
| `highlight-action` | The highlight menu (`data-ick-action`: `reply`, `remove`) |
|
|
297
|
+
| `thread-save`, `thread-close` | A thread |
|
|
298
|
+
| `pane-expand`, `pane-close` | The artifact pane |
|
|
299
|
+
| `remove-attachment` | An attachment's X |
|
|
300
|
+
|
|
301
|
+
A header action can be drawn as a primary with `variant: "primary"` on it.
|
|
302
|
+
|
|
303
|
+
**Bigger buttons on a phone.** Heights are `--ick-control-xs` … `-xl`. On a
|
|
304
|
+
coarse pointer the kit already raises them a step and gives every control an
|
|
305
|
+
invisible 44px hit area, so a 38px header button already answers to a 44px
|
|
306
|
+
thumb. A product that wants the buttons themselves drawn at 44 says so:
|
|
307
|
+
|
|
308
|
+
```css
|
|
309
|
+
@media (pointer: coarse) {
|
|
310
|
+
:root { --ick-control-m: 44px; }
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
The composer's own controls — the send / stop / save glyph, the "+", the
|
|
315
|
+
microphone — are `--ick-composer-control`, which is `--ick-control-s`: 28 on a
|
|
316
|
+
pointer, 32 on a touch screen. Its own token so the composer's row can move
|
|
317
|
+
without every other `s` button moving with it:
|
|
318
|
+
|
|
319
|
+
```css
|
|
320
|
+
@media (pointer: coarse) {
|
|
321
|
+
:root { --ick-composer-control: var(--ick-control-l); }
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Bring your own button
|
|
326
|
+
|
|
327
|
+
Three levels, each one further than the last. Stop at the first that is
|
|
328
|
+
enough.
|
|
329
|
+
|
|
330
|
+
**1. Tokens.** The `--ick-btn-<variant>-*` tokens above, `--ick-btn-radius`,
|
|
331
|
+
`--ick-btn-weight` and the `--ick-control-*` heights. Every button the kit
|
|
332
|
+
draws reads them, the composer's glyph included. Most hosts need nothing else.
|
|
333
|
+
|
|
334
|
+
**2. Per role, in CSS.** The same tokens on a `[data-ick-role]`, or your own
|
|
335
|
+
rules on it — the role table above is what to select on. A role is what the
|
|
336
|
+
button is for, so it survives a translation; a class name is hashed and a
|
|
337
|
+
label is not yours to match on.
|
|
338
|
+
|
|
339
|
+
**3. Your component.** Give `ChatExperience` your button and it draws it in
|
|
340
|
+
place of its own, everywhere but one place:
|
|
341
|
+
|
|
342
|
+
```tsx
|
|
343
|
+
<ChatExperience components={{ Button: MyButton }} onSend={send} />
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Pieces assembled by hand — `ChatTurnRow`, `ChatHeader`, `Approval`,
|
|
347
|
+
`ArtifactPane` — take it from `ComponentsProvider`, as they take words from
|
|
348
|
+
`LabelsProvider`:
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
<ComponentsProvider components={{ Button: MyButton }}>
|
|
352
|
+
<ChatHeader title="Chat" actions={actions} />
|
|
353
|
+
{turns.map((turn) => <ChatTurnRow key={turn.id} turn={turn} />)}
|
|
354
|
+
</ComponentsProvider>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Declare `MyButton` outside a render. A component made inside one is a new
|
|
358
|
+
component every time, and every button in the chat remounts with it.
|
|
359
|
+
|
|
360
|
+
### Who owns what
|
|
361
|
+
|
|
362
|
+
The kit owns **layout and behaviour**: the box each button sits in, its height
|
|
363
|
+
from `--ick-control-*` (and on an icon-only button its width), where it goes,
|
|
364
|
+
how it arrives and leaves, the 44px it answers to under a finger, focus moving
|
|
365
|
+
to it, and what pressing it does. Your button **paints**: colour, border,
|
|
366
|
+
radius, font, shadow, what hover and press look like, its icons, and the focus
|
|
367
|
+
ring.
|
|
368
|
+
|
|
369
|
+
So your button fills the box it is given — the kit sets its height over yours,
|
|
370
|
+
a `h-9` included, and its width when it is an icon on its own; its padding,
|
|
371
|
+
radius and everything it paints are left alone — and it never animates or
|
|
372
|
+
positions itself.
|
|
373
|
+
|
|
374
|
+
### The contract
|
|
375
|
+
|
|
376
|
+
Your component is called with `KitButtonProps`:
|
|
377
|
+
|
|
378
|
+
| Prop | |
|
|
379
|
+
| --- | --- |
|
|
380
|
+
| `kitRole` | What it is for — a role from the table above. Switch on it to pick your own variant |
|
|
381
|
+
| `variant` | What the kit would have drawn: `primary`, `secondary`, `outline`, `ghost`, `glass`. A hint |
|
|
382
|
+
| `size` | `xs` … `xl`: the step of `--ick-control-*` the box already is |
|
|
383
|
+
| `shape` | `square` (an icon on its own), `pill` (a chip: an opener, "Read more", a highlight's action) or `default` (a text button among others). A hint |
|
|
384
|
+
| `icon`, `iconRight`, `children` | The content. An icon-only button is named by its `aria-label` |
|
|
385
|
+
| `disabled`, `loading`, `pressed` | `loading` also sets `disabled` and `aria-busy`; `pressed` also sets `aria-pressed` |
|
|
386
|
+
| `type` | Always `"button"` |
|
|
387
|
+
| `onClick` | And every other handler the kit needs |
|
|
388
|
+
| `aria-*`, `title`, `role`, `tabIndex` | A menu's items arrive with `role="menuitem"` and a roving `tabIndex` |
|
|
389
|
+
| `data-ick-role`, `data-ick-variant`, `data-ick-action` | So the CSS above still reaches your button |
|
|
390
|
+
| `ref` | The `<button>` itself. The kit focuses it and anchors the header's menu to it |
|
|
391
|
+
|
|
392
|
+
Three rules, and the words in the first column of the table are the kit's,
|
|
393
|
+
not attributes — take them out before spreading the rest:
|
|
394
|
+
|
|
395
|
+
1. **Forward the ref** — `forwardRef`, or in React 19 pass `ref` through.
|
|
396
|
+
2. **Render a `<button>`.** The keyboard behaviour is the button's.
|
|
397
|
+
3. **Spread what you do not use** onto it: the `aria-*`, `data-*`, `role`,
|
|
398
|
+
`tabIndex`, `title` and handlers.
|
|
399
|
+
|
|
400
|
+
```tsx
|
|
401
|
+
const MyButton = forwardRef<HTMLButtonElement, KitButtonProps>(function MyButton(
|
|
402
|
+
{ kitRole, variant, size, shape, icon, iconRight, loading, pressed, children, ...rest },
|
|
403
|
+
ref
|
|
404
|
+
) {
|
|
405
|
+
const look = kitRole === "approval-once" ? "default" : variant === "primary" ? "secondary" : "ghost";
|
|
406
|
+
return (
|
|
407
|
+
<Button ref={ref} variant={look} size={shape === "square" ? "icon" : "sm"} {...rest}>
|
|
408
|
+
{loading ? <Spinner /> : icon}
|
|
409
|
+
{children}
|
|
410
|
+
{iconRight}
|
|
411
|
+
</Button>
|
|
412
|
+
);
|
|
413
|
+
});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
In development the kit checks each role's button once and says so in the
|
|
417
|
+
console when it does not forward its ref, is not a `<button>`, drops the
|
|
418
|
+
`aria-*` or `data-ick-*` it was given, or looks no different with keyboard
|
|
419
|
+
focus. One warning per role; none in a production build.
|
|
420
|
+
|
|
421
|
+
### The one exception: the send glyph
|
|
422
|
+
|
|
423
|
+
The composer's send / stop / save button is always the kit's. It is one button
|
|
424
|
+
whose glyph morphs between the three as the composer changes state, and that
|
|
425
|
+
animation lives inside the button — a host component would have to take it on
|
|
426
|
+
to stand in for it. It follows the tokens instead: `--ick-btn-radius`,
|
|
427
|
+
`--ick-btn-primary-*` (on `[data-ick-role="send"]`, `"stop"` or `"save"` to
|
|
428
|
+
tell them apart) and `--ick-composer-control`.
|
|
429
|
+
|
|
430
|
+
Two more stay the kit's for a different reason: the header's back control and
|
|
431
|
+
a header action given an `href` are links, not buttons, and draw as `<a>`.
|
|
432
|
+
|
|
433
|
+
### One radius
|
|
434
|
+
|
|
435
|
+
Set `--ick-btn-radius` to your buttons' corner even when you bring your own
|
|
436
|
+
button. It is how the kit's own glyph matches yours, and how the surfaces
|
|
437
|
+
around buttons match them: the composer's corner is the button's plus the
|
|
438
|
+
composer's 8px padding — concentric — up to its own ceiling of
|
|
439
|
+
`--ick-radius-xl`. A 6px button sits in a 14px composer; the default pill sits
|
|
440
|
+
in the 24px composer it always has.
|
|
441
|
+
|
|
442
|
+
```css
|
|
443
|
+
:root { --ick-btn-radius: 6px; }
|
|
444
|
+
```
|
|
445
|
+
|
|
248
446
|
## Motion
|
|
249
447
|
|
|
250
448
|
`--ick-ease`, `--ick-ease-overshoot`, and the `--ick-duration-*` scale. The kit
|