@bitforgehq/ui 0.3.3 → 0.5.0-next.3

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 (99) hide show
  1. package/CHANGELOG.md +394 -0
  2. package/README.md +14 -14
  3. package/ai/MANIFEST.index.json +101 -2
  4. package/ai/MANIFEST.json +2630 -746
  5. package/ai/REFERENCE.index.json +196 -0
  6. package/ai/REFERENCE.json +1625 -140
  7. package/ai/UI_GUIDE.md +83 -21
  8. package/ai/components/app-frame.md +1 -1
  9. package/ai/components/badge.md +39 -2
  10. package/ai/components/chat-composer.md +357 -0
  11. package/ai/components/chat-message.md +251 -0
  12. package/ai/components/chat-thread.md +521 -0
  13. package/ai/components/checkbox.md +7 -0
  14. package/ai/components/combobox.md +12 -0
  15. package/ai/components/date-input.md +9 -0
  16. package/ai/components/datetime-input.md +2 -0
  17. package/ai/components/field.md +10 -0
  18. package/ai/components/file-input.md +498 -0
  19. package/ai/components/header.md +1 -1
  20. package/ai/components/image-input.md +368 -0
  21. package/ai/components/image-viewer.md +309 -0
  22. package/ai/components/list-item.md +105 -9
  23. package/ai/components/media-card.md +478 -0
  24. package/ai/components/menu-button.md +2 -0
  25. package/ai/components/menu.md +10 -0
  26. package/ai/components/multi-combobox.md +7 -0
  27. package/ai/components/nav-group.md +10 -3
  28. package/ai/components/nav-item.md +11 -2
  29. package/ai/components/number-input.md +2 -7
  30. package/ai/components/popover.md +13 -0
  31. package/ai/components/radio-group.md +6 -0
  32. package/ai/components/segmented.md +14 -2
  33. package/ai/components/select.md +100 -42
  34. package/ai/components/sidebar-toggle.md +16 -9
  35. package/ai/components/sidebar.md +41 -13
  36. package/ai/components/step.md +112 -0
  37. package/ai/components/steps.md +124 -0
  38. package/ai/components/tab-group.md +18 -2
  39. package/ai/components/table.md +115 -4
  40. package/ai/components/theme-menu-button.md +1 -0
  41. package/ai/components/time-input.md +2 -0
  42. package/ai/components/timeline-event.md +144 -0
  43. package/ai/components/timeline.md +201 -0
  44. package/ai/components/toggle.md +11 -1
  45. package/ai/components/toolbar.md +7 -18
  46. package/ai/reference/bf-action-directive.md +3 -1
  47. package/ai/reference/bf-badge-emphasis.md +27 -0
  48. package/ai/reference/bf-chat-composer-harness.md +64 -0
  49. package/ai/reference/bf-chat-message-role.md +27 -0
  50. package/ai/reference/bf-chat-message-status.md +28 -0
  51. package/ai/reference/bf-fade-in-directive.md +18 -0
  52. package/ai/reference/bf-file-input-harness.md +67 -0
  53. package/ai/reference/bf-file-input-variant.md +27 -0
  54. package/ai/reference/bf-image-input-harness.md +67 -0
  55. package/ai/reference/bf-image-input-shape.md +27 -0
  56. package/ai/reference/bf-image-viewer-actions-context.md +29 -0
  57. package/ai/reference/bf-image-viewer-harness.md +87 -0
  58. package/ai/reference/bf-image-viewer-image.md +25 -0
  59. package/ai/reference/bf-image-viewer-options.md +33 -0
  60. package/ai/reference/bf-image-viewer-origin.md +23 -0
  61. package/ai/reference/bf-image-viewer-ref.md +55 -0
  62. package/ai/reference/bf-image-viewer-service.md +32 -0
  63. package/ai/reference/bf-labels.md +105 -74
  64. package/ai/reference/bf-media-card-aspect.md +28 -0
  65. package/ai/reference/bf-media-card-harness.md +66 -0
  66. package/ai/reference/bf-motion-list-directive.md +22 -0
  67. package/ai/reference/bf-prose-directive.md +16 -0
  68. package/ai/reference/bf-rejected-file-reason.md +28 -0
  69. package/ai/reference/bf-rejected-file.md +28 -0
  70. package/ai/reference/bf-select-harness.md +14 -5
  71. package/ai/reference/bf-select-option.md +2 -0
  72. package/ai/reference/bf-size.md +3 -0
  73. package/ai/reference/bf-step-heading-level.md +28 -0
  74. package/ai/reference/bf-table-align.md +1 -1
  75. package/ai/reference/bf-table-column-align.md +33 -0
  76. package/ai/reference/bf-table-column.md +7 -7
  77. package/ai/reference/bf-table-harness.md +12 -0
  78. package/ai/reference/bf-timeline-tone.md +31 -0
  79. package/ai/reference/bf-toggle-harness.md +55 -0
  80. package/ai/reference/bf_table_sort_select.md +23 -0
  81. package/ai/reference/provide-bf-labels.md +10 -3
  82. package/ai/reference/provide-bf-select.md +20 -0
  83. package/bin/bf-ui.js +1 -0
  84. package/dark-ink.css +124 -0
  85. package/fesm2022/bitforgehq-ui-mobile.mjs +2 -1
  86. package/fesm2022/bitforgehq-ui-mobile.mjs.map +1 -1
  87. package/fesm2022/bitforgehq-ui-overlay.mjs +2649 -606
  88. package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -1
  89. package/fesm2022/bitforgehq-ui-testing.mjs +406 -11
  90. package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
  91. package/fesm2022/bitforgehq-ui.mjs +11149 -6957
  92. package/fesm2022/bitforgehq-ui.mjs.map +1 -1
  93. package/llms-full.txt +5219 -141
  94. package/llms.txt +40 -1
  95. package/package.json +2 -1
  96. package/theme.css +84 -0
  97. package/types/bitforgehq-ui-overlay.d.ts +684 -7
  98. package/types/bitforgehq-ui-testing.d.ts +510 -7
  99. package/types/bitforgehq-ui.d.ts +1757 -186
@@ -0,0 +1,66 @@
1
+ # BfMediaCardHarness
2
+
3
+ Test harness for a media card: its image state, its messages and its selection
4
+
5
+ Class from `@bitforgehq/ui/testing` · since 0.5.0
6
+
7
+ Harness for `bf-media-card`. jsdom never loads images, so `loadImage()` and `failImage()` fire
8
+ the image's `load` and `error` events the way a browser would; `getState()` then tells what the
9
+ image area shows.
10
+
11
+ ```ts
12
+ import { BfMediaCardHarness } from '@bitforgehq/ui/testing';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ class BfMediaCardHarness extends ComponentHarness
19
+ ```
20
+
21
+ ## Methods
22
+
23
+ ### `getTitle(): Promise<string>`
24
+
25
+ The card's title: the text of the first heading in its body.
26
+
27
+ ### `getState(): Promise<'empty' | 'loading' | 'loaded' | 'failed'>`
28
+
29
+ What the image area shows: `empty` (no `src`, not loading), `loading` (the skeleton),
30
+ `loaded` (the image) or `failed` (the failure message).
31
+
32
+ ### `getSrc(): Promise<string>`
33
+
34
+ The URL of the image.
35
+
36
+ ### `getAlt(): Promise<string>`
37
+
38
+ The alternative text of the image.
39
+
40
+ ### `getLoadingLabel(): Promise<string>`
41
+
42
+ The caption over the skeleton while loading (the `loading` label when none is set).
43
+
44
+ ### `getFailedMessage(): Promise<string>`
45
+
46
+ The failure message.
47
+
48
+ ### `loadImage(): Promise<void>`
49
+
50
+ Fires the image's `load` event, as a browser does when it arrives. Throws without one.
51
+
52
+ ### `failImage(): Promise<void>`
53
+
54
+ Fires the image's `error` event, as a browser does when it fails. Throws without one.
55
+
56
+ ### `isSelectable(): Promise<boolean>`
57
+
58
+ Whether the card has a select button (`selectable`).
59
+
60
+ ### `isSelected(): Promise<boolean>`
61
+
62
+ Whether the card is selected (its select button is pressed).
63
+
64
+ ### `toggleSelected(): Promise<void>`
65
+
66
+ Clicks the select button, toggling the selection. Throws for a card that is not selectable.
@@ -0,0 +1,22 @@
1
+ # BfMotionListDirective
2
+
3
+ Glides the items of a list or grid to their new place when it changes
4
+
5
+ Directive from `@bitforgehq/ui` · since 0.5.0
6
+
7
+ Glides the items of an app's list or grid to their new place when items are added, removed or
8
+ reordered, instead of letting them jump (the FLIP technique). Put `bfMotionList` on the element
9
+ whose direct children are the items, usually the one around an `@for`. Each item remembers
10
+ where it was; after the DOM changes, every item that moved slides from its old place to its new
11
+ one over 200 ms (`--bf-duration-layout`, on the settle curve). Pair it with Angular's
12
+ `animate.enter="motion-safe:animate-item-enter"` and
13
+ `animate.leave="motion-safe:animate-item-leave"` on the items, so new items fade and rise in and
14
+ removed ones fade out before the rest close the gap. Nothing moves under
15
+ `prefers-reduced-motion: reduce`, and nothing glides when the container is resized. It moves
16
+ items within one container: an item moved to another list leaves one and enters the other.
17
+
18
+ ```ts
19
+ import { BfMotionListDirective } from '@bitforgehq/ui';
20
+ ```
21
+
22
+ Selector: `[bfMotionList]`
@@ -0,0 +1,16 @@
1
+ # BfProseDirective
2
+
3
+ Styles rendered markdown with the library tokens: headings, lists, code and quotes
4
+
5
+ Directive from `@bitforgehq/ui` · since 0.5.0
6
+
7
+ Styles rendered markdown inside its element: headings, paragraphs, lists, links, inline code,
8
+ code blocks, quotes and rules, through the semantic tokens only (so a theme override restyles
9
+ it). The app renders the markdown to HTML itself (and sanitises it); `bfProse` only styles it.
10
+ A `bf-chat-message` body is a `bfProse` element already.
11
+
12
+ ```ts
13
+ import { BfProseDirective } from '@bitforgehq/ui';
14
+ ```
15
+
16
+ Selector: `[bfProse]`
@@ -0,0 +1,28 @@
1
+ # BfRejectedFileReason
2
+
3
+ The rule a refused file broke, its type, its size or the file count
4
+
5
+ Type from `@bitforgehq/ui` · since 0.5.0
6
+
7
+ The rule a refused file broke: `type` (not accepted), `size` (over `maxSize`) or `count` (over
8
+ the limit).
9
+
10
+ ```ts
11
+ import { type BfRejectedFileReason } from '@bitforgehq/ui';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ type BfRejectedFileReason = 'type' | 'size' | 'count'
18
+ ```
19
+
20
+ ## Values
21
+
22
+ - `type`
23
+ - `size`
24
+ - `count`
25
+
26
+ ## Used by
27
+
28
+ - [BfRejectedFile](bf-rejected-file.md)
@@ -0,0 +1,28 @@
1
+ # BfRejectedFile
2
+
3
+ A picked or dropped file that broke a rule, with the rule and its message
4
+
5
+ Interface from `@bitforgehq/ui` · since 0.5.0
6
+
7
+ A picked or dropped file that broke a rule, with the rule and its message.
8
+
9
+ ```ts
10
+ import { type BfRejectedFile } from '@bitforgehq/ui';
11
+ ```
12
+
13
+ ## Properties
14
+
15
+ | Name | Type | Default | Description |
16
+ | --------- | ------------------------------------------------------ | -------- | ---------------------------------------------------------------------------------------------- |
17
+ | `file` | `File` | required | The file that was not added. |
18
+ | `reason` | `BfRejectedFileReason` (`'type' \| 'size' \| 'count'`) | required | The rule it broke: `type` (not accepted), `size` (over `maxSize`) or `count` (over the limit). |
19
+ | `message` | `string` | required | The user-facing text for the rule, from the labels. |
20
+
21
+ ## Uses
22
+
23
+ - [BfRejectedFileReason](bf-rejected-file-reason.md)
24
+
25
+ ## Used by
26
+
27
+ - [bf-file-input](../components/file-input.md)
28
+ - [bf-image-input](../components/image-input.md)
@@ -4,8 +4,11 @@ Test harness for the select: reads its label and options and picks one
4
4
 
5
5
  Class from `@bitforgehq/ui/testing` · since 0.3.0
6
6
 
7
- Harness for `bf-select`. It works by option label, so a test never needs the native option
8
- values (an object option's native value is its index).
7
+ Harness for `bf-select`, in both modes: the styled list under a mouse (its options render in the
8
+ CDK overlay container while open, found through the field's `aria-controls`) and the native
9
+ `<select>` under a coarse pointer. It also drives the native select with `data-bf-select` that a
10
+ stacked `bf-table` renders as its Sort by select without `provideBfSelect()`. It works by option
11
+ label, so a test never needs the option values (an object option's native value is its index).
9
12
 
10
13
  ```ts
11
14
  import { BfSelectHarness } from '@bitforgehq/ui/testing';
@@ -23,6 +26,11 @@ class BfSelectHarness extends ComponentHarness
23
26
 
24
27
  The visible label without the required mark, else the `aria-label`.
25
28
 
29
+ ### `isOpen(): Promise<boolean>`
30
+
31
+ Whether the styled option list is open (`aria-expanded`). Always false for the native select,
32
+ whose list belongs to the platform.
33
+
26
34
  ### `getValueLabel(): Promise<string>`
27
35
 
28
36
  The selected option's label, `''` while nothing is selected.
@@ -35,7 +43,8 @@ The labels of the options, in order, without the placeholder.
35
43
 
36
44
  Chooses the option with this label, as a user would: the select's `value` becomes that
37
45
  option's value. Throws, leaving the value as it is, for an unknown or disabled option and
38
- while the select itself is disabled.
46
+ while the select itself is disabled. On a read-only select it changes nothing, in both modes:
47
+ the styled list does not open, and the native select restores the shown option.
39
48
 
40
49
  | Parameter | Type | Description |
41
50
  | --------- | -------- | ------------------- |
@@ -63,11 +72,11 @@ The help text under the select; it is hidden while an error shows.
63
72
 
64
73
  ### `focus(): Promise<void>`
65
74
 
66
- Focuses the native select.
75
+ Focuses the field, or the native select.
67
76
 
68
77
  ### `blur(): Promise<void>`
69
78
 
70
- Blurs the native select, which marks a bound form field touched.
79
+ Blurs the field, or the native select, which marks a bound form field touched.
71
80
 
72
81
  ## Used by
73
82
 
@@ -4,6 +4,8 @@ One choice of a select with its value, its label and a disabled flag
4
4
 
5
5
  Interface from `@bitforgehq/ui` · since 0.1.0
6
6
 
7
+ Also exported from `@bitforgehq/ui/overlay`.
8
+
7
9
  One choice of `bf-select`; `value` is any type (a string by default).
8
10
 
9
11
  ```ts
@@ -27,6 +27,7 @@ type BfSize = 'sm' | 'md' | 'lg'
27
27
  - [bf-button](../components/button.md)
28
28
  - [BfButtonSize](bf-button-size.md)
29
29
  - [bf-calendar](../components/calendar.md)
30
+ - [bf-chat-composer](../components/chat-composer.md)
30
31
  - [bf-checkbox](../components/checkbox.md)
31
32
  - [bf-chip](../components/chip.md)
32
33
  - [bf-combobox](../components/combobox.md)
@@ -36,7 +37,9 @@ type BfSize = 'sm' | 'md' | 'lg'
36
37
  - [BfDefaultsOptions](bf-defaults-options.md)
37
38
  - [BfFieldControlState](bf-field-control-state.md)
38
39
  - [BfFieldSize](bf-field-size.md)
40
+ - [bf-file-input](../components/file-input.md)
39
41
  - [bf-icon-button](../components/icon-button.md)
42
+ - [bf-image-input](../components/image-input.md)
40
43
  - [bf-input](../components/input.md)
41
44
  - [bf-menu-button](../components/menu-button.md)
42
45
  - [bf-menu](../components/menu.md)
@@ -0,0 +1,28 @@
1
+ # BfStepHeadingLevel
2
+
3
+ The heading level a step title can take, two, three or four
4
+
5
+ Type from `@bitforgehq/ui` · since 0.4.0
6
+
7
+ The heading level of a `bf-step` title, for a guide whose steps hold enough content (screenshots,
8
+ code) that a screen-reader user moves between them by heading.
9
+
10
+ ```ts
11
+ import { type BfStepHeadingLevel } from '@bitforgehq/ui';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ type BfStepHeadingLevel = 2 | 3 | 4
18
+ ```
19
+
20
+ ## Values
21
+
22
+ - `2`
23
+ - `3`
24
+ - `4`
25
+
26
+ ## Used by
27
+
28
+ - [bf-step](../components/step.md)
@@ -23,4 +23,4 @@ type BfTableAlign = 'start' | 'end'
23
23
 
24
24
  ## Used by
25
25
 
26
- - [BfTableColumn](bf-table-column.md)
26
+ - [BfTableColumnAlign](bf-table-column-align.md)
@@ -0,0 +1,33 @@
1
+ # BfTableColumnAlign
2
+
3
+ The inline alignment of a table column: start, end, or centred for controls
4
+
5
+ Type from `@bitforgehq/ui` · since 0.4.0
6
+
7
+ Where a `bf-table` column lines up its header and cells: a `BfTableAlign`, or `center` for a
8
+ column of controls such as the toggles of a settings matrix. A new type, so `Record`s over the
9
+ released `BfTableAlign` keep compiling.
10
+
11
+ ```ts
12
+ import { type BfTableColumnAlign } from '@bitforgehq/ui';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ type BfTableColumnAlign = BfTableAlign | 'center'
19
+ ```
20
+
21
+ ## Values
22
+
23
+ - `start`
24
+ - `end`
25
+ - `center`
26
+
27
+ ## Uses
28
+
29
+ - [BfTableAlign](bf-table-align.md)
30
+
31
+ ## Used by
32
+
33
+ - [BfTableColumn](bf-table-column.md)
@@ -12,16 +12,16 @@ import { type BfTableColumn } from '@bitforgehq/ui';
12
12
 
13
13
  ## Properties
14
14
 
15
- | Name | Type | Default | Description |
16
- | ---------- | ----------------------------------- | --------- | ------------------------------------------------------------------------------------- |
17
- | `key` | `string` | required | The row property the default cell shows; also the key a `bfTableCell` template names. |
18
- | `label` | `string` | required | The header text. |
19
- | `sortable` | `boolean` | `false` | Whether the header is a button that sets the table's `sort`. |
20
- | `align` | `BfTableAlign` (`'start' \| 'end'`) | `'start'` | The inline alignment of the header and cells; `end` also sets tabular figures. |
15
+ | Name | Type | Default | Description |
16
+ | ---------- | ----------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
17
+ | `key` | `string` | required | The row property the default cell shows; also the key a `bfTableCell` template names. |
18
+ | `label` | `string` | required | The header text. |
19
+ | `sortable` | `boolean` | `false` | Whether the header is a button that sets the table's `sort`. |
20
+ | `align` | `BfTableColumnAlign` (`'start' \| 'end' \| 'center'`) | `'start'` | The inline alignment of the header and cells; `end` also sets tabular figures, `center` centres a cell's control (a toggle, a checkbox) in the column. |
21
21
 
22
22
  ## Uses
23
23
 
24
- - [BfTableAlign](bf-table-align.md)
24
+ - [BfTableColumnAlign](bf-table-column-align.md)
25
25
 
26
26
  ## Used by
27
27
 
@@ -41,6 +41,18 @@ The text of one cell.
41
41
  | `row` | `number` | The row's position, from 0. |
42
42
  | `column` | `string` | The column's header text. |
43
43
 
44
+ ### `getCellHarness<T extends ComponentHarness>(row: number, column: string, query: HarnessQuery<T>): Promise<T>`
45
+
46
+ A harness for a control in one cell, such as a `bf-toggle` of a settings matrix or a
47
+ `bf-select` in a custom cell. Throws for an unknown row or column, or when the cell holds no
48
+ matching control.
49
+
50
+ | Parameter | Type | Description |
51
+ | --------- | ----------------- | --------------------------------------------------- |
52
+ | `row` | `number` | The row's position, from 0. |
53
+ | `column` | `string` | The column's header text. |
54
+ | `query` | `HarnessQuery<T>` | The harness type, or a predicate from its `with()`. |
55
+
44
56
  ### `sortBy(column: string): Promise<void>`
45
57
 
46
58
  Clicks a sortable column's header, as a user would: ascending first, then descending.
@@ -0,0 +1,31 @@
1
+ # BfTimelineTone
2
+
3
+ The marker colour of a timeline event, neutral, primary or a status
4
+
5
+ Type from `@bitforgehq/ui` · since 0.4.0
6
+
7
+ The colour of a `bf-timeline-event`'s marker: `neutral` (the default), `primary`, or a status
8
+ (`success`, `warning`, `danger`, `info`), such as danger for a failed CI run.
9
+
10
+ ```ts
11
+ import { type BfTimelineTone } from '@bitforgehq/ui';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ type BfTimelineTone = 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info'
18
+ ```
19
+
20
+ ## Values
21
+
22
+ - `neutral`
23
+ - `primary`
24
+ - `success`
25
+ - `warning`
26
+ - `danger`
27
+ - `info`
28
+
29
+ ## Used by
30
+
31
+ - [bf-timeline-event](../components/timeline-event.md)
@@ -0,0 +1,55 @@
1
+ # BfToggleHarness
2
+
3
+ Test harness for the toggle: reads its name and state and switches it
4
+
5
+ Class from `@bitforgehq/ui/testing` · since 0.4.0
6
+
7
+ Harness for `bf-toggle`. Its `label` filter matches the switch's name: the text of the elements
8
+ `ariaLabelledby` names, else `ariaLabel`, else the visible label, so a label-less switch in a
9
+ table cell or a list row is found the same way.
10
+
11
+ ```ts
12
+ import { BfToggleHarness } from '@bitforgehq/ui/testing';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ class BfToggleHarness extends ComponentHarness
19
+ ```
20
+
21
+ ## Methods
22
+
23
+ ### `getLabel(): Promise<string>`
24
+
25
+ The switch's name, as the browser computes it: the text of the elements `ariaLabelledby`
26
+ names, else `ariaLabel`, else the visible label (the `label` text and the default slot).
27
+
28
+ ### `isChecked(): Promise<boolean>`
29
+
30
+ Whether the switch is on.
31
+
32
+ ### `isDisabled(): Promise<boolean>`
33
+
34
+ Whether the switch is disabled.
35
+
36
+ ### `isReadonly(): Promise<boolean>`
37
+
38
+ Whether the switch is read-only (`aria-readonly`): it shows its state but a click does nothing.
39
+
40
+ ### `toggle(): Promise<void>`
41
+
42
+ Clicks the switch, as a user would, so it turns on or off. Throws while it is disabled (a
43
+ user's click would do nothing); a read-only switch takes the click and stays as it is.
44
+
45
+ ### `check(): Promise<void>`
46
+
47
+ Turns the switch on with a click; an on switch stays on. Throws while it is disabled.
48
+
49
+ ### `uncheck(): Promise<void>`
50
+
51
+ Turns the switch off with a click; an off switch stays off. Throws while it is disabled.
52
+
53
+ ### `getErrorText(): Promise<string>`
54
+
55
+ The error text under the switch.
@@ -0,0 +1,23 @@
1
+ # BF_TABLE_SORT_SELECT
2
+
3
+ The component a stacked table renders as its Sort by select
4
+
5
+ Injection token from `@bitforgehq/ui` · since 0.5.0
6
+
7
+ The component a stacked `bf-table` renders as its Sort by select; `null` (the default) keeps the
8
+ built-in native `<select>`. `provideBfSelect()` from `@bitforgehq/ui/overlay` sets it to the
9
+ styled `bf-select`, so the core entry never imports the overlay entry. A component given here
10
+ must take the inputs `label` (string), `options` (`BfSelectOption<string>[]`) and `value`
11
+ (string) and emit the picked value from the output `changed`. The table adds its layout classes
12
+ to the component's host with `classList`, so the component must not overwrite its host
13
+ `className` or `class` attribute directly.
14
+
15
+ ```ts
16
+ import { BF_TABLE_SORT_SELECT } from '@bitforgehq/ui';
17
+ ```
18
+
19
+ ## Signature
20
+
21
+ ```ts
22
+ const BF_TABLE_SORT_SELECT: InjectionToken<Type<unknown> | null>
23
+ ```
@@ -17,9 +17,16 @@ every string. In a component's `providers` it covers that sub-tree's widgets and
17
17
  `dateInputUnavailable`, `timeInputHour`, `timeInputMinute`, `timeInputSecond`,
18
18
  `timeInputDayPeriod`, `timeInputOpenList`, `timeInputInvalid`, `timeInputMin`, `timeInputMax`,
19
19
  `chart`, `chartLegend`, `chartValues`, `chartShowData`, `chartHideData`, `chartCategory`,
20
- `chartValue`, `chartEmpty`, `chartError`, `validation`); the overlay services (`ok`, `cancel`,
21
- `actions`, `sheet`, `modal`, `close`, `expand`, `collapse`, `sheetPosition`, `dialog`,
22
- `notifications`) are root singletons and pick it up only when the caller passes its injector:
20
+ `chartValue`, `chartEmpty`, `chartError`, `listItemUnread`,
21
+ `fileInputChoose`, `fileInputDropHint`, `fileInputDropzone`, `fileInputTapToChoose`, `fileInputRemove`,
22
+ `fileInputDismiss`, `fileInputAdded`, `fileInputNotAdded`, `fileInputRemoved`, `fileInputCount`,
23
+ `fileRejectedType`, `fileRejectedSize`, `fileRejectedCount`,
24
+ `imageInputChoose`, `imageInputUpload`, `imageInputReplace`, `imageInputRemove`,
25
+ `chatThread`, `chatJumpToLatest`, `chatMessageStopped`, `chatMessageFailed`, `chatComposer`,
26
+ `chatSend`, `chatStop`, `mediaCardSelect`, `imageLoadFailed`, `validation`); the overlay
27
+ services (`ok`, `cancel`, `actions`, `sheet`, `modal`, `close`, `expand`, `collapse`,
28
+ `sheetPosition`, `dialog`, `notifications`, `imageViewer`, `imageViewerPrevious`,
29
+ `imageViewerNext`, `imageViewerPosition`) are root singletons and pick it up only when the caller passes its injector:
23
30
  `open(…, { injector: inject(Injector) })`.
24
31
 
25
32
  ```ts
@@ -0,0 +1,20 @@
1
+ # provideBfSelect
2
+
3
+ Makes a stacked table's Sort by select the styled bf-select, app-wide
4
+
5
+ Function from `@bitforgehq/ui/overlay` · since 0.5.0
6
+
7
+ Makes the library's built-in selects use the styled `bf-select`: a stacked `bf-table` then
8
+ renders its Sort by select as a `bf-select` (the native `<select>` under a coarse pointer, as
9
+ `bf-select` itself does) instead of the plain native one. Add it to
10
+ `ApplicationConfig.providers`.
11
+
12
+ ```ts
13
+ import { provideBfSelect } from '@bitforgehq/ui/overlay';
14
+ ```
15
+
16
+ ## Signature
17
+
18
+ ```ts
19
+ function provideBfSelect(): EnvironmentProviders
20
+ ```
package/bin/bf-ui.js CHANGED
@@ -120,6 +120,7 @@ const PAIRS = [
120
120
  { fg: 'primary-strong', bg: 'surface', min: TEXT, use: 'text button hover, radio dot' },
121
121
  { fg: 'primary-strong', bg: 'surface-sunken', min: NON_TEXT, use: 'segment cue, progress' },
122
122
  { fg: 'primary-strong', bg: 'surface-muted', min: NON_TEXT, use: 'read-only toggle and radio' },
123
+ { fg: 'text', bg: 'primary-soft', min: TEXT, use: 'chat user message bubble' },
123
124
  { fg: 'text', bg: 'primary-soft-pressed', min: TEXT, use: 'outline button pressed' },
124
125
  { fg: 'ring', bg: 'bg', min: NON_TEXT, use: 'focus ring' },
125
126
  { fg: 'ring', bg: 'surface', min: NON_TEXT, use: 'focus ring on a card' },
package/dark-ink.css ADDED
@@ -0,0 +1,124 @@
1
+ /*
2
+ * @bitforgehq/ui — Ink, an opt-in dark preset: near-black surfaces one small step apart,
3
+ * see-through status tints, 1 px edges instead of heavy shadows, off-white text.
4
+ *
5
+ * Usage: import it AFTER theme.css. It redefines tokens under .dark only, so light mode is
6
+ * untouched, and it wins over theme.css's own .dark block by order:
7
+ * @import 'tailwindcss';
8
+ * @import '@bitforgehq/ui/theme.css';
9
+ * @import '@bitforgehq/ui/dark-ink.css';
10
+ *
11
+ * It sets every colour and shadow token theme.css's .dark block sets except the brand set (the
12
+ * primary family below), so the app's brand primary stays: the default dark indigo, or the
13
+ * app's own .dark brand override placed after this import. For the monochrome look of the
14
+ * mockups, paste this optional block after the import as well:
15
+ *
16
+ * .dark {
17
+ * --color-primary: #ececee;
18
+ * --color-primary-hover: #dcdce0;
19
+ * --color-primary-pressed: #cdcdd2;
20
+ * --color-primary-soft: rgb(255 255 255 / 0.08);
21
+ * --color-primary-soft-hover: rgb(255 255 255 / 0.11);
22
+ * --color-primary-soft-pressed: rgb(255 255 255 / 0.14);
23
+ * --color-primary-strong: #ffffff;
24
+ * --color-on-primary: #0b0c0e;
25
+ * --color-primary-text: #e8e9ec;
26
+ * }
27
+ *
28
+ * Every pair is contrast-checked in theme.spec.ts, alpha tints composited over the surface they
29
+ * sit on (bg, surface, surface-muted and surface-sunken), with the default dark brand and with
30
+ * the monochrome block.
31
+ */
32
+
33
+ /* Tailwind inlines a shadow token's value into the shadow-* utilities when it compiles them, so
34
+ redefining --shadow-* under .dark alone changes nothing that the utilities draw. These read
35
+ the dark value through --bf-shadow-*, which only .dark below sets; in light mode the fallback
36
+ is theme.css's own light value, so light mode compiles to the same shadows. */
37
+ @theme {
38
+ --shadow-raised: var(
39
+ --bf-shadow-raised,
40
+ 0 1px 2px rgb(31 42 34 / 0.06),
41
+ 0 8px 24px rgb(31 42 34 / 0.08)
42
+ );
43
+ --shadow-floating: var(--bf-shadow-floating, 0 10px 30px rgb(31 42 34 / 0.18));
44
+ --shadow-segment: var(--bf-shadow-segment, 0 1px 3px rgb(31 42 34 / 0.14));
45
+ }
46
+
47
+ .dark {
48
+ /* Surfaces: the page and cards near black, one step apart. */
49
+ --color-bg: #0b0c0e;
50
+ --color-surface: #121316;
51
+ --color-surface-muted: #191a1e; /* hover */
52
+ --color-surface-sunken: #0e0f11;
53
+ --color-surface-pressed: #202126;
54
+ --color-selected: rgb(255 255 255 / 0.06);
55
+
56
+ /* Status: the colour as text, its soft tint the same colour at 12 % (a see-through tint that
57
+ sits on any surface, >= 5:1 under its text on bg, surface, surface-muted and surface-sunken). */
58
+ --color-success: #4cc38a;
59
+ --color-success-soft: rgb(76 195 138 / 0.12);
60
+ --color-warning: #e5b454;
61
+ --color-warning-soft: rgb(229 180 84 / 0.12);
62
+ --color-danger: #f2706a;
63
+ /* Opaque (the danger colour at 13 % over surface), not see-through: the danger button's hover
64
+ and pressed states write danger-soft as text on the danger fill, where a tint would vanish. */
65
+ --color-danger-soft: #2f1f21;
66
+ --color-danger-pressed: #f59994;
67
+ --color-danger-border: #c9372c;
68
+ --color-info: #5eb1ef;
69
+ --color-info-soft: rgb(94 177 239 / 0.12);
70
+ /* Strong fills (>= 3:1 on bg, surface and surface-sunken), text on them >= 4.5:1. */
71
+ --color-neutral-strong: #9a9da5;
72
+ --color-on-neutral-strong: #0b0c0e; /* 7.2:1 */
73
+ --color-success-strong: #26804f;
74
+ --color-on-success-strong: #ffffff; /* 4.9:1 */
75
+ --color-warning-strong: #d99a3c;
76
+ --color-on-warning-strong: #1a1206; /* 7.6:1 */
77
+ --color-danger-strong: #c9372c;
78
+ --color-on-danger-strong: #ffffff; /* 5.2:1 */
79
+ --color-info-strong: #2a7aa8;
80
+ --color-on-info-strong: #ffffff; /* 4.7:1 */
81
+ --color-tooltip: #e8e9ec;
82
+ --color-on-tooltip: #121316; /* 15.3:1 on tooltip */
83
+
84
+ /* Charts: the default dark series (each >= 5:1 on bg and surface here, adjacent pairs distinct
85
+ under colour vision deficiency); grid lines as faint as the border, the axis >= 3:1. */
86
+ --color-chart-1: #3e9e66;
87
+ --color-chart-2: #7479ee;
88
+ --color-chart-3: #d8692f;
89
+ --color-chart-4: #1f9cb8;
90
+ --color-chart-5: #b08a1c;
91
+ --color-chart-6: #dc5893;
92
+ --color-chart-7: #a072e6;
93
+ --color-chart-8: #7f9c2c;
94
+ --color-chart-grid: #1f2024;
95
+ --color-chart-axis: #64676e;
96
+ --color-neutral: #a9adb5;
97
+ --color-neutral-soft: rgb(255 255 255 / 0.06);
98
+
99
+ /* Lines: border-strong and control-off >= 3:1 on bg, surface, surface-muted, surface-sunken. */
100
+ --color-border: #1f2024;
101
+ --color-border-strong: #64676e;
102
+ --color-divider: #18191c;
103
+ --color-control-off: #64676e;
104
+ --color-scrim: #000000;
105
+
106
+ /* Text: off-white, never pure white; muted >= 4.5:1 on every surface and on primary-soft. */
107
+ --color-text: #e8e9ec;
108
+ --color-text-secondary: #b4b7bd;
109
+ --color-text-muted: #90949b;
110
+ --color-text-subtle: #63676f; /* icons and chevrons only (>= 3:1), never text */
111
+ --color-text-disabled: #4a4d53;
112
+ --color-text-done: #6e727a;
113
+
114
+ /* A neutral focus ring (>= 5:1 on bg and surface), so it fits any brand. */
115
+ --color-ring: #8b8f97;
116
+
117
+ /* Edges instead of shadows: a 1 px white ring inside the raised and floating shadows. */
118
+ --shadow-raised: 0 0 0 1px rgb(255 255 255 / 0.06), 0 1px 2px rgb(0 0 0 / 0.6);
119
+ --shadow-floating: 0 0 0 1px rgb(255 255 255 / 0.08), 0 16px 48px rgb(0 0 0 / 0.7);
120
+ --shadow-segment: 0 1px 3px rgb(0 0 0 / 0.5);
121
+ --bf-shadow-raised: var(--shadow-raised);
122
+ --bf-shadow-floating: var(--shadow-floating);
123
+ --bf-shadow-segment: var(--shadow-segment);
124
+ }
@@ -5166,7 +5166,8 @@ var BfActionSheetComponent = class BfActionSheetComponent {
5166
5166
  "interactive",
5167
5167
  "chevron",
5168
5168
  "disabled",
5169
- "truncate"
5169
+ "truncate",
5170
+ "unread"
5170
5171
  ],
5171
5172
  outputs: ["clicked"]
5172
5173
  },