@karmo-co/drift-kit-reference 0.0.0-stage → 23.5.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 (93) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +24 -2
  3. package/bin/drift-kit-ref.js +197 -0
  4. package/manifest/components/accordion.md +47 -0
  5. package/manifest/components/action-bar.md +51 -0
  6. package/manifest/components/alert.md +53 -0
  7. package/manifest/components/app-shell.md +43 -0
  8. package/manifest/components/avatar.md +42 -0
  9. package/manifest/components/body.md +48 -0
  10. package/manifest/components/box.md +58 -0
  11. package/manifest/components/breadcrumb.md +59 -0
  12. package/manifest/components/button.md +46 -0
  13. package/manifest/components/calendar.md +69 -0
  14. package/manifest/components/card.md +71 -0
  15. package/manifest/components/checkbox.md +43 -0
  16. package/manifest/components/choice-card.md +61 -0
  17. package/manifest/components/code-input.md +56 -0
  18. package/manifest/components/date-picker.md +66 -0
  19. package/manifest/components/day-of-month.md +54 -0
  20. package/manifest/components/detail-list.md +37 -0
  21. package/manifest/components/divider.md +33 -0
  22. package/manifest/components/dropdown.md +52 -0
  23. package/manifest/components/dropzone.md +56 -0
  24. package/manifest/components/eyebrow.md +45 -0
  25. package/manifest/components/feedback-badge.md +35 -0
  26. package/manifest/components/glider.md +34 -0
  27. package/manifest/components/heading.md +47 -0
  28. package/manifest/components/hero.md +46 -0
  29. package/manifest/components/icon-button.md +41 -0
  30. package/manifest/components/icon-tile.md +44 -0
  31. package/manifest/components/icon.md +30 -0
  32. package/manifest/components/input.md +63 -0
  33. package/manifest/components/link.md +42 -0
  34. package/manifest/components/loading-spinner.md +42 -0
  35. package/manifest/components/logo.md +38 -0
  36. package/manifest/components/modal.md +53 -0
  37. package/manifest/components/pagination.md +54 -0
  38. package/manifest/components/payment-form.md +29 -0
  39. package/manifest/components/price-summary.md +30 -0
  40. package/manifest/components/radio.md +42 -0
  41. package/manifest/components/section-heading.md +41 -0
  42. package/manifest/components/select.md +99 -0
  43. package/manifest/components/shield.md +34 -0
  44. package/manifest/components/sidebar.md +73 -0
  45. package/manifest/components/stepper.md +53 -0
  46. package/manifest/components/switch.md +45 -0
  47. package/manifest/components/table.md +77 -0
  48. package/manifest/components/tabs.md +43 -0
  49. package/manifest/components/tag.md +43 -0
  50. package/manifest/components/textarea.md +52 -0
  51. package/manifest/components/toast.md +52 -0
  52. package/manifest/components/tooltip.md +42 -0
  53. package/manifest/components/top-bar.md +60 -0
  54. package/manifest/components/vehicle.md +43 -0
  55. package/manifest/index.json +1171 -0
  56. package/manifest/migrations/1.0.0.md +50 -0
  57. package/manifest/migrations/10.0.0.md +154 -0
  58. package/manifest/migrations/11.0.0.md +24 -0
  59. package/manifest/migrations/12.0.0.md +38 -0
  60. package/manifest/migrations/13.0.0.md +50 -0
  61. package/manifest/migrations/14.0.0.md +148 -0
  62. package/manifest/migrations/15.0.0.md +140 -0
  63. package/manifest/migrations/16.0.0.md +196 -0
  64. package/manifest/migrations/17.0.0.md +19 -0
  65. package/manifest/migrations/18.0.0.md +23 -0
  66. package/manifest/migrations/19.0.0.md +15 -0
  67. package/manifest/migrations/2.0.0.md +18 -0
  68. package/manifest/migrations/20.0.0.md +43 -0
  69. package/manifest/migrations/21.0.0.md +97 -0
  70. package/manifest/migrations/22.0.0.md +17 -0
  71. package/manifest/migrations/23.0.0.md +86 -0
  72. package/manifest/migrations/3.0.0.md +34 -0
  73. package/manifest/migrations/4.0.0.md +147 -0
  74. package/manifest/migrations/5.0.0.md +73 -0
  75. package/manifest/migrations/6.0.0.md +67 -0
  76. package/manifest/migrations/7.0.0.md +71 -0
  77. package/manifest/migrations/8.0.0.md +16 -0
  78. package/manifest/migrations/9.0.0.md +107 -0
  79. package/manifest/rules.md +37 -0
  80. package/manifest/setup.md +70 -0
  81. package/manifest/tokens/border-width.md +12 -0
  82. package/manifest/tokens/border.md +147 -0
  83. package/manifest/tokens/font.md +90 -0
  84. package/manifest/tokens/icon.md +84 -0
  85. package/manifest/tokens/interactive.md +53 -0
  86. package/manifest/tokens/layout.md +8 -0
  87. package/manifest/tokens/motion.md +97 -0
  88. package/manifest/tokens/radius.md +20 -0
  89. package/manifest/tokens/shadow.md +28 -0
  90. package/manifest/tokens/spacing.md +35 -0
  91. package/manifest/tokens/surface.md +138 -0
  92. package/manifest/tokens/text.md +92 -0
  93. package/package.json +20 -4
@@ -0,0 +1,42 @@
1
+ # Loading spinner (`loading-spinner`)
2
+
3
+ The brand symbol inside a sweeping arc. It spins for at least half a second, so a fast load does not flash, and tells you when it has gone.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ div.dk-component-loading-spinner[data-size="small|medium|large"]?
10
+ span.__message?
11
+ (the arc and the brand symbol are drawn by the runtime)
12
+ ```
13
+
14
+ ## Attributes
15
+
16
+ | Attribute | Values the stylesheet styles |
17
+ |---|---|
18
+ | `data-animation` | `enter`, `exit` |
19
+ | `data-color` | `neutral` |
20
+ | `data-size` | `large`, `small`, `xsmall` |
21
+ | `data-variant` | `ring` |
22
+
23
+ ## React
24
+
25
+ ```tsx
26
+ import { LoadingSpinner } from '@karmo-co/drift-kit/react';
27
+ ```
28
+
29
+ | Prop | Type | Notes |
30
+ |---|---|---|
31
+ | `size` | `'xsmall' \| 'small' \| 'medium' \| 'large'` | |
32
+ | `variant` | `'symbol' \| 'ring'` | |
33
+ | `color` | `'primary' \| 'neutral'` | neutral is grayscale: the arc, and the mark in the symbol variant. |
34
+ | `animation` | `'enter' \| 'exit'` | "enter" shows it; "exit" plays the exit once 500ms have passed since enter, then unmounts and calls onExitComplete. |
35
+ | `onExitComplete` | `() => void` | |
36
+ | `label` | `string` | |
37
+ | `message` | `string` | Text under the spinner, "Loading reports". It is also the accessible name unless label is given. |
38
+ | `brand` | `LogoBrand` | |
39
+
40
+ ## Component tokens
41
+
42
+ `--dk-component-loading-spinner-color`, `--dk-component-loading-spinner-neutral-color`, `--dk-component-loading-spinner-message-gap`, `--dk-component-loading-spinner-message-font-size`, `--dk-component-loading-spinner-message-line-height`, `--dk-component-loading-spinner-message-font-weight`, `--dk-component-loading-spinner-message-color`, `--dk-component-loading-spinner-message-max-width`, `--dk-component-loading-spinner-tail-start`, `--dk-component-loading-spinner-ring-tail-start`, `--dk-component-loading-spinner-ring-xsmall-size`, `--dk-component-loading-spinner-ring-xsmall-stroke`, `--dk-component-loading-spinner-ring-small-size`, `--dk-component-loading-spinner-ring-medium-size`, `--dk-component-loading-spinner-ring-large-size`, `--dk-component-loading-spinner-small-logo-size`, `--dk-component-loading-spinner-small-gap`, `--dk-component-loading-spinner-small-stroke`, `--dk-component-loading-spinner-medium-logo-size`, `--dk-component-loading-spinner-medium-gap`, `--dk-component-loading-spinner-medium-stroke`, `--dk-component-loading-spinner-large-logo-size`, `--dk-component-loading-spinner-large-gap`, `--dk-component-loading-spinner-large-stroke`, `--dk-component-loading-spinner-spin-duration`, `--dk-component-loading-spinner-ring-spin-duration`, `--dk-component-loading-spinner-enter-duration`, `--dk-component-loading-spinner-exit-duration`, `--dk-component-loading-spinner-exit-delay`, `--dk-component-loading-spinner-fade-duration`, `--dk-component-loading-spinner-fade-delay`, `--dk-component-loading-spinner-enter-easing`, `--dk-component-loading-spinner-exit-easing`
@@ -0,0 +1,38 @@
1
+ # Logo (`logo`)
2
+
3
+ The brand mark, as a symbol or with its wordmark, in three colourways.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ span.dk-component-logo[data-brand]?[data-lockup="symbol|symbol-text"]?[data-mode="reverse"]?[data-size]?[role="img"][aria-label]
10
+ (the vectors are drawn by the runtime)
11
+ ```
12
+
13
+ ## Attributes
14
+
15
+ | Attribute | Values the stylesheet styles |
16
+ |---|---|
17
+ | `data-mode` | `neutral`, `reverse` |
18
+ | `data-part` | `primary`, `secondary` |
19
+ | `data-size` | `large`, `medium`, `small`, `xlarge` |
20
+
21
+ ## React
22
+
23
+ ```tsx
24
+ import { Logo } from '@karmo-co/drift-kit/react';
25
+ ```
26
+
27
+ | Prop | Type | Notes |
28
+ |---|---|---|
29
+ | `lockup` | `'symbol' \| 'symbol-text'` | |
30
+ | `mode` | `'default' \| 'reverse' \| 'neutral'` | |
31
+ | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | |
32
+ | `brand` | `LogoBrand` | The runtime reads the nearest data-brand; React cannot, so it is a prop. |
33
+ | `label` | `string` | The accessible name. Defaults to the brand's name. |
34
+ | `decorative` | `boolean` | Hidden from assistive tech, for a logo beside the brand name in text. |
35
+
36
+ ## Component tokens
37
+
38
+ `--dk-component-logo-default-secondary`, `--dk-component-logo-default-primary`, `--dk-component-logo-reverse-secondary`, `--dk-component-logo-reverse-primary`, `--dk-component-logo-neutral-secondary`, `--dk-component-logo-neutral-primary`, `--dk-component-logo-small-height`, `--dk-component-logo-medium-height`, `--dk-component-logo-large-height`, `--dk-component-logo-xlarge-height`
@@ -0,0 +1,53 @@
1
+ # Modal (`modal`)
2
+
3
+ A dialog on a backdrop, and a bottom sheet on a phone. Focus trap, Escape, scroll lock and focus return included.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ div.dk-component-modal[hidden][data-sheet][data-sheet-open][data-closing]
10
+ div.dk-component-modal__backdrop
11
+ div.dk-component-modal__box[data-size][role=dialog][aria-modal=true]
12
+ div.dk-component-modal__header
13
+ span.dk-component-modal__icon > svg
14
+ h2.dk-component-modal__title
15
+ button.dk-component-icon-button[aria-label]
16
+ div.dk-component-modal__body
17
+ div.dk-component-modal__footer
18
+ ```
19
+
20
+ ## Attributes
21
+
22
+ | Attribute | Values the stylesheet styles |
23
+ |---|---|
24
+ | `data-closing` | (present or absent) |
25
+ | `data-sheet` | `always`, `never` |
26
+ | `data-sheet-open` | (present or absent) |
27
+ | `data-size` | `large`, `small`, `xlarge` |
28
+
29
+ ## React
30
+
31
+ ```tsx
32
+ import { Modal } from '@karmo-co/drift-kit/react';
33
+ ```
34
+
35
+ | Prop | Type | Notes |
36
+ |---|---|---|
37
+ | `open` (required) | `boolean` | Controlled: true shows it, false plays its exit. |
38
+ | `onClose` | `() => void` | Called once when the dialog closes ITSELF (Escape, the cross, the backdrop), after its exit, so the parent can set open to false. Not called when the parent closed it. |
39
+ | `size` | `'small' \| 'medium' \| 'large' \| 'xlarge'` | |
40
+ | `sheet` | `'auto' \| 'always' \| 'never'` | |
41
+ | `dismissible` | `boolean` | false: it has to be answered; Escape and the backdrop are both refused. |
42
+ | `backdropDismiss` | `boolean` | false keeps Escape and refuses a click beside it, for a form. |
43
+ | `initialFocus` | `string` | A selector inside the box to focus on open. |
44
+ | `title` | `ReactNode` | |
45
+ | `icon` | `ReactNode` | |
46
+ | `footer` | `ReactNode` | |
47
+ | `showClose` | `boolean` | The header's cross. On unless dismissible is false. |
48
+ | `closeLabel` | `string` | |
49
+ | `children` | `ReactNode` | |
50
+
51
+ ## Component tokens
52
+
53
+ `--dk-component-modal-small-width`, `--dk-component-modal-width`, `--dk-component-modal-large-width`, `--dk-component-modal-xlarge-width`, `--dk-component-modal-radius`, `--dk-component-modal-surface`, `--dk-component-modal-border`, `--dk-component-modal-border-width`, `--dk-component-modal-shadow`, `--dk-component-modal-inset`, `--dk-component-modal-max-height`, `--dk-component-modal-backdrop`, `--dk-component-modal-padding-inline`, `--dk-component-modal-header-padding-block`, `--dk-component-modal-body-padding-block`, `--dk-component-modal-footer-padding-block`, `--dk-component-modal-body-gap`, `--dk-component-modal-footer-gap`, `--dk-component-modal-header-gap`, `--dk-component-modal-divider`, `--dk-component-modal-title-font-size`, `--dk-component-modal-title-line-height`, `--dk-component-modal-title-font-weight`, `--dk-component-modal-title-color`, `--dk-component-modal-icon-size`, `--dk-component-modal-icon-color`, `--dk-component-modal-sheet-max-height`, `--dk-component-modal-sheet-max-width`, `--dk-component-modal-sheet-radius`, `--dk-component-modal-sheet-action-height`, `--dk-component-modal-sheet-action-min`, `--dk-component-modal-enter-duration`, `--dk-component-modal-exit-duration`, `--dk-component-modal-enter-easing`, `--dk-component-modal-exit-easing`, `--dk-component-modal-enter-travel`
@@ -0,0 +1,54 @@
1
+ # Pagination (`pagination`)
2
+
3
+ Where a long list is in pages, and the way to the others: a page list between two arrows, with an optional count of what is showing and a rows select.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ nav.dk-component-pagination[data-page][data-pages|data-total][data-page-size]
10
+ [data-size][data-href] (aria-label)
11
+ p.dk-component-pagination__summary (optional, filled by the runtime)
12
+ div.dk-component-pagination__rows (optional)
13
+ span.dk-component-pagination__rows-label
14
+ div.dk-component-select[data-size] (a kit Select: 20, 50, 100)
15
+ div.dk-component-pagination__pages (drawn by the runtime)
16
+ button.dk-component-icon-button.__prev (ghost, the pagination's size)
17
+ ol.dk-component-pagination__list
18
+ li > button.__page[aria-current="page"] (or a.__page in link mode)
19
+ li > span.__gap (aria-hidden)
20
+ span.dk-component-pagination__status ("Page 3 of 12", phone only)
21
+ button.dk-component-icon-button.__next
22
+ ```
23
+
24
+ ## Attributes
25
+
26
+ | Attribute | Values the stylesheet styles |
27
+ |---|---|
28
+ | `data-pseudo-class` | `active`, `focus`, `hover` |
29
+ | `data-size` | `large`, `medium`, `small` |
30
+
31
+ ## React
32
+
33
+ ```tsx
34
+ import { Pagination } from '@karmo-co/drift-kit/react';
35
+ ```
36
+
37
+ | Prop | Type | Notes |
38
+ |---|---|---|
39
+ | `page` (required) | `number` | The current page, from 1. Controlled: it shows what you pass. |
40
+ | `pages` | `number` | The page count. Or pass total and pageSize, and it is worked out. |
41
+ | `total` | `number` | |
42
+ | `pageSize` | `number` | |
43
+ | `onPageChange` | `(page: number) => void` | A button was pressed for another page. |
44
+ | `pageSizes` | `number[]` | The choices in the rows select, which shows when onPageSizeChange is passed. [20, 50, 100] when absent. |
45
+ | `onPageSizeChange` | `(pageSize: number, page: number) => void` | The new size, and the page that keeps the first row on screen: row 81 was first on page 5 of 20s, and is on page 2 of 50s. |
46
+ | `rowsLabel` | `ReactNode` | The words beside the rows select. |
47
+ | `summary` | `boolean` | "Showing 41–60 of 234". On when total and pageSize are known. |
48
+ | `href` | `(page: number) => string` | Pages as links: the URL for page n. The page loads the next one itself. |
49
+ | `size` | `'small' \| 'medium' \| 'large'` | medium when absent. The arrows take the same size. |
50
+ | `messages` | `Partial<PaginationMessages>` | |
51
+
52
+ ## Component tokens
53
+
54
+ `--dk-component-pagination-small-padding`, `--dk-component-pagination-small-line-height`, `--dk-component-pagination-small-font-size`, `--dk-component-pagination-small-border-radius`, `--dk-component-pagination-padding`, `--dk-component-pagination-line-height`, `--dk-component-pagination-font-size`, `--dk-component-pagination-border-radius`, `--dk-component-pagination-large-padding`, `--dk-component-pagination-large-line-height`, `--dk-component-pagination-large-font-size`, `--dk-component-pagination-large-border-radius`, `--dk-component-pagination-gap`, `--dk-component-pagination-section-gap`, `--dk-component-pagination-font-family`, `--dk-component-pagination-page-font-weight`, `--dk-component-pagination-page-text`, `--dk-component-pagination-page-text-hover`, `--dk-component-pagination-page-surface-hover`, `--dk-component-pagination-page-surface-active`, `--dk-component-pagination-press-scale`, `--dk-component-pagination-current-surface`, `--dk-component-pagination-current-surface-hover`, `--dk-component-pagination-current-surface-active`, `--dk-component-pagination-current-text`, `--dk-component-pagination-current-font-weight`, `--dk-component-pagination-gap-text`, `--dk-component-pagination-summary-text`, `--dk-component-pagination-summary-font-size`, `--dk-component-pagination-summary-line-height`, `--dk-component-pagination-focus-ring-width`, `--dk-component-pagination-focus-ring`
@@ -0,0 +1,29 @@
1
+ # Payment form (`payment-form`)
2
+
3
+ Stripe's Payment Element on the kit's tokens: its fields, labels, tabs and errors follow the theme, the surface and the tone around them, like any kit field.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ div.dk-component-payment-form
10
+ div.dk-component-payment-form__element (mount the Payment Element here)
11
+ p.dk-component-payment-form__error (optional, role="alert")
12
+ div.dk-component-payment-form__actions (optional: Pay, Back)
13
+ ```
14
+
15
+ ## React
16
+
17
+ ```tsx
18
+ import { PaymentForm } from '@karmo-co/drift-kit/react';
19
+ ```
20
+
21
+ | Prop | Type | Notes |
22
+ |---|---|---|
23
+ | `children` | `ReactNode` | The Payment Element (inside Stripe's <Elements>). |
24
+ | `error` | `ReactNode` | The message under it: a decline, a failed confirmation. |
25
+ | `actions` | `ReactNode` | Pay, Back: usually kit Buttons. |
26
+
27
+ ## Component tokens
28
+
29
+ `--dk-component-payment-form-font-family`, `--dk-component-payment-form-font-size`, `--dk-component-payment-form-spacing-unit`, `--dk-component-payment-form-radius`, `--dk-component-payment-form-gap`, `--dk-component-payment-form-primary`, `--dk-component-payment-form-surface`, `--dk-component-payment-form-border`, `--dk-component-payment-form-border-hover`, `--dk-component-payment-form-border-focus`, `--dk-component-payment-form-border-width`, `--dk-component-payment-form-ring`, `--dk-component-payment-form-ring-width`, `--dk-component-payment-form-padding-block`, `--dk-component-payment-form-padding-inline`, `--dk-component-payment-form-text`, `--dk-component-payment-form-text-secondary`, `--dk-component-payment-form-placeholder`, `--dk-component-payment-form-danger`, `--dk-component-payment-form-icon`, `--dk-component-payment-form-label-color`, `--dk-component-payment-form-label-font-size`, `--dk-component-payment-form-label-font-weight`, `--dk-component-payment-form-label-letter-spacing`, `--dk-component-payment-form-tab-surface`, `--dk-component-payment-form-tab-surface-hover`, `--dk-component-payment-form-tab-border`, `--dk-component-payment-form-tab-selected-surface`, `--dk-component-payment-form-tab-selected-surface-hover`, `--dk-component-payment-form-tab-selected-border`, `--dk-component-payment-form-tab-selected-text`, `--dk-component-payment-form-error-font-size`, `--dk-component-payment-form-error-line-height`, `--dk-component-payment-form-element-min-height`
@@ -0,0 +1,30 @@
1
+ # Price summary (`price-summary`)
2
+
3
+ Labelled amounts on hairlines, then their total with a note under it. Credits in the brand tone.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ dl.dk-component-price-summary
10
+ div.__row dt.__label + dd.__amount[data-tone="credit"]?
11
+ …
12
+ div.__row[data-total] dt.__label + dd.__amount (+ span.__note?)
13
+ ```
14
+
15
+ ## Attributes
16
+
17
+ | Attribute | Values the stylesheet styles |
18
+ |---|---|
19
+ | `data-tone` | `credit` |
20
+ | `data-total` | (present or absent) |
21
+
22
+ ## React
23
+
24
+ ```tsx
25
+ import { PriceSummary } from '@karmo-co/drift-kit/react';
26
+ ```
27
+
28
+ ## Component tokens
29
+
30
+ `--dk-component-price-summary-font-family`, `--dk-component-price-summary-divider`, `--dk-component-price-summary-divider-width`, `--dk-component-price-summary-row-gap`, `--dk-component-price-summary-row-padding-block`, `--dk-component-price-summary-total-padding-block`, `--dk-component-price-summary-label-font-size`, `--dk-component-price-summary-label-line-height`, `--dk-component-price-summary-label-font-weight`, `--dk-component-price-summary-label-letter-spacing`, `--dk-component-price-summary-label-color`, `--dk-component-price-summary-amount-font-size`, `--dk-component-price-summary-amount-line-height`, `--dk-component-price-summary-amount-font-weight`, `--dk-component-price-summary-amount-color`, `--dk-component-price-summary-credit-color`, `--dk-component-price-summary-total-label-font-size`, `--dk-component-price-summary-total-label-line-height`, `--dk-component-price-summary-total-label-color`, `--dk-component-price-summary-total-amount-font-size`, `--dk-component-price-summary-total-amount-line-height`, `--dk-component-price-summary-total-amount-color`, `--dk-component-price-summary-note-font-size`, `--dk-component-price-summary-note-line-height`, `--dk-component-price-summary-note-font-weight`, `--dk-component-price-summary-note-color`
@@ -0,0 +1,42 @@
1
+ # Radio (`radio`)
2
+
3
+ One of these, and only one. Checkbox's twin, with a circular box, a drawn dot and a group that is not optional.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ label.dk-component-radio[data-size]
10
+ span.dk-component-radio__box
11
+ input.dk-component-radio__input
12
+ span.dk-component-radio__indicator
13
+ span.dk-component-radio__text
14
+ span.dk-component-radio__label
15
+ span.dk-component-radio__desc
16
+ ```
17
+
18
+ ## Attributes
19
+
20
+ | Attribute | Values the stylesheet styles |
21
+ |---|---|
22
+ | `data-orientation` | `horizontal` |
23
+ | `data-pseudo-class` | `active`, `focus`, `hover` |
24
+ | `data-size` | `large`, `small` |
25
+
26
+ ## React
27
+
28
+ ```tsx
29
+ import { Radio } from '@karmo-co/drift-kit/react';
30
+ ```
31
+
32
+ | Prop | Type | Notes |
33
+ |---|---|---|
34
+ | `label` | `ReactNode` | The visible label. OPTIONAL, unlike Input's, and the difference is real rather than an oversight: a select row checkbox in a table, a select all in its header and a radio in a comparison grid all take their name from the column or the row they sit in, and printing it beside every one of them would be noise. Omit it and the control collapses to its box. WITHOUT IT THE NAME HAS TO COME FROM SOMEWHERE ELSE. Pass aria-label, or aria-labelledby pointing at the heading that already says it. A checkbox with neither is a control a screen reader announces as "checkbox" and nothing more, which is the one shape this must not make easy. |
35
+ | `size` | `'small' \| 'medium' \| 'large'` | |
36
+ | `description` | `ReactNode` | A second line under the label. The control's DESCRIPTION, never part of its name: it is rendered outside the <label>'s naming path and wired with aria-describedby, so a screen reader announces "Marketing emails, checkbox, not checked" and then the explanation, rather than running the two together. |
37
+ | `invalid` | `boolean` | The invalid state. A boolean here rather than Input's message-carrying `error`, because a single checkbox's message belongs to the group it sits in: see CheckboxGroup and RadioGroup, which render it once for the set. |
38
+ | `className` | `string` | |
39
+
40
+ ## Component tokens
41
+
42
+ `--dk-component-radio-size`, `--dk-component-radio-small-size`, `--dk-component-radio-large-size`, `--dk-component-radio-glyph-size`, `--dk-component-radio-glyph-enter-delay`, `--dk-component-radio-glyph-enter-duration`, `--dk-component-radio-glyph-enter-easing`, `--dk-component-radio-glyph-exit-duration`, `--dk-component-radio-glyph-exit-easing`, `--dk-component-radio-small-glyph-size`, `--dk-component-radio-large-glyph-size`, `--dk-component-radio-radius`, `--dk-component-radio-border-width`, `--dk-component-radio-focus-ring-width`, `--dk-component-radio-gap`, `--dk-component-radio-text-gap`, `--dk-component-radio-group-gap`, `--dk-component-radio-group-legend-gap`, `--dk-component-radio-group-row-gap`, `--dk-component-radio-label-font-family`, `--dk-component-radio-label-font-size`, `--dk-component-radio-label-line-height`, `--dk-component-radio-small-label-font-size`, `--dk-component-radio-small-label-line-height`, `--dk-component-radio-large-label-font-size`, `--dk-component-radio-large-label-line-height`, `--dk-component-radio-label-font-weight`, `--dk-component-radio-desc-font-weight`, `--dk-component-radio-surface-default`, `--dk-component-radio-surface-hover`, `--dk-component-radio-surface-active`, `--dk-component-radio-border-default`, `--dk-component-radio-border-hover`, `--dk-component-radio-border-active`, `--dk-component-radio-checked-surface-default`, `--dk-component-radio-checked-surface-hover`, `--dk-component-radio-checked-surface-active`, `--dk-component-radio-checked-border-default`, `--dk-component-radio-checked-border-hover`, `--dk-component-radio-checked-border-active`, `--dk-component-radio-glyph`, `--dk-component-radio-halo`, `--dk-component-radio-halo-width`, `--dk-component-radio-ring`, `--dk-component-radio-focus-border`, `--dk-component-radio-error-border-default`, `--dk-component-radio-error-border-hover`, `--dk-component-radio-error-ring`, `--dk-component-radio-error-color`, `--dk-component-radio-disabled-surface`, `--dk-component-radio-disabled-border`, `--dk-component-radio-disabled-checked-surface`, `--dk-component-radio-disabled-checked-border`, `--dk-component-radio-disabled-glyph`, `--dk-component-radio-label-color`, `--dk-component-radio-desc-color`, `--dk-component-radio-disabled-label-color`, `--dk-component-radio-disabled-desc-color`, `--dk-component-radio-legend-color`
@@ -0,0 +1,41 @@
1
+ # Section heading (`section-heading`)
2
+
3
+ A glyph beside a title and a line under it, heading a list or a card from outside.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ div.dk-component-section-heading[data-size][data-tone]
10
+ span.__icon? a kit Icon, a Lucide <i>, an <svg>
11
+ div.__content
12
+ h2..h6.__title the author's level (h1 for a page's at large)
13
+ p.__description?
14
+ ```
15
+
16
+ ## Attributes
17
+
18
+ | Attribute | Values the stylesheet styles |
19
+ |---|---|
20
+ | `data-size` | `large`, `medium` |
21
+ | `data-tone` | `neutral` |
22
+
23
+ ## React
24
+
25
+ ```tsx
26
+ import { SectionHeading } from '@karmo-co/drift-kit/react';
27
+ ```
28
+
29
+ | Prop | Type | Notes |
30
+ |---|---|---|
31
+ | `title` (required) | `ReactNode` | |
32
+ | `titleAs` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | The level in the page's outline; the size is separate. h2 when absent. |
33
+ | `titleId` | `string` | The title's own id, so a list or card under it can be named by the title alone (aria-labelledby). An id on the component names the whole block, description and all. |
34
+ | `description` | `ReactNode` | A line under the title. |
35
+ | `icon` | `ReactNode` | A glyph beside it, decorative: the title says what the section is. |
36
+ | `size` | `'small' \| 'medium' \| 'large'` | small (the default) heads a list or a card; medium a group of cards; large is a page's own heading. |
37
+ | `tone` | `'neutral'` | The glyph is primary; neutral is the grey one. |
38
+
39
+ ## Component tokens
40
+
41
+ `--dk-component-section-heading-gap`, `--dk-component-section-heading-content-gap`, `--dk-component-section-heading-title-color`, `--dk-component-section-heading-title-font-family`, `--dk-component-section-heading-title-font-weight`, `--dk-component-section-heading-description-color`, `--dk-component-section-heading-description-font-weight`, `--dk-component-section-heading-icon-color`, `--dk-component-section-heading-icon-neutral-color`, `--dk-component-section-heading-small-icon-size`, `--dk-component-section-heading-small-title-font-size`, `--dk-component-section-heading-small-title-line-height`, `--dk-component-section-heading-small-description-font-size`, `--dk-component-section-heading-small-description-line-height`, `--dk-component-section-heading-medium-icon-size`, `--dk-component-section-heading-medium-title-font-size`, `--dk-component-section-heading-medium-title-line-height`, `--dk-component-section-heading-medium-description-font-size`, `--dk-component-section-heading-medium-description-line-height`, `--dk-component-section-heading-large-gap`, `--dk-component-section-heading-large-content-gap`, `--dk-component-section-heading-large-icon-size`, `--dk-component-section-heading-large-title-font-family`, `--dk-component-section-heading-large-title-font-weight`, `--dk-component-section-heading-large-title-font-size`, `--dk-component-section-heading-large-title-line-height`, `--dk-component-section-heading-large-description-font-size`, `--dk-component-section-heading-large-description-line-height`
@@ -0,0 +1,99 @@
1
+ # Select (`select`)
2
+
3
+ One value from a list. A field-shaped trigger, a floating listbox, and the keyboard that drives both.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ div.dk-component-select[data-size][data-open][data-selected]
10
+ label.dk-component-select__label (optional, + __req)
11
+ input[type=hidden] (the form value)
12
+ button.dk-component-select__trigger (role=combobox)
13
+ span.dk-component-select__chips (built by the behaviour, [data-multiple] only)
14
+ span.dk-component-select__chip
15
+ span.dk-component-select__chip-label
16
+ span.dk-component-select__chip-remove (aria-hidden, a picture not a button)
17
+ span.dk-component-select__value ([data-empty] when unchosen)
18
+ span.dk-component-select__value-icon (optional)
19
+ span.dk-component-select__value-label
20
+ svg.dk-component-select__chevron
21
+ div.dk-component-select__menu (role=listbox, portalled)
22
+ div.dk-component-select__search (built by the behaviour, [data-search] only)
23
+ input.dk-component-select__search-input (role=combobox; the menu becomes a
24
+ div.dk-component-select__list presentation wrapper and the LIST is the listbox)
25
+ div.dk-component-select__group (optional)
26
+ span.dk-component-select__group-label
27
+ button.dk-component-select__option (role=option)
28
+ span.dk-component-select__option-main
29
+ span.dk-component-select__option-meta (optional, right-aligned)
30
+ span.dk-component-select__option-icon (optional)
31
+ span.dk-component-select__option-text
32
+ span.dk-component-select__option-label
33
+ span.dk-component-select__option-desc (optional)
34
+ svg.dk-component-select__check
35
+ p.dk-component-select__empty (optional)
36
+ p.dk-component-select__caption (optional)
37
+ p.dk-component-select__error (optional)
38
+ ```
39
+
40
+ ## Attributes
41
+
42
+ | Attribute | Values the stylesheet styles |
43
+ |---|---|
44
+ | `data-active` | (present or absent) |
45
+ | `data-appearance` | `sentence` |
46
+ | `data-clearable` | (present or absent) |
47
+ | `data-closing` | (present or absent) |
48
+ | `data-empty` | (present or absent) |
49
+ | `data-layout` | `grid` |
50
+ | `data-loading` | (present or absent) |
51
+ | `data-multiple` | (present or absent) |
52
+ | `data-nav` | `keyboard` |
53
+ | `data-open` | (present or absent) |
54
+ | `data-pseudo-class` | `active`, `focus`, `hover` |
55
+ | `data-raised` | (present or absent) |
56
+ | `data-searchable` | (present or absent) |
57
+ | `data-selected` | (present or absent) |
58
+ | `data-sheet-closing` | (present or absent) |
59
+ | `data-sheet-open` | (present or absent) |
60
+ | `data-size` | `large`, `small` |
61
+ | `data-tone` | `error`, `information`, `primary`, `success`, `warning` |
62
+ | `data-variant` | `inset`, `raised` |
63
+
64
+ ## React
65
+
66
+ ```tsx
67
+ import { Select } from '@karmo-co/drift-kit/react';
68
+ ```
69
+
70
+ | Prop | Type | Notes |
71
+ |---|---|---|
72
+ | `options` (required) | `SelectOption[]` | |
73
+ | `label` | `ReactNode` | The visible label. Optional, like Checkbox's and for the same reason: a select in a toolbar takes its name from what it sits in. Without one, pass aria-label. |
74
+ | `size` | `'small' \| 'medium' \| 'large'` | |
75
+ | `caption` | `ReactNode` | Helper text, wired as the control's description. |
76
+ | `error` | `ReactNode` | The message AND the invalid state, exactly as Input spells it: one prop, so the border, the words and aria-invalid cannot disagree. |
77
+ | `placeholder` | `string` | What the trigger says before anything is chosen. |
78
+ | `defaultValue` | `string \| string[]` | UNCONTROLLED ONLY, and that is deliberate rather than unfinished. The menu is built and mutated by behaviour.js in DOM React does not own, so a `value` prop would be a promise this component cannot keep: React would re-render the trigger's contents from props and the helper would write over them on the next selection. defaultValue seeds it, onChange reports it, and the DOM is the source of truth in between. |
79
+ | `onChange` | `(value: string \| string[]) => void` | |
80
+ | `multiple` | `boolean` | SEVERAL VALUES AT ONCE. The trigger holds a chip per value and grows as they wrap, choosing does not close the menu, and onChange reports an array. defaultValue takes one too. The control's shape follows the mode rather than making every caller ask, which is why these are unions: a multi-select that reported a string would be lying about what it holds. |
81
+ | `search` | `boolean` | Puts a search field at the top of the POPUP, which keeps this the select-only combobox it already is: the trigger still shows a value and still opens, and the thing that takes typing exists only while the list is up. Worth it once a list stops being readable at a glance — the country case, where typeahead finds what you can spell and nothing else. |
82
+ | `searchPlaceholder` | `string` | |
83
+ | `clearable` | `boolean` | A cross on the trigger that puts the placeholder back. Without one, unchosen is a state the control can leave and never return to. |
84
+ | `loading` | `boolean` | While the options are still arriving. The list says so rather than saying it is empty, which is a different thing and reads as an answer. |
85
+ | `name` | `string` | The name the hidden input posts under, so the control works in an ordinary form. |
86
+ | `required` | `boolean` | |
87
+ | `disabled` | `boolean` | |
88
+ | `raised` | `boolean` | Lifts the trigger off the surface on an elevation instead of sitting flush in it, the same attribute and the same trade as Input's: the shadow is the whole of it, and padding and height still come from the size rung. Kept as an alias of variant="raised". |
89
+ | `variant` | `'plain' \| 'raised' \| 'inset' \| 'default'` | How the trigger separates from the surface, as Input's and Glider's do: plain (the default) sits flush with an edge, raised lifts it on a shadow, inset sinks it into the nested fill with no edge. 'default' is the old name for plain and still renders as it. |
90
+ | `sheet` | `'auto' \| 'always' \| 'never'` | How the menu presents itself on a phone. 'auto', the default, is a bottom sheet below the kit's mobile breakpoint and a dropdown above it. 'never' opts out, for a select inside something that is already a sheet or a full-screen modal. 'always' forces the sheet at any width, which is how the documentation shows it on a desktop. |
91
+ | `layout` | `'list' \| 'grid'` | 'grid' lays the options out as cards in a wider popup, for options that are pictures (VehicleSelect). Up and down move a row, left and right a card. |
92
+ | `appearance` | `'field' \| 'sentence'` | 'sentence' sets the trigger inside a line of text, the value in bold primary ("Every [Monday] of each week"). Name it with label (kept, not shown) or aria-label. |
93
+ | `className` | `string` | |
94
+ | `id` | `string` | |
95
+ | `'aria-label'` | `string` | |
96
+
97
+ ## Component tokens
98
+
99
+ `--dk-component-select-small-padding-y`, `--dk-component-select-padding-y`, `--dk-component-select-large-padding-y`, `--dk-component-select-small-height`, `--dk-component-select-height`, `--dk-component-select-large-height`, `--dk-component-select-padding-inline`, `--dk-component-select-radius`, `--dk-component-select-border-width`, `--dk-component-select-focus-ring-width`, `--dk-component-select-gap`, `--dk-component-select-slot-gap`, `--dk-component-select-chevron-size`, `--dk-component-select-sentence-border`, `--dk-component-select-sentence-surface`, `--dk-component-select-sentence-text`, `--dk-component-select-sentence-font-weight`, `--dk-component-select-sentence-font-size`, `--dk-component-select-sentence-line-height`, `--dk-component-select-sentence-small-font-size`, `--dk-component-select-sentence-small-line-height`, `--dk-component-select-sentence-large-font-size`, `--dk-component-select-sentence-large-line-height`, `--dk-component-select-sentence-padding-inline`, `--dk-component-select-sentence-chevron-size`, `--dk-component-select-sentence-value-min-width`, `--dk-component-select-sentence-margin-inline`, `--dk-component-select-font-family`, `--dk-component-select-font-size`, `--dk-component-select-line-height`, `--dk-component-select-small-font-size`, `--dk-component-select-small-line-height`, `--dk-component-select-large-font-size`, `--dk-component-select-large-line-height`, `--dk-component-select-value-font-weight`, `--dk-component-select-placeholder-font-weight`, `--dk-component-select-label-font-family`, `--dk-component-select-label-font-size`, `--dk-component-select-label-line-height`, `--dk-component-select-label-letter-spacing`, `--dk-component-select-label-font-weight`, `--dk-component-select-label-color`, `--dk-component-select-caption-font-size`, `--dk-component-select-caption-line-height`, `--dk-component-select-caption-color`, `--dk-component-select-error-color`, `--dk-component-select-required-color`, `--dk-component-select-surface-default`, `--dk-component-select-surface-hover`, `--dk-component-select-surface-active`, `--dk-component-select-inset-surface`, `--dk-component-select-inset-surface-hover`, `--dk-component-select-inset-surface-active`, `--dk-component-select-inset-border`, `--dk-component-select-inset-value-color`, `--dk-component-select-inset-placeholder-color`, `--dk-component-select-inset-chevron-color`, `--dk-component-select-inset-chevron-primary`, `--dk-component-select-inset-chevron-success`, `--dk-component-select-inset-chevron-error`, `--dk-component-select-inset-chevron-warning`, `--dk-component-select-inset-chevron-information`, `--dk-component-select-border-default`, `--dk-component-select-border-hover`, `--dk-component-select-border-focus`, `--dk-component-select-ring`, `--dk-component-select-value-color`, `--dk-component-select-placeholder-color`, `--dk-component-select-chevron-color`, `--dk-component-select-chevron-color-hover`, `--dk-component-select-value-icon-color`, `--dk-component-select-raised-shadow`, `--dk-component-select-raised-shadow-hover`, `--dk-component-select-raised-border-default`, `--dk-component-select-raised-border-hover`, `--dk-component-select-raised-border-focus`, `--dk-component-select-error-border-default`, `--dk-component-select-error-border-focus`, `--dk-component-select-error-ring`, `--dk-component-select-disabled-surface`, `--dk-component-select-disabled-border`, `--dk-component-select-disabled-value-color`, `--dk-component-select-disabled-icon-color`, `--dk-component-select-disabled-label-color`, `--dk-component-menu-surface`, `--dk-component-menu-border`, `--dk-component-menu-border-width`, `--dk-component-menu-radius`, `--dk-component-menu-shadow`, `--dk-component-menu-padding-block`, `--dk-component-menu-padding-inline`, `--dk-component-menu-max-height`, `--dk-component-menu-max-width`, `--dk-component-menu-viewport-gap`, `--dk-component-menu-sheet-max-height`, `--dk-component-menu-sheet-radius`, `--dk-component-menu-sheet-padding-block`, `--dk-component-menu-scrim`, `--dk-component-menu-sheet-exit-duration`, `--dk-component-menu-sheet-exit-easing`, `--dk-component-menu-enter-duration`, `--dk-component-menu-enter-easing`, `--dk-component-menu-exit-duration`, `--dk-component-menu-exit-easing`, `--dk-component-menu-motion-offset`, `--dk-component-select-option-touch-height`, `--dk-component-select-sheet-title-color`, `--dk-component-menu-scrollbar-thumb`, `--dk-component-menu-scrollbar-thumb-hover`, `--dk-component-select-chip-gap`, `--dk-component-select-chip-padding-block`, `--dk-component-select-chip-padding-inline`, `--dk-component-select-chip-radius`, `--dk-component-select-chip-surface`, `--dk-component-select-chip-shadow`, `--dk-component-select-chip-surface-hover`, `--dk-component-select-chip-color`, `--dk-component-select-chip-font-size`, `--dk-component-select-chip-line-height`, `--dk-component-select-small-chip-font-size`, `--dk-component-select-small-chip-line-height`, `--dk-component-select-large-chip-font-size`, `--dk-component-select-large-chip-line-height`, `--dk-component-select-chip-remove-size`, `--dk-component-select-chip-remove-icon-size`, `--dk-component-select-chip-remove-radius`, `--dk-component-select-chip-remove-surface`, `--dk-component-select-chip-remove-surface-hover`, `--dk-component-select-chip-remove-surface-active`, `--dk-component-select-chip-remove-color`, `--dk-component-select-chip-remove-color-hover`, `--dk-component-select-chip-remove-color-active`, `--dk-component-select-chip-remove-transform-scale-active`, `--dk-component-select-chips-padding-block`, `--dk-component-select-option-padding-block`, `--dk-component-select-option-padding-inline`, `--dk-component-select-option-radius`, `--dk-component-select-option-gap`, `--dk-component-select-option-transform-scale-active`, `--dk-component-select-option-font-size`, `--dk-component-select-option-line-height`, `--dk-component-select-small-option-font-size`, `--dk-component-select-small-option-line-height`, `--dk-component-select-large-option-font-size`, `--dk-component-select-large-option-line-height`, `--dk-component-select-option-font-weight`, `--dk-component-select-option-color`, `--dk-component-select-option-color-active`, `--dk-component-select-option-color-hover`, `--dk-component-select-option-icon-size`, `--dk-component-select-option-media-width`, `--dk-component-select-value-media-height`, `--dk-component-select-grid-menu-width`, `--dk-component-select-grid-menu-max-height`, `--dk-component-select-grid-card-min`, `--dk-component-select-grid-media-width`, `--dk-component-select-grid-desc-font-size`, `--dk-component-select-grid-desc-line-height`, `--dk-component-select-grid-gap`, `--dk-component-select-grid-card-padding`, `--dk-component-select-grid-card-radius`, `--dk-component-select-grid-card-selected-surface`, `--dk-component-select-grid-card-selected-surface-hover`, `--dk-component-select-grid-card-selected-border`, `--dk-component-select-grid-label-font-size`, `--dk-component-select-grid-label-line-height`, `--dk-component-select-grid-card-selected-width`, `--dk-component-select-option-icon-color`, `--dk-component-select-option-icon-color-hover`, `--dk-component-select-check-size`, `--dk-component-select-check-color`, `--dk-component-select-check-stroke-width`, `--dk-component-select-option-surface-hover`, `--dk-component-select-option-surface-active`, `--dk-component-select-option-disabled-color`, `--dk-component-select-option-disabled-icon-color`, `--dk-component-select-option-desc-color`, `--dk-component-select-option-desc-font-weight`, `--dk-component-select-option-desc-gap`, `--dk-component-select-group-font-size`, `--dk-component-select-group-line-height`, `--dk-component-select-group-letter-spacing`, `--dk-component-select-group-font-weight`, `--dk-component-select-group-color`, `--dk-component-select-group-padding-block`, `--dk-component-select-group-gap`, `--dk-component-select-search-padding-block`, `--dk-component-select-search-gap`, `--dk-component-select-search-font-size`, `--dk-component-select-search-line-height`, `--dk-component-select-small-search-font-size`, `--dk-component-select-small-search-line-height`, `--dk-component-select-large-search-font-size`, `--dk-component-select-large-search-line-height`, `--dk-component-select-search-color`, `--dk-component-select-search-placeholder-color`, `--dk-component-select-search-icon-size`, `--dk-component-select-search-icon-color`, `--dk-component-select-search-border`, `--dk-component-select-search-border-width`, `--dk-component-select-loading-color`, `--dk-component-select-loading-spinner-size`, `--dk-component-select-loading-spinner-track`, `--dk-component-select-loading-spinner-head`, `--dk-component-select-loading-duration`, `--dk-component-select-clear-size`, `--dk-component-select-clear-icon-size`, `--dk-component-select-clear-radius`, `--dk-component-select-clear-surface-hover`, `--dk-component-select-clear-surface-active`, `--dk-component-select-clear-color`, `--dk-component-select-clear-color-hover`, `--dk-component-select-clear-color-active`, `--dk-component-select-clear-transform-scale-active`, `--dk-component-select-option-meta-color`, `--dk-component-select-empty-color`, `--dk-component-select-duration`, `--dk-component-select-duration-fast`, `--dk-component-select-easing`
@@ -0,0 +1,34 @@
1
+ # Shield (`shield`)
2
+
3
+ A shield that scales in, shakes when a code is wrong and pulses a tick in when it is right.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ div.dk-component-shield[data-animation="idle|enter|success|error"]?[data-size]?
10
+ (the vectors are drawn by the runtime)
11
+ ```
12
+
13
+ ## Attributes
14
+
15
+ | Attribute | Values the stylesheet styles |
16
+ |---|---|
17
+ | `data-animation` | `enter`, `error`, `success` |
18
+ | `data-part` | `check`, `fill`, `lock`, `outline` |
19
+
20
+ ## React
21
+
22
+ ```tsx
23
+ import { Shield } from '@karmo-co/drift-kit/react';
24
+ ```
25
+
26
+ | Prop | Type | Notes |
27
+ |---|---|---|
28
+ | `animation` | `'enter' \| 'error' \| 'success'` | Setting the same value again replays it, as in CL. |
29
+ | `replayKey` | `string \| number` | Change it (a counter, an attempt number) to play the same state again: a second wrong code has the same animation as the first, and a prop set to its own value is not a change React can see. |
30
+ | `label` | `string` | |
31
+
32
+ ## Component tokens
33
+
34
+ `--dk-component-shield-size`, `--dk-component-shield-disc`, `--dk-component-shield-body`, `--dk-component-shield-glyph`, `--dk-component-shield-check`, `--dk-component-shield-glyph-scale`, `--dk-component-shield-enter-duration`, `--dk-component-shield-enter-delay`, `--dk-component-shield-enter-easing`, `--dk-component-shield-success-duration`, `--dk-component-shield-check-duration`, `--dk-component-shield-check-delay`, `--dk-component-shield-error-duration`, `--dk-component-shield-error-easing`, `--dk-component-shield-glyph-fade`
@@ -0,0 +1,73 @@
1
+ # Sidebar (`sidebar`)
2
+
3
+ An app's main navigation. A rail on a desktop that collapses to its glyphs, and on a phone a bottom tab bar or a drawer, from one set of markup.
4
+
5
+
6
+ ## Anatomy (HTML)
7
+
8
+ ```text
9
+ nav.dk-component-sidebar[data-collapsed]?
10
+ div.__head > a.__brand > span.__mark + span.__wordmark
11
+ div.__body
12
+ div.__section > span.__heading? + ul.__list > a|button.__item[aria-current]?
13
+ div.__foot
14
+ ul.__list > button.__item.__toggle
15
+ div.dk-component-dropdown.__account > button.__user (an avatar and __user-text)
16
+ ```
17
+
18
+ ## Attributes
19
+
20
+ | Attribute | Values the stylesheet styles |
21
+ |---|---|
22
+ | `data-bar-hidden` | (present or absent) |
23
+ | `data-bar-shown` | (present or absent) |
24
+ | `data-collapsed` | (present or absent) |
25
+ | `data-current-within` | (present or absent) |
26
+ | `data-indicator` | (present or absent) |
27
+ | `data-level` | `2` |
28
+ | `data-nested` | (present or absent) |
29
+ | `data-open` | (present or absent) |
30
+ | `data-panel` | `closed`, `closing`, `filling` |
31
+ | `data-presentation` | `bar`, `drawer`, `rail` |
32
+ | `data-rising` | (present or absent) |
33
+ | `data-sb-carry` | (present or absent) |
34
+ | `data-sb-instant` | (present or absent) |
35
+ | `data-sb-unit` | (present or absent) |
36
+ | `data-space` | (present or absent) |
37
+ | `data-variant` | `floating` |
38
+
39
+ ## React
40
+
41
+ ```tsx
42
+ import { Sidebar } from '@karmo-co/drift-kit/react';
43
+ ```
44
+
45
+ | Prop | Type | Notes |
46
+ |---|---|---|
47
+ | `'aria-label'` | `string` | |
48
+ | `id` | `string` | |
49
+ | `brand` | `{ mark: ReactNode; wordmark?: ReactNode; href?: string; label?: string }` | |
50
+ | `sections` (required) | `SidebarSection[]` | |
51
+ | `panel` | `SidebarPanel` | Nested: the current section's pages in a panel beside the rail. Mark the section's own row current: 'section'. |
52
+ | `footer` | `SidebarItem[]` | Utilities above the user row: Settings, Help. On a phone bar they are in More. |
53
+ | `user` | `SidebarUser` | |
54
+ | `collapsible` | `boolean` | A collapse toggle in the foot. On by default. |
55
+ | `collapsed` | `boolean` | |
56
+ | `defaultCollapsed` | `boolean` | |
57
+ | `onCollapsedChange` | `(collapsed: boolean) => void` | |
58
+ | `persist` | `string` | Remember the collapse in localStorage under this key. |
59
+ | `variant` | `'docked' \| 'floating'` | |
60
+ | `size` | `'medium' \| 'small'` | 'small' steps everything down for an app that needs the room. Medium when absent. |
61
+ | `phone` | `'bar' \| 'drawer' \| 'rail'` | |
62
+ | `device` | `'auto' \| 'phone' \| 'desktop'` | Force a presentation regardless of the screen, as the docs do. |
63
+ | `motion` | `'rise' \| 'simple'` | 'simple' skips the letters' rise: the labels fade. |
64
+ | `panelEnter` | `boolean` | Play the panel's opening on mount, not only when a panel arrives later. The page knows how it was reached; the Sidebar does not. |
65
+ | `moreLabel` | `string` | |
66
+ | `dotLabel` | `string` | What a screen reader hears for an unread dot. "New" when absent. |
67
+ | `renderLink` | `(props: SidebarLinkProps) => ReactElement` | |
68
+ | `theme` | `'light' \| 'dark'` | Dark chrome: 'dark' makes it dark on a light page and one step deeper than a dark one. Everything inside resolves dark, menus included. |
69
+ | `className` | `string` | |
70
+
71
+ ## Component tokens
72
+
73
+ `--dk-component-sidebar-width`, `--dk-component-sidebar-collapsed-width`, `--dk-component-sidebar-padding-block`, `--dk-component-sidebar-padding-inline`, `--dk-component-sidebar-gap`, `--dk-component-sidebar-section-gap`, `--dk-component-sidebar-border-width`, `--dk-component-sidebar-docked-surface`, `--dk-component-sidebar-docked-border`, `--dk-component-sidebar-floating-surface`, `--dk-component-sidebar-floating-border`, `--dk-component-sidebar-floating-radius`, `--dk-component-sidebar-floating-shadow`, `--dk-component-sidebar-floating-inset`, `--dk-component-sidebar-blur`, `--dk-component-sidebar-brand-height`, `--dk-component-sidebar-head-height`, `--dk-component-sidebar-brand-mark-size`, `--dk-component-sidebar-brand-gap`, `--dk-component-sidebar-wordmark-font-family`, `--dk-component-sidebar-wordmark-font-size`, `--dk-component-sidebar-wordmark-font-weight`, `--dk-component-sidebar-wordmark-color`, `--dk-component-sidebar-divider`, `--dk-component-sidebar-item-height`, `--dk-component-sidebar-item-gap`, `--dk-component-sidebar-item-radius`, `--dk-component-sidebar-item-icon-size`, `--dk-component-sidebar-item-font-family`, `--dk-component-sidebar-item-font-size`, `--dk-component-sidebar-item-line-height`, `--dk-component-sidebar-item-font-weight`, `--dk-component-sidebar-item-text`, `--dk-component-sidebar-item-text-hover`, `--dk-component-sidebar-item-text-active`, `--dk-component-sidebar-item-surface-hover`, `--dk-component-sidebar-item-border-hover`, `--dk-component-sidebar-item-surface-active`, `--dk-component-sidebar-item-border-active`, `--dk-component-sidebar-item-text-disabled`, `--dk-component-sidebar-item-press-scale`, `--dk-component-sidebar-bar-press-scale`, `--dk-component-sidebar-focus-ring`, `--dk-component-sidebar-focus-ring-width`, `--dk-component-sidebar-current-surface`, `--dk-component-sidebar-current-surface-hover`, `--dk-component-sidebar-current-border`, `--dk-component-sidebar-current-border-hover`, `--dk-component-sidebar-current-border-active`, `--dk-component-sidebar-current-text`, `--dk-component-sidebar-menu-current-text`, `--dk-component-sidebar-menu-current-font-weight`, `--dk-component-sidebar-child-height`, `--dk-component-sidebar-child-icon-size`, `--dk-component-sidebar-child-inset`, `--dk-component-sidebar-child-gap`, `--dk-component-sidebar-child-font-weight`, `--dk-component-sidebar-guide`, `--dk-component-sidebar-guide-width`, `--dk-component-sidebar-guide-radius`, `--dk-component-sidebar-heading-font-size`, `--dk-component-sidebar-heading-line-height`, `--dk-component-sidebar-heading-font-weight`, `--dk-component-sidebar-heading-letter-spacing`, `--dk-component-sidebar-heading-color`, `--dk-component-sidebar-badge-size`, `--dk-component-sidebar-badge-font-size`, `--dk-component-sidebar-badge-font-weight`, `--dk-component-sidebar-badge-surface`, `--dk-component-sidebar-badge-text`, `--dk-component-sidebar-badge-current-surface`, `--dk-component-sidebar-badge-current-text`, `--dk-component-sidebar-dot-size`, `--dk-component-sidebar-dot-surface`, `--dk-component-sidebar-user-height`, `--dk-component-sidebar-user-avatar-size`, `--dk-component-sidebar-user-text-gap`, `--dk-component-sidebar-user-name-font-size`, `--dk-component-sidebar-user-name-font-weight`, `--dk-component-sidebar-user-name-color`, `--dk-component-sidebar-user-meta-font-size`, `--dk-component-sidebar-user-meta-color`, `--dk-component-sidebar-panel-width`, `--dk-component-sidebar-panel-padding`, `--dk-component-sidebar-panel-radius`, `--dk-component-sidebar-panel-surface`, `--dk-component-sidebar-panel-border`, `--dk-component-sidebar-panel-item-surface-hover`, `--dk-component-sidebar-panel-item-border-hover`, `--dk-component-sidebar-panel-title-font-size`, `--dk-component-sidebar-panel-title-font-weight`, `--dk-component-sidebar-panel-title-color`, `--dk-component-sidebar-scrollbar-size`, `--dk-component-sidebar-scrollbar-thumb`, `--dk-component-sidebar-scrollbar-thumb-hover`, `--dk-component-sidebar-duration`, `--dk-component-sidebar-easing`, `--dk-component-sidebar-rise-duration`, `--dk-component-sidebar-rise-stagger`, `--dk-component-sidebar-rise-row-stagger`, `--dk-component-sidebar-indicator-duration`, `--dk-component-sidebar-group-row-duration`, `--dk-component-sidebar-group-stagger`, `--dk-component-sidebar-group-easing`, `--dk-component-sidebar-panel-duration`, `--dk-component-sidebar-panel-easing`, `--dk-component-sidebar-panel-rows-start`, `--dk-component-sidebar-panel-row-duration`, `--dk-component-sidebar-panel-row-easing`, `--dk-component-sidebar-panel-row-beat`, `--dk-component-sidebar-panel-row-exit-duration`, `--dk-component-sidebar-panel-row-exit-easing`, `--dk-component-sidebar-bar-height`, `--dk-component-sidebar-bar-surface`, `--dk-component-sidebar-bar-border`, `--dk-component-sidebar-bar-shadow`, `--dk-component-sidebar-bar-radius`, `--dk-component-sidebar-bar-inset`, `--dk-component-sidebar-bar-max-width`, `--dk-component-sidebar-bar-font-size`, `--dk-component-sidebar-bar-icon-size`, `--dk-component-sidebar-bar-pill-width`, `--dk-component-sidebar-bar-pill-height`, `--dk-component-sidebar-bar-current-surface`, `--dk-component-sidebar-bar-current-text`, `--dk-component-sidebar-bar-slots`, `--dk-component-sidebar-bar-z-index`, `--dk-component-sidebar-drawer-width`, `--dk-component-sidebar-drawer-shadow`, `--dk-component-sidebar-scrim`, `--dk-component-sidebar-drawer-duration`, `--dk-component-sidebar-drawer-easing`, `--dk-component-sidebar-drawer-z-index`