@mitcsutt/kiln-ui 0.4.0 → 0.6.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.
Files changed (49) hide show
  1. package/dist/components/display/CodeBlock/CodeBlock.d.ts +44 -3
  2. package/dist/components/display/CodeBlock/CodeBlock.js +54 -49
  3. package/dist/components/display/CodeBlock/CodeBlock.js.map +1 -1
  4. package/dist/components/display/CodeBlock/CodeBlock.module.js +4 -3
  5. package/dist/components/display/CodeBlock/CodeBlock.module.js.map +1 -1
  6. package/dist/components/display/CodeBlock/index.d.ts +1 -1
  7. package/dist/components/display/List/List.d.ts +8 -0
  8. package/dist/components/display/List/List.js +5 -4
  9. package/dist/components/display/List/List.js.map +1 -1
  10. package/dist/components/display/List/List.module.js.map +1 -1
  11. package/dist/components/display/List/index.d.ts +1 -1
  12. package/dist/components/display/Media/Media.d.ts +2 -0
  13. package/dist/components/display/Media/Media.js +41 -25
  14. package/dist/components/display/Media/Media.js.map +1 -1
  15. package/dist/components/display/Table/Table.d.ts +17 -0
  16. package/dist/components/display/Table/Table.js +13 -10
  17. package/dist/components/display/Table/Table.js.map +1 -1
  18. package/dist/components/display/Table/Table.module.js.map +1 -1
  19. package/dist/components/display/Table/index.d.ts +1 -1
  20. package/dist/components/layout/Box/Box.d.ts +12 -3
  21. package/dist/components/layout/Box/Box.js +11 -10
  22. package/dist/components/layout/Box/Box.js.map +1 -1
  23. package/dist/components/layout/Box/Box.module.js.map +1 -1
  24. package/dist/components/layout/ScrollArea/ScrollArea.d.ts +36 -0
  25. package/dist/components/layout/ScrollArea/ScrollArea.js +25 -0
  26. package/dist/components/layout/ScrollArea/ScrollArea.js.map +1 -0
  27. package/dist/components/layout/ScrollArea/ScrollArea.module.js +6 -0
  28. package/dist/components/layout/ScrollArea/ScrollArea.module.js.map +1 -0
  29. package/dist/components/layout/ScrollArea/index.d.ts +2 -0
  30. package/dist/components/layout/Section/Section.d.ts +11 -2
  31. package/dist/components/layout/Section/Section.js +10 -9
  32. package/dist/components/layout/Section/Section.js.map +1 -1
  33. package/dist/components/layout/Section/Section.module.js.map +1 -1
  34. package/dist/highlight/index.d.ts +18 -0
  35. package/dist/highlight/index.js +103 -0
  36. package/dist/highlight/index.js.map +1 -0
  37. package/dist/index.d.ts +5 -3
  38. package/dist/index.js +102 -101
  39. package/dist/styles.css +1 -1
  40. package/dist/utils/newlines.d.ts +2 -0
  41. package/dist/utils/newlines.js +10 -0
  42. package/dist/utils/newlines.js.map +1 -0
  43. package/package.json +13 -2
  44. package/skills/design-rules/SKILL.md +1 -0
  45. package/skills/layout-composition/SKILL.md +2 -0
  46. package/skills/layout-composition/references/box.md +21 -1
  47. package/skills/layout-composition/references/scroll-area.md +68 -0
  48. package/skills/layout-composition/references/section.md +2 -1
  49. package/skills/setup-and-theming/SKILL.md +1 -0
@@ -0,0 +1,2 @@
1
+ /** `text` without its trailing newlines, found by a backward scan rather than a regex. */
2
+ export declare function trimTrailingNewlines(text: string): string;
@@ -0,0 +1,10 @@
1
+ //#region src/utils/newlines.ts
2
+ function e(e) {
3
+ let t = e.length;
4
+ for (; t > 0 && e[t - 1] === "\n";) t--;
5
+ return e.slice(0, t);
6
+ }
7
+ //#endregion
8
+ export { e as trimTrailingNewlines };
9
+
10
+ //# sourceMappingURL=newlines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"newlines.js","names":["trimTrailingNewlines","end","text"],"sources":["../../src/utils/newlines.ts"],"sourcesContent":["/** `text` without its trailing newlines, found by a backward scan rather than a regex. */\nexport function trimTrailingNewlines(text: string): string {\n let end = text.length\n while (end > 0 && text[end - 1] === '\\n') end--\n return text.slice(0, end)\n}\n"],"mappings":";AACA,SAAgBA,EAAqB,GAAsB;CACzD,IAAIC,IAAMC,EAAK;CACf,OAAOD,IAAM,KAAKC,EAAKD,IAAM,OAAO,OAAM;CAC1C,OAAOC,EAAK,MAAM,GAAGD,CAAG;AAC1B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mitcsutt/kiln-ui",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Kiln: a themeable React design system on Radix primitives, plain CSS and design tokens",
5
5
  "keywords": [
6
6
  "kiln",
@@ -36,6 +36,10 @@
36
36
  "types": "./dist/theme/script.d.ts",
37
37
  "default": "./dist/theme/script.js"
38
38
  },
39
+ "./highlight": {
40
+ "types": "./dist/highlight/index.d.ts",
41
+ "default": "./dist/highlight/index.js"
42
+ },
39
43
  "./styles.css": "./dist/styles.css",
40
44
  "./themes/monograph.css": "./dist/themes/monograph.css",
41
45
  "./themes/ledger.css": "./dist/themes/ledger.css",
@@ -72,6 +76,7 @@
72
76
  "publint": "^0.3.25",
73
77
  "react": "^19.3.0",
74
78
  "react-dom": "^19.3.0",
79
+ "shiki": "^4.5.0",
75
80
  "storybook": "^10.6.1",
76
81
  "typescript": "~6.0.3",
77
82
  "vite": "^8.3.2",
@@ -79,7 +84,13 @@
79
84
  },
80
85
  "peerDependencies": {
81
86
  "react": "^18.3.0 || ^19.0.0",
82
- "react-dom": "^18.3.0 || ^19.0.0"
87
+ "react-dom": "^18.3.0 || ^19.0.0",
88
+ "shiki": "^4.0.0"
89
+ },
90
+ "peerDependenciesMeta": {
91
+ "shiki": {
92
+ "optional": true
93
+ }
83
94
  },
84
95
  "engines": {
85
96
  "node": ">=22.12.0"
@@ -79,6 +79,7 @@ Beyond the checks, a theme has a subject, and each colour, face, radius and easi
79
79
  - **Asymmetric splits** (`<Split ratio="5/7">`), a hang column for labels, at least one element per page that breaks the column.
80
80
  - **Vary section rhythm.** The space scale is non-linear (4 8 12 16 24 32 48 64 96 144…) and adjacent `<Section>`s should not use the same `space`.
81
81
  - **Not everything is a card.** Prefer lists, tables, rules and whitespace. A card needs a reason: it's interactive, draggable, or a self-contained object.
82
+ - **A list on a busy canvas gets one sheet, not a card per row.** Where rows would float on a textured or coloured canvas, `List` and `Table` take `surface` (`surface` or `raised`): the whole list sits on one sheet and its rows, fills, rails and rules stay rows inside it.
82
83
  - The hero is the subject's most characteristic thing: the open invoices, the release board, today's orders. Not a stat row with a gradient.
83
84
 
84
85
  ### Components & depth
@@ -18,6 +18,7 @@ sources:
18
18
  - mitcsutt/kiln:packages/ui/src/components/layout/ActionBar/ActionBar.tsx
19
19
  - mitcsutt/kiln:packages/ui/src/components/layout/Divider/Divider.tsx
20
20
  - mitcsutt/kiln:packages/ui/src/components/layout/AspectRatio/AspectRatio.tsx
21
+ - mitcsutt/kiln:packages/ui/src/components/layout/ScrollArea/ScrollArea.tsx
21
22
  - mitcsutt/kiln:packages/ui/src/components/layout/VisuallyHidden/VisuallyHidden.tsx
22
23
  - mitcsutt/kiln:apps/docs/content/docs/ui/patterns/dashboard.mdx
23
24
  - mitcsutt/kiln:apps/docs/content/docs/ui/patterns/settings.mdx
@@ -431,6 +432,7 @@ Read a reference when its description matches the task:
431
432
  - [ActionBar](references/action-bar.md): The row of actions at the end of a form or dialog. Cancel, save, continue.
432
433
  - [Divider](references/divider.md): A hairline rule between groups of content, optionally labelled, horizontal or vertical.
433
434
  - [AspectRatio](references/aspect-ratio.md): A frame that keeps its proportions, for images, video, maps and charts.
435
+ - [ScrollArea](references/scroll-area.md): A scroll container for content wider or taller than the page, such as a bracket, a timeline or a wide board, that keyboard users can reach and scroll.
434
436
  - [VisuallyHidden](references/visually-hidden.md): Content that screen readers announce and sighted readers don't need to see.
435
437
  - [Dashboard](references/dashboard.md): A week of operations at a glance, built from stats, a table and a list. No tiles, no gradients, no cards that don't need to be cards.
436
438
  - [Settings](references/settings.md): A settings page with section navigation, labelled fields, grouped switches and a guarded destructive action.
@@ -30,6 +30,25 @@ export function Usage() {
30
30
  }
31
31
  ```
32
32
 
33
+ ## Accent panel
34
+
35
+ `surface="accent"` is a rounded panel in the accent colour, for the one thing on a page that should shout. Text, links and buttons inside it take the accent's own ink.
36
+
37
+ ```tsx
38
+ import { Box, Stack, Text } from '@mitcsutt/kiln-ui'
39
+
40
+ export function AccentPanel() {
41
+ return (
42
+ <Box surface="accent" padding={5} radius="surface">
43
+ <Stack gap={2}>
44
+ <Text weight="medium">Ferry tickets go on sale Monday at 09:00</Text>
45
+ <Text size="sm">Weekend crossings sell out within the hour, so set a reminder.</Text>
46
+ </Stack>
47
+ </Box>
48
+ )
49
+ }
50
+ ```
51
+
33
52
  ## API
34
53
 
35
54
  `BoxProps`:
@@ -39,7 +58,8 @@ export function Usage() {
39
58
  | `padding` | `Responsive<Space>` | | Padding on every side. Responsive. |
40
59
  | `paddingX` | `Responsive<Space>` | | Inline (left/right) padding; overrides `padding` on that axis. Responsive. |
41
60
  | `paddingY` | `Responsive<Space>` | | Block (top/bottom) padding; overrides `padding` on that axis. Responsive. |
42
- | `surface` | `'none' \| 'surface' \| 'canvas' \| 'sunken' \| 'raised' \| 'inverse' \| 'cat-6' \| 'cat-3' \| 'cat-5' \| 'cat-1' \| 'cat-2' \| 'cat-4' \| 'cat-7' \| 'cat-8'` | `none` | Background fill. `inverse` and the categorical `cat-1` to `cat-8` (one person's or team's colour, matching their `Tag`) also re-point ink and line colours for its children. |
61
+ | `surface` | `'none' \| 'accent' \| 'surface' \| 'canvas' \| 'sunken' \| 'raised' \| 'inverse' \| 'cat-6' \| 'cat-3' \| 'cat-5' \| 'cat-1' \| 'cat-2' \| 'cat-4' \| 'cat-7' \| 'cat-8'` | `none` | Background fill. `inverse`, `accent` and the categorical `cat-1` to `cat-8` (one person's or team's colour, matching their `Tag`) also re-point ink, line and accent colours for its children, so they stay legible on the fill. |
62
+ | `adaptTones` | `boolean` | `false` | On an `inverse`, `accent` or categorical fill, re-point the status tones too, so tone text and soft tone fills (a `Stat` delta, a toned `Numeral` or `Text`, a soft `Badge`) stay AA on the fill. On `accent` and categorical fills tone text becomes the fill's ink, so the sign, glyph or label carries the status; on `inverse` each tone keeps its hue. Off by default, so tones keep the page's colours. No effect on other surfaces. |
43
63
  | `border` | `boolean` | `false` | Hairline border in `--color-line`. One edge treatment per element — a border *or* a fill. |
44
64
  | `radius` | `'none' \| 'surface' \| 'field' \| 'media'` | `none` | Corner radius, by role. |
45
65
  | `as` | `'div' \| 'section' \| 'article' \| 'aside' \| 'header' \| 'footer' \| 'li' \| 'span'` | `div` | |
@@ -0,0 +1,68 @@
1
+ <!-- Generated from the Kiln docs by apps/docs/src/skills. Edit the docs pages, then run `pnpm generate:skills`. -->
2
+
3
+ # ScrollArea
4
+
5
+ > A scroll container for content wider or taller than the page, such as a bracket, a timeline or a wide board, that keyboard users can reach and scroll.
6
+
7
+ Source: https://kiln.mitchellsutton.com/docs/ui/layout/scroll-area
8
+
9
+ `ScrollArea` lets one wide thing scroll on its own instead of pushing the page sideways. Give it a `label` and it's a named region in the tab order, so someone without a mouse or touch screen can focus it and scroll with the arrow keys. The scrollbar takes the theme's line colour.
10
+
11
+ A data table doesn't need one: `Table` scrolls sideways itself, and takes the same `label`.
12
+
13
+ Something wider than the page, such as a knockout bracket, scrolls inside a `ScrollArea` instead of pushing the page sideways. Its `label` makes it a named region that keyboard users can focus and scroll with the arrow keys.
14
+
15
+ ```tsx
16
+ import { Badge, Card, Inline, ScrollArea, Stack, Text } from '@mitcsutt/kiln-ui'
17
+
18
+ const ROUNDS = [
19
+ { round: 'Round of 16', ties: ['Kelso Bay 2–1 Old Quay', 'Harbour Square 0–0 Marram Point'] },
20
+ { round: 'Quarter-finals', ties: ['Kelso Bay 3–2 North Point', 'Harbour Square 1–0 Eastgate'] },
21
+ { round: 'Semi-finals', ties: ['Kelso Bay 1–1 Harbour Square'] },
22
+ { round: 'Final', ties: ['Saturday 14:00 at Harbour Park'] },
23
+ ]
24
+
25
+ export function Usage() {
26
+ return (
27
+ <ScrollArea label="Knockout rounds">
28
+ <Inline gap={4} wrap={false}>
29
+ {ROUNDS.map((r) => (
30
+ <Card key={r.round}>
31
+ <Card.Body>
32
+ <Stack gap={2} align="start">
33
+ <Text weight="medium">{r.round}</Text>
34
+ {r.ties.map((tie) => (
35
+ <Badge key={tie} variant="outline">
36
+ {tie}
37
+ </Badge>
38
+ ))}
39
+ </Stack>
40
+ </Card.Body>
41
+ </Card>
42
+ ))}
43
+ </Inline>
44
+ </ScrollArea>
45
+ )
46
+ }
47
+ ```
48
+
49
+ ## API
50
+
51
+ `ScrollAreaProps`:
52
+
53
+ | Prop | Type | Default | Description |
54
+ | --- | --- | --- | --- |
55
+ | `label` | `string` | | Names the area. With a name (this, or `aria-labelledby`) it becomes a labelled region that keyboard users can focus and scroll with the arrow keys. |
56
+ | `axis` | `'both' \| 'x' \| 'y'` | `x` | Which way it scrolls. On `x` and `both` the content keeps its natural width, so a row of cards scrolls instead of squeezing. `y` and `both` scroll once a parent gives the area a height (a grid row, a pane). Default `x`. |
57
+ | `hideBelow` | `'sm' \| 'md' \| 'lg' \| 'xl'` | | Hide below this breakpoint (e.g. `md` → hidden on phones, shown from 48em). |
58
+ | `hideAbove` | `'sm' \| 'md' \| 'lg' \| 'xl'` | | Hide from this breakpoint up (e.g. `md` → shown on phones only). |
59
+
60
+ Also accepts every prop of `HTMLAttributes<HTMLDivElement>`.
61
+
62
+ ### Component tokens
63
+
64
+ Set these in a theme, or on one element, to change this component without touching the rest.
65
+
66
+ | Token | Default and use |
67
+ | --- | --- |
68
+ | `--scroll-area-thumb` | default var(--color-line-strong) — the scrollbar's thumb |
@@ -62,7 +62,7 @@ export function CategoricalBand() {
62
62
 
63
63
  ## Surfaces and bands
64
64
 
65
- `surface` is `canvas`, `surface`, `sunken`, `inverse`, `accent`, or a categorical `cat-1` to `cat-8` (a band in one person's or team's colour, matching their `Tag`). On `inverse`, `accent` and the categorical bands, the colour roles flip for everything inside, so text, links, focus rings and buttons stay legible with no extra props. `divider` adds a rule at the `top`, `bottom` or `both`.
65
+ `surface` is `canvas`, `surface`, `sunken`, `inverse`, `accent`, or a categorical `cat-1` to `cat-8` (a band in one person's or team's colour, matching their `Tag`). On `inverse`, `accent` and the categorical bands, the colour roles flip for everything inside, so text, links, focus rings and buttons stay legible with no extra props. Add `adaptTones` to flip the status tones too. `divider` adds a rule at the `top`, `bottom` or `both`.
66
66
 
67
67
  ## API
68
68
 
@@ -72,6 +72,7 @@ export function CategoricalBand() {
72
72
  | --- | --- | --- | --- |
73
73
  | `space` | `Responsive<Space>` | `8` | Block padding (top and bottom), as a step on the space scale. Responsive. Vary it: adjacent sections should not share the same step. Default `8`. |
74
74
  | `surface` | `'accent' \| 'surface' \| 'canvas' \| 'sunken' \| 'inverse' \| 'cat-6' \| 'cat-3' \| 'cat-5' \| 'cat-1' \| 'cat-2' \| 'cat-4' \| 'cat-7' \| 'cat-8'` | | Full-bleed band colour. Omit to stay transparent on the canvas. `inverse`, `accent` and the categorical `cat-1` to `cat-8` re-point the ink, line and focus colours so children stay legible. |
75
+ | `adaptTones` | `boolean` | `false` | On an `inverse`, `accent` or categorical band, re-point the status tones too, so tone text and soft tone fills (a `Stat` delta, a toned `Numeral` or `Text`, a soft `Badge`) stay AA on the band. On `accent` and categorical bands tone text becomes the band's ink, so the sign, glyph or label carries the status; on `inverse` each tone keeps its hue. Off by default, so tones keep the page's colours. No effect on other surfaces. |
75
76
  | `divider` | `'top' \| 'bottom' \| 'both'` | | A hairline across the full bleed at the top, bottom or both edges. |
76
77
  | `as` | `'div' \| 'section' \| 'article' \| 'aside' \| 'header' \| 'footer'` | `section` | |
77
78
  | `hideBelow` | `'sm' \| 'md' \| 'lg' \| 'xl'` | | Hide below this breakpoint (e.g. `md` → hidden on phones, shown from 48em). |
@@ -226,6 +226,7 @@ Merges class names, filtering falsy values.
226
226
  - [Tokens](https://kiln.mitchellsutton.com/docs/ui/foundations/tokens): the contract every theme fills in.
227
227
  - [Theming](https://kiln.mitchellsutton.com/docs/ui/foundations/theming): write a theme of your own.
228
228
  - [Button](https://kiln.mitchellsutton.com/docs/ui/actions/button): the reference component.
229
+ - [AI tooling](https://kiln.mitchellsutton.com/docs/tooling/ai): the agent skills that ship with kiln-ui, and how to load them into your coding agent.
229
230
 
230
231
  ## References
231
232