@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
package/ai/REFERENCE.json CHANGED
@@ -145,6 +145,22 @@
145
145
  "since": "0.3.0",
146
146
  "signature": "const BF_TAB_LINKS: InjectionToken<BfTabLinks>"
147
147
  },
148
+ {
149
+ "name": "BF_TABLE_SORT_SELECT",
150
+ "slug": "bf_table_sort_select",
151
+ "kind": "token",
152
+ "entryPoint": "@bitforgehq/ui",
153
+ "file": "src/components/table/table-sort-select.token.ts",
154
+ "summary": "The component a stacked table renders as its Sort by select",
155
+ "description": "The component a stacked `bf-table` renders as its Sort by select; `null` (the default) keeps the\nbuilt-in native `<select>`. `provideBfSelect()` from `@bitforgehq/ui/overlay` sets it to the\nstyled `bf-select`, so the core entry never imports the overlay entry. A component given here\nmust take the inputs `label` (string), `options` (`BfSelectOption<string>[]`) and `value`\n(string) and emit the picked value from the output `changed`. The table adds its layout classes\nto the component's host with `classList`, so the component must not overwrite its host\n`className` or `class` attribute directly.",
156
+ "members": [],
157
+ "methods": [],
158
+ "slots": [],
159
+ "references": [],
160
+ "usedBy": [],
161
+ "since": "0.5.0",
162
+ "signature": "const BF_TABLE_SORT_SELECT: InjectionToken<Type<unknown> | null>"
163
+ },
148
164
  {
149
165
  "name": "BfActionDirective",
150
166
  "slug": "bf-action-directive",
@@ -152,7 +168,7 @@
152
168
  "entryPoint": "@bitforgehq/ui",
153
169
  "file": "src/components/action/action.directive.ts",
154
170
  "summary": "Makes one link or button the click target of a whole card or list row",
155
- "description": "The one interactive element of a `bf-card` or `bf-list-item` (the stretched-link pattern): put\nit on the `<a>` (navigation) or `<button>` (an action) that holds the card's heading text or the\nrow's title. Its `::after` stretches the hit area over the nearest positioned ancestor (the card\nbox, the row), so the whole surface is clickable while only the heading's link or button is\nexposed: the heading stays a heading and the accessible name is the title alone. It registers\nwith the nearest card or row, which then draws the pointer, the hover and, while the action has\nkeyboard focus, the focus ring; a card is never lit by the actions of rows nested in it. Give\nsecondary controls inside the surface `class=\"relative z-1\"` so they stay clickable above the\nstretched area.",
171
+ "description": "The one interactive element of a `bf-card` or `bf-list-item` (the stretched-link pattern): put\nit on the `<a>` (navigation) or `<button>` (an action) that holds the card's heading text or the\nrow's title. Its `::after` stretches the hit area over the nearest positioned ancestor (the card\nbox, the row), so the whole surface is clickable while only the heading's link or button is\nexposed: the heading stays a heading and the accessible name is the title alone. It registers\nwith the nearest card or row, which then draws the pointer, the hover and, while the action has\nkeyboard focus, the focus ring; a card is never lit by the actions of rows nested in it. Give\nsecondary controls inside the surface `class=\"relative z-1\"` so they stay clickable above the\nstretched area. When the surface marks a state that belongs in the name (an `unread` list\nrow), the directive names the element `aria-labelledby=\"<state id> <own id>\"`, so the link reads\n\"Unread, Account\", and restores the element's own `aria-labelledby` when the state goes.",
156
172
  "members": [],
157
173
  "methods": [],
158
174
  "slots": [],
@@ -280,6 +296,23 @@
280
296
  "signature": "type BfBadgeAppearance = BfBadgeVariant | 'info'",
281
297
  "values": ["neutral", "primary", "success", "warning", "danger", "info"]
282
298
  },
299
+ {
300
+ "name": "BfBadgeEmphasis",
301
+ "slug": "bf-badge-emphasis",
302
+ "kind": "type",
303
+ "entryPoint": "@bitforgehq/ui",
304
+ "file": "src/components/badge/badge.component.ts",
305
+ "summary": "The two badge emphases, the soft tint or the solid strong fill",
306
+ "description": "How loud a `bf-badge` is: `soft`, a pale tint with tinted text (the default), or `strong`, a\nsolid fill with contrasting text for the one state that must stand out, such as \"Critical\".",
307
+ "members": [],
308
+ "methods": [],
309
+ "slots": [],
310
+ "references": [],
311
+ "usedBy": ["bf-badge-component"],
312
+ "since": "0.4.0",
313
+ "signature": "type BfBadgeEmphasis = 'soft' | 'strong'",
314
+ "values": ["soft", "strong"]
315
+ },
283
316
  {
284
317
  "name": "BfBadgeVariant",
285
318
  "slug": "bf-badge-variant",
@@ -437,6 +470,40 @@
437
470
  "signature": "type BfCardVariant = 'raised' | 'tint' | 'ink' | 'flat'",
438
471
  "values": ["raised", "tint", "ink", "flat"]
439
472
  },
473
+ {
474
+ "name": "BfChatMessageRole",
475
+ "slug": "bf-chat-message-role",
476
+ "kind": "type",
477
+ "entryPoint": "@bitforgehq/ui",
478
+ "file": "src/components/chat-thread/chat-message.component.ts",
479
+ "summary": "Who wrote a chat message, the user or the assistant",
480
+ "description": "Who wrote a `bf-chat-message`: `user` (a tinted bubble at the inline end) or `assistant` (full\nwidth, no bubble).",
481
+ "members": [],
482
+ "methods": [],
483
+ "slots": [],
484
+ "references": [],
485
+ "usedBy": ["bf-chat-message-component"],
486
+ "since": "0.5.0",
487
+ "signature": "type BfChatMessageRole = 'user' | 'assistant'",
488
+ "values": ["user", "assistant"]
489
+ },
490
+ {
491
+ "name": "BfChatMessageStatus",
492
+ "slug": "bf-chat-message-status",
493
+ "kind": "type",
494
+ "entryPoint": "@bitforgehq/ui",
495
+ "file": "src/components/chat-thread/chat-message.component.ts",
496
+ "summary": "How a chat message ended: done, stopped by the user, or failed",
497
+ "description": "How a `bf-chat-message` ended: `done` (the default, no status line), `stopped` (the user\nstopped the reply) or `failed` (it did not arrive or was not sent).",
498
+ "members": [],
499
+ "methods": [],
500
+ "slots": [],
501
+ "references": [],
502
+ "usedBy": ["bf-chat-message-component"],
503
+ "since": "0.5.0",
504
+ "signature": "type BfChatMessageStatus = 'done' | 'stopped' | 'failed'",
505
+ "values": ["done", "stopped", "failed"]
506
+ },
440
507
  {
441
508
  "name": "BfChipGroupMode",
442
509
  "slug": "bf-chip-group-mode",
@@ -687,6 +754,22 @@
687
754
  "signature": "type BfEnterKeyHint = 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send'",
688
755
  "values": ["enter", "done", "go", "next", "previous", "search", "send"]
689
756
  },
757
+ {
758
+ "name": "BfFadeInDirective",
759
+ "slug": "bf-fade-in-directive",
760
+ "kind": "directive",
761
+ "entryPoint": "@bitforgehq/ui",
762
+ "file": "src/components/fade-in/fade-in.directive.ts",
763
+ "summary": "Fades an image in once it has loaded instead of popping in",
764
+ "description": "Fades an image in when it has loaded instead of letting it pop in line by line: put\n`bfFadeIn` on the `<img>`. The image stays transparent until its `load` (or `error`) event,\nthen fades in over 260 ms (`duration-slow`), at once under `prefers-reduced-motion: reduce`. An\nimage that is already loaded when it renders (from the cache) shows straight away. Reserve its\nspace (`width`/`height` attributes or an aspect ratio) so the layout does not move when it\narrives; for a placeholder while it loads, put a `bf-skeleton` behind it.",
765
+ "members": [],
766
+ "methods": [],
767
+ "slots": [],
768
+ "references": [],
769
+ "usedBy": [],
770
+ "since": "0.5.0",
771
+ "selector": "img[bfFadeIn]"
772
+ },
690
773
  {
691
774
  "name": "bfFieldControlClass",
692
775
  "slug": "bf-field-control-class",
@@ -781,6 +864,23 @@
781
864
  "signature": "type BfFieldSize = BfSize",
782
865
  "values": ["sm", "md", "lg"]
783
866
  },
867
+ {
868
+ "name": "BfFileInputVariant",
869
+ "slug": "bf-file-input-variant",
870
+ "kind": "type",
871
+ "entryPoint": "@bitforgehq/ui",
872
+ "file": "src/components/file-input/file-input.component.ts",
873
+ "summary": "The two looks of a file picker, a compact field or a drop zone",
874
+ "description": "The look of a `bf-file-input`: a compact field with a pick button (`field`), or a drop zone\n(`dropzone`). Both have the same API and behaviour.",
875
+ "members": [],
876
+ "methods": [],
877
+ "slots": [],
878
+ "references": [],
879
+ "usedBy": ["bf-file-input-component"],
880
+ "since": "0.5.0",
881
+ "signature": "type BfFileInputVariant = 'field' | 'dropzone'",
882
+ "values": ["field", "dropzone"]
883
+ },
784
884
  {
785
885
  "name": "BfIconButtonVariant",
786
886
  "slug": "bf-icon-button-variant",
@@ -798,6 +898,23 @@
798
898
  "signature": "type BfIconButtonVariant = 'tonal' | 'primary' | 'outline' | 'text'",
799
899
  "values": ["tonal", "primary", "outline", "text"]
800
900
  },
901
+ {
902
+ "name": "BfImageInputShape",
903
+ "slug": "bf-image-input-shape",
904
+ "kind": "type",
905
+ "entryPoint": "@bitforgehq/ui",
906
+ "file": "src/components/image-input/image-input.component.ts",
907
+ "summary": "The two tile shapes of an image picker, a circle or a rounded square",
908
+ "description": "The shape of a `bf-image-input` tile: a circle (`round`, for avatars) or a rounded square\n(`square`, for logos and covers).",
909
+ "members": [],
910
+ "methods": [],
911
+ "slots": [],
912
+ "references": [],
913
+ "usedBy": ["bf-image-input-component"],
914
+ "since": "0.5.0",
915
+ "signature": "type BfImageInputShape = 'round' | 'square'",
916
+ "values": ["round", "square"]
917
+ },
801
918
  {
802
919
  "name": "BfInputAutocapitalize",
803
920
  "slug": "bf-input-autocapitalize",
@@ -1543,6 +1660,285 @@
1543
1660
  "readonly": true,
1544
1661
  "default": "'The data could not be loaded'"
1545
1662
  },
1663
+ {
1664
+ "name": "listItemUnread",
1665
+ "kind": "property",
1666
+ "type": "string",
1667
+ "required": true,
1668
+ "doc": "bf-list-item's visually hidden state text before the title of an `unread` row.",
1669
+ "readonly": true,
1670
+ "default": "'Unread'"
1671
+ },
1672
+ {
1673
+ "name": "fileInputChoose",
1674
+ "kind": "property",
1675
+ "type": "(multiple: boolean) => string",
1676
+ "required": true,
1677
+ "doc": "bf-file-input's button text.",
1678
+ "readonly": true,
1679
+ "default": "(multiple) => (multiple ? 'Choose files' : 'Choose file')"
1680
+ },
1681
+ {
1682
+ "name": "fileInputDropHint",
1683
+ "kind": "property",
1684
+ "type": "(multiple: boolean) => string",
1685
+ "required": true,
1686
+ "doc": "bf-file-input's hint beside the button.",
1687
+ "readonly": true,
1688
+ "default": "(multiple) => (multiple ? 'or drop them here' : 'or drop it here')"
1689
+ },
1690
+ {
1691
+ "name": "fileInputDropzone",
1692
+ "kind": "property",
1693
+ "type": "(multiple: boolean) => string",
1694
+ "required": true,
1695
+ "doc": "bf-file-input's drop zone text.",
1696
+ "readonly": true,
1697
+ "default": "(multiple) => (multiple ? 'Drag files here or browse' : 'Drag a file here or browse')"
1698
+ },
1699
+ {
1700
+ "name": "fileInputTapToChoose",
1701
+ "kind": "property",
1702
+ "type": "(multiple: boolean) => string",
1703
+ "required": true,
1704
+ "doc": "bf-file-input's text under touch input.",
1705
+ "readonly": true,
1706
+ "default": "(multiple) => (multiple ? 'Tap to choose files' : 'Tap to choose a file')"
1707
+ },
1708
+ {
1709
+ "name": "fileInputRemove",
1710
+ "kind": "property",
1711
+ "type": "(name: string) => string",
1712
+ "required": true,
1713
+ "doc": "The accessible name of bf-file-input's remove button for a file.",
1714
+ "readonly": true,
1715
+ "default": "(name) => `Remove ${name}`"
1716
+ },
1717
+ {
1718
+ "name": "fileInputDismiss",
1719
+ "kind": "property",
1720
+ "type": "(name: string) => string",
1721
+ "required": true,
1722
+ "doc": "The accessible name of bf-file-input's button that dismisses a rejected file.",
1723
+ "readonly": true,
1724
+ "default": "(name) => `Dismiss ${name}`"
1725
+ },
1726
+ {
1727
+ "name": "fileInputAdded",
1728
+ "kind": "property",
1729
+ "type": "(count: number) => string",
1730
+ "required": true,
1731
+ "doc": "bf-file-input's live announcement after files are added.",
1732
+ "readonly": true,
1733
+ "default": "(count) => (count === 1 ? '1 file added' : `${count} files added`)"
1734
+ },
1735
+ {
1736
+ "name": "fileInputNotAdded",
1737
+ "kind": "property",
1738
+ "type": "(name: string, reason: string) => string",
1739
+ "required": true,
1740
+ "doc": "bf-file-input's live announcement for a rejected file.",
1741
+ "readonly": true,
1742
+ "default": "(name, reason) => `${name} was not added: ${reason}`"
1743
+ },
1744
+ {
1745
+ "name": "fileInputRemoved",
1746
+ "kind": "property",
1747
+ "type": "(name: string) => string",
1748
+ "required": true,
1749
+ "doc": "bf-file-input's live announcement after a file is removed.",
1750
+ "readonly": true,
1751
+ "default": "(name) => `${name} removed`"
1752
+ },
1753
+ {
1754
+ "name": "fileInputCount",
1755
+ "kind": "property",
1756
+ "type": "(count: number) => string",
1757
+ "required": true,
1758
+ "doc": "bf-file-input's read-only box text for the number of chosen files.",
1759
+ "readonly": true,
1760
+ "default": "(count) => (count === 1 ? '1 file' : `${count} files`)"
1761
+ },
1762
+ {
1763
+ "name": "fileRejectedType",
1764
+ "kind": "property",
1765
+ "type": "string",
1766
+ "required": true,
1767
+ "doc": "The message of a file rejected for its type.",
1768
+ "readonly": true,
1769
+ "default": "'Not an accepted type'"
1770
+ },
1771
+ {
1772
+ "name": "fileRejectedSize",
1773
+ "kind": "property",
1774
+ "type": "(max: string) => string",
1775
+ "required": true,
1776
+ "doc": "The message of a file rejected for its size; `max` is the formatted limit.",
1777
+ "readonly": true,
1778
+ "default": "(max) => `Too large, max ${max}`"
1779
+ },
1780
+ {
1781
+ "name": "fileRejectedCount",
1782
+ "kind": "property",
1783
+ "type": "(max: number) => string",
1784
+ "required": true,
1785
+ "doc": "The message of a file rejected because the file limit is reached.",
1786
+ "readonly": true,
1787
+ "default": "(max) => `Too many files, max ${max}`"
1788
+ },
1789
+ {
1790
+ "name": "imageInputChoose",
1791
+ "kind": "property",
1792
+ "type": "string",
1793
+ "required": true,
1794
+ "doc": "bf-image-input's accessible name for the empty drop target.",
1795
+ "readonly": true,
1796
+ "default": "'Choose image'"
1797
+ },
1798
+ {
1799
+ "name": "imageInputUpload",
1800
+ "kind": "property",
1801
+ "type": "string",
1802
+ "required": true,
1803
+ "doc": "bf-image-input's text for choosing the first image.",
1804
+ "readonly": true,
1805
+ "default": "'Upload'"
1806
+ },
1807
+ {
1808
+ "name": "imageInputReplace",
1809
+ "kind": "property",
1810
+ "type": "string",
1811
+ "required": true,
1812
+ "doc": "bf-image-input's text for replacing the image.",
1813
+ "readonly": true,
1814
+ "default": "'Replace'"
1815
+ },
1816
+ {
1817
+ "name": "imageInputRemove",
1818
+ "kind": "property",
1819
+ "type": "string",
1820
+ "required": true,
1821
+ "doc": "bf-image-input's text for removing the image.",
1822
+ "readonly": true,
1823
+ "default": "'Remove'"
1824
+ },
1825
+ {
1826
+ "name": "chatThread",
1827
+ "kind": "property",
1828
+ "type": "string",
1829
+ "required": true,
1830
+ "doc": "bf-chat-thread's accessible name (its `role=\"log\"`) when no `label` is set.",
1831
+ "readonly": true,
1832
+ "default": "'Conversation'"
1833
+ },
1834
+ {
1835
+ "name": "chatJumpToLatest",
1836
+ "kind": "property",
1837
+ "type": "string",
1838
+ "required": true,
1839
+ "doc": "bf-chat-thread's button that scrolls back to the newest message and follows it again.",
1840
+ "readonly": true,
1841
+ "default": "'Jump to latest'"
1842
+ },
1843
+ {
1844
+ "name": "chatMessageStopped",
1845
+ "kind": "property",
1846
+ "type": "string",
1847
+ "required": true,
1848
+ "doc": "bf-chat-message's status line for a reply the user stopped.",
1849
+ "readonly": true,
1850
+ "default": "'Stopped'"
1851
+ },
1852
+ {
1853
+ "name": "chatMessageFailed",
1854
+ "kind": "property",
1855
+ "type": "string",
1856
+ "required": true,
1857
+ "doc": "bf-chat-message's status line for a message that failed.",
1858
+ "readonly": true,
1859
+ "default": "'Something went wrong'"
1860
+ },
1861
+ {
1862
+ "name": "chatComposer",
1863
+ "kind": "property",
1864
+ "type": "string",
1865
+ "required": true,
1866
+ "doc": "bf-chat-composer's text field name when no `label` or `ariaLabel` is set.",
1867
+ "readonly": true,
1868
+ "default": "'Message'"
1869
+ },
1870
+ {
1871
+ "name": "chatSend",
1872
+ "kind": "property",
1873
+ "type": "string",
1874
+ "required": true,
1875
+ "doc": "bf-chat-composer's send button.",
1876
+ "readonly": true,
1877
+ "default": "'Send'"
1878
+ },
1879
+ {
1880
+ "name": "chatStop",
1881
+ "kind": "property",
1882
+ "type": "string",
1883
+ "required": true,
1884
+ "doc": "bf-chat-composer's stop button, shown in place of send while a reply runs.",
1885
+ "readonly": true,
1886
+ "default": "'Stop'"
1887
+ },
1888
+ {
1889
+ "name": "mediaCardSelect",
1890
+ "kind": "property",
1891
+ "type": "string",
1892
+ "required": true,
1893
+ "doc": "bf-media-card's select button, read before the card's name (\"Select Starfall\").",
1894
+ "readonly": true,
1895
+ "default": "'Select'"
1896
+ },
1897
+ {
1898
+ "name": "imageLoadFailed",
1899
+ "kind": "property",
1900
+ "type": "string",
1901
+ "required": true,
1902
+ "doc": "bf-media-card's and bf-image-viewer's message for an image that failed to load.",
1903
+ "readonly": true,
1904
+ "default": "'The image could not be loaded'"
1905
+ },
1906
+ {
1907
+ "name": "imageViewer",
1908
+ "kind": "property",
1909
+ "type": "string",
1910
+ "required": true,
1911
+ "doc": "bf-image-viewer's name.",
1912
+ "readonly": true,
1913
+ "default": "'Image viewer'"
1914
+ },
1915
+ {
1916
+ "name": "imageViewerPrevious",
1917
+ "kind": "property",
1918
+ "type": "string",
1919
+ "required": true,
1920
+ "doc": "bf-image-viewer's button that shows the previous image.",
1921
+ "readonly": true,
1922
+ "default": "'Previous image'"
1923
+ },
1924
+ {
1925
+ "name": "imageViewerNext",
1926
+ "kind": "property",
1927
+ "type": "string",
1928
+ "required": true,
1929
+ "doc": "bf-image-viewer's button that shows the next image.",
1930
+ "readonly": true,
1931
+ "default": "'Next image'"
1932
+ },
1933
+ {
1934
+ "name": "imageViewerPosition",
1935
+ "kind": "property",
1936
+ "type": "(position: number, count: number) => string",
1937
+ "required": true,
1938
+ "doc": "bf-image-viewer's counter: the shown image's position (1-based) among the images.",
1939
+ "readonly": true,
1940
+ "default": "(position, count) => `${position} of ${count}`"
1941
+ },
1546
1942
  {
1547
1943
  "name": "validation",
1548
1944
  "kind": "property",
@@ -1574,6 +1970,39 @@
1574
1970
  "since": "0.3.0",
1575
1971
  "signature": "type BfLabelsOverrides = Partial<Omit<BfLabels, 'validation'>> & { readonly validation?: Partial<BfValidationMessages>; }"
1576
1972
  },
1973
+ {
1974
+ "name": "BfMediaCardAspect",
1975
+ "slug": "bf-media-card-aspect",
1976
+ "kind": "type",
1977
+ "entryPoint": "@bitforgehq/ui",
1978
+ "file": "src/components/media-card/media-card.component.ts",
1979
+ "summary": "The four aspect ratios of a media card's image area, wide to portrait",
1980
+ "description": "The aspect ratio of a `bf-media-card`'s image area: 16:9 (default), 4:3, square or 3:4.",
1981
+ "members": [],
1982
+ "methods": [],
1983
+ "slots": [],
1984
+ "references": [],
1985
+ "usedBy": ["bf-media-card-component"],
1986
+ "since": "0.5.0",
1987
+ "signature": "type BfMediaCardAspect = '16/9' | '4/3' | '1/1' | '3/4'",
1988
+ "values": ["16/9", "4/3", "1/1", "3/4"]
1989
+ },
1990
+ {
1991
+ "name": "BfMotionListDirective",
1992
+ "slug": "bf-motion-list-directive",
1993
+ "kind": "directive",
1994
+ "entryPoint": "@bitforgehq/ui",
1995
+ "file": "src/components/motion-list/motion-list.directive.ts",
1996
+ "summary": "Glides the items of a list or grid to their new place when it changes",
1997
+ "description": "Glides the items of an app's list or grid to their new place when items are added, removed or\nreordered, instead of letting them jump (the FLIP technique). Put `bfMotionList` on the element\nwhose direct children are the items, usually the one around an `@for`. Each item remembers\nwhere it was; after the DOM changes, every item that moved slides from its old place to its new\none over 200 ms (`--bf-duration-layout`, on the settle curve). Pair it with Angular's\n`animate.enter=\"motion-safe:animate-item-enter\"` and\n`animate.leave=\"motion-safe:animate-item-leave\"` on the items, so new items fade and rise in and\nremoved ones fade out before the rest close the gap. Nothing moves under\n`prefers-reduced-motion: reduce`, and nothing glides when the container is resized. It moves\nitems within one container: an item moved to another list leaves one and enters the other.",
1998
+ "members": [],
1999
+ "methods": [],
2000
+ "slots": [],
2001
+ "references": [],
2002
+ "usedBy": [],
2003
+ "since": "0.5.0",
2004
+ "selector": "[bfMotionList]"
2005
+ },
1577
2006
  {
1578
2007
  "name": "BfPageHeaderHeadingLevel",
1579
2008
  "slug": "bf-page-header-heading-level",
@@ -1626,8 +2055,24 @@
1626
2055
  "values": ["primary", "success", "warning", "danger"]
1627
2056
  },
1628
2057
  {
1629
- "name": "BfRadioGroupOrientation",
1630
- "slug": "bf-radio-group-orientation",
2058
+ "name": "BfProseDirective",
2059
+ "slug": "bf-prose-directive",
2060
+ "kind": "directive",
2061
+ "entryPoint": "@bitforgehq/ui",
2062
+ "file": "src/components/chat-thread/prose.directive.ts",
2063
+ "summary": "Styles rendered markdown with the library tokens: headings, lists, code and quotes",
2064
+ "description": "Styles rendered markdown inside its element: headings, paragraphs, lists, links, inline code,\ncode blocks, quotes and rules, through the semantic tokens only (so a theme override restyles\nit). The app renders the markdown to HTML itself (and sanitises it); `bfProse` only styles it.\nA `bf-chat-message` body is a `bfProse` element already.",
2065
+ "members": [],
2066
+ "methods": [],
2067
+ "slots": [],
2068
+ "references": [],
2069
+ "usedBy": [],
2070
+ "since": "0.5.0",
2071
+ "selector": "[bfProse]"
2072
+ },
2073
+ {
2074
+ "name": "BfRadioGroupOrientation",
2075
+ "slug": "bf-radio-group-orientation",
1631
2076
  "kind": "type",
1632
2077
  "entryPoint": "@bitforgehq/ui",
1633
2078
  "file": "src/components/radio-group/radio-group.component.ts",
@@ -1689,6 +2134,64 @@
1689
2134
  "since": "0.1.0",
1690
2135
  "signature": "interface BfRadioOption<T = string>"
1691
2136
  },
2137
+ {
2138
+ "name": "BfRejectedFile",
2139
+ "slug": "bf-rejected-file",
2140
+ "kind": "interface",
2141
+ "entryPoint": "@bitforgehq/ui",
2142
+ "file": "src/components/_shared/file-rules.ts",
2143
+ "summary": "A picked or dropped file that broke a rule, with the rule and its message",
2144
+ "description": "A picked or dropped file that broke a rule, with the rule and its message.",
2145
+ "members": [
2146
+ {
2147
+ "name": "file",
2148
+ "kind": "property",
2149
+ "type": "File",
2150
+ "required": true,
2151
+ "doc": "The file that was not added.",
2152
+ "readonly": true
2153
+ },
2154
+ {
2155
+ "name": "reason",
2156
+ "kind": "property",
2157
+ "type": "BfRejectedFileReason",
2158
+ "required": true,
2159
+ "doc": "The rule it broke: `type` (not accepted), `size` (over `maxSize`) or `count` (over the limit).",
2160
+ "readonly": true,
2161
+ "expandedType": "'type' | 'size' | 'count'"
2162
+ },
2163
+ {
2164
+ "name": "message",
2165
+ "kind": "property",
2166
+ "type": "string",
2167
+ "required": true,
2168
+ "doc": "The user-facing text for the rule, from the labels.",
2169
+ "readonly": true
2170
+ }
2171
+ ],
2172
+ "methods": [],
2173
+ "slots": [],
2174
+ "references": ["bf-rejected-file-reason"],
2175
+ "usedBy": ["bf-file-input-component", "bf-image-input-component"],
2176
+ "since": "0.5.0"
2177
+ },
2178
+ {
2179
+ "name": "BfRejectedFileReason",
2180
+ "slug": "bf-rejected-file-reason",
2181
+ "kind": "type",
2182
+ "entryPoint": "@bitforgehq/ui",
2183
+ "file": "src/components/_shared/file-rules.ts",
2184
+ "summary": "The rule a refused file broke, its type, its size or the file count",
2185
+ "description": "The rule a refused file broke: `type` (not accepted), `size` (over `maxSize`) or `count` (over\nthe limit).",
2186
+ "members": [],
2187
+ "methods": [],
2188
+ "slots": [],
2189
+ "references": [],
2190
+ "usedBy": ["bf-rejected-file"],
2191
+ "since": "0.5.0",
2192
+ "signature": "type BfRejectedFileReason = 'type' | 'size' | 'count'",
2193
+ "values": ["type", "size", "count"]
2194
+ },
1692
2195
  {
1693
2196
  "name": "BfSegmentedSize",
1694
2197
  "slug": "bf-segmented-size",
@@ -1751,7 +2254,7 @@
1751
2254
  "slug": "bf-select-option",
1752
2255
  "kind": "interface",
1753
2256
  "entryPoint": "@bitforgehq/ui",
1754
- "file": "src/components/select/select.component.ts",
2257
+ "file": "src/components/_shared/select-option.ts",
1755
2258
  "summary": "One choice of a select with its value, its label and a disabled flag",
1756
2259
  "description": "One choice of `bf-select`; `value` is any type (a string by default).",
1757
2260
  "members": [
@@ -1783,7 +2286,12 @@
1783
2286
  "references": [],
1784
2287
  "usedBy": ["bf-select-component"],
1785
2288
  "since": "0.1.0",
1786
- "signature": "interface BfSelectOption<T = string>"
2289
+ "signature": "interface BfSelectOption<T = string>",
2290
+ "alsoExportedFrom": [
2291
+ {
2292
+ "entryPoint": "@bitforgehq/ui/overlay"
2293
+ }
2294
+ ]
1787
2295
  },
1788
2296
  {
1789
2297
  "name": "BfSidebarStateService",
@@ -1825,6 +2333,7 @@
1825
2333
  "bf-button-component",
1826
2334
  "bf-button-size",
1827
2335
  "bf-calendar-component",
2336
+ "bf-chat-composer-component",
1828
2337
  "bf-checkbox-component",
1829
2338
  "bf-chip-component",
1830
2339
  "bf-combobox-component",
@@ -1834,7 +2343,9 @@
1834
2343
  "bf-defaults-options",
1835
2344
  "bf-field-control-state",
1836
2345
  "bf-field-size",
2346
+ "bf-file-input-component",
1837
2347
  "bf-icon-button-component",
2348
+ "bf-image-input-component",
1838
2349
  "bf-input-component",
1839
2350
  "bf-menu-button-component",
1840
2351
  "bf-menu-component",
@@ -1961,6 +2472,23 @@
1961
2472
  "signature": "type BfStatVariant = 'plain' | 'card'",
1962
2473
  "values": ["plain", "card"]
1963
2474
  },
2475
+ {
2476
+ "name": "BfStepHeadingLevel",
2477
+ "slug": "bf-step-heading-level",
2478
+ "kind": "type",
2479
+ "entryPoint": "@bitforgehq/ui",
2480
+ "file": "src/components/steps/step.component.ts",
2481
+ "summary": "The heading level a step title can take, two, three or four",
2482
+ "description": "The heading level of a `bf-step` title, for a guide whose steps hold enough content (screenshots,\ncode) that a screen-reader user moves between them by heading.",
2483
+ "members": [],
2484
+ "methods": [],
2485
+ "slots": [],
2486
+ "references": [],
2487
+ "usedBy": ["bf-step-component"],
2488
+ "since": "0.4.0",
2489
+ "signature": "type BfStepHeadingLevel = 2 | 3 | 4",
2490
+ "values": ["2", "3", "4"]
2491
+ },
1964
2492
  {
1965
2493
  "name": "BfTabBarController",
1966
2494
  "slug": "bf-tab-bar-controller",
@@ -2135,7 +2663,7 @@
2135
2663
  "methods": [],
2136
2664
  "slots": [],
2137
2665
  "references": [],
2138
- "usedBy": ["bf-table-column"],
2666
+ "usedBy": ["bf-table-column-align"],
2139
2667
  "since": "0.3.1",
2140
2668
  "signature": "type BfTableAlign = 'start' | 'end'",
2141
2669
  "values": ["start", "end"]
@@ -2238,20 +2766,37 @@
2238
2766
  {
2239
2767
  "name": "align",
2240
2768
  "kind": "property",
2241
- "type": "BfTableAlign",
2769
+ "type": "BfTableColumnAlign",
2242
2770
  "required": false,
2243
- "doc": "The inline alignment of the header and cells; `end` also sets tabular figures.",
2771
+ "doc": "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.",
2244
2772
  "optional": true,
2245
2773
  "default": "'start'",
2246
- "expandedType": "'start' | 'end'"
2774
+ "expandedType": "'start' | 'end' | 'center'"
2247
2775
  }
2248
2776
  ],
2249
2777
  "methods": [],
2250
2778
  "slots": [],
2251
- "references": ["bf-table-align"],
2779
+ "references": ["bf-table-column-align"],
2252
2780
  "usedBy": ["bf-table-component"],
2253
2781
  "since": "0.3.1"
2254
2782
  },
2783
+ {
2784
+ "name": "BfTableColumnAlign",
2785
+ "slug": "bf-table-column-align",
2786
+ "kind": "type",
2787
+ "entryPoint": "@bitforgehq/ui",
2788
+ "file": "src/components/table/table.component.ts",
2789
+ "summary": "The inline alignment of a table column: start, end, or centred for controls",
2790
+ "description": "Where a `bf-table` column lines up its header and cells: a `BfTableAlign`, or `center` for a\ncolumn of controls such as the toggles of a settings matrix. A new type, so `Record`s over the\nreleased `BfTableAlign` keep compiling.",
2791
+ "members": [],
2792
+ "methods": [],
2793
+ "slots": [],
2794
+ "references": ["bf-table-align"],
2795
+ "usedBy": ["bf-table-column"],
2796
+ "since": "0.4.0",
2797
+ "signature": "type BfTableColumnAlign = BfTableAlign | 'center'",
2798
+ "values": ["start", "end", "center"]
2799
+ },
2255
2800
  {
2256
2801
  "name": "BfTableRowKey",
2257
2802
  "slug": "bf-table-row-key",
@@ -2377,6 +2922,23 @@
2377
2922
  "usedBy": ["bf-tab-bar-controller", "bf_tab_links"],
2378
2923
  "since": "0.3.0"
2379
2924
  },
2925
+ {
2926
+ "name": "BfTimelineTone",
2927
+ "slug": "bf-timeline-tone",
2928
+ "kind": "type",
2929
+ "entryPoint": "@bitforgehq/ui",
2930
+ "file": "src/components/timeline/timeline-event.component.ts",
2931
+ "summary": "The marker colour of a timeline event, neutral, primary or a status",
2932
+ "description": "The colour of a `bf-timeline-event`'s marker: `neutral` (the default), `primary`, or a status\n(`success`, `warning`, `danger`, `info`), such as danger for a failed CI run.",
2933
+ "members": [],
2934
+ "methods": [],
2935
+ "slots": [],
2936
+ "references": [],
2937
+ "usedBy": ["bf-timeline-event-component"],
2938
+ "since": "0.4.0",
2939
+ "signature": "type BfTimelineTone = 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info'",
2940
+ "values": ["neutral", "primary", "success", "warning", "danger", "info"]
2941
+ },
2380
2942
  {
2381
2943
  "name": "BfToggleLabelPosition",
2382
2944
  "slug": "bf-toggle-label-position",
@@ -2608,7 +3170,7 @@
2608
3170
  "entryPoint": "@bitforgehq/ui",
2609
3171
  "file": "src/config/labels.ts",
2610
3172
  "summary": "Replaces built-in strings for an app or a sub-tree, such as a translation",
2611
- "description": "Replaces built-in strings, merged over the parent's (validation merged key by key); a key left\nout or set to `undefined` keeps the parent's string. In `ApplicationConfig.providers` it covers\nevery string. In a component's `providers` it covers that sub-tree's widgets and form controls\n(`loading`, `dismiss`, `tabBar`, `tabBadge`, `back`, `refreshing`, `tableSelectAll`, `tableSortBy`,\n`tableSortNone`, `tableSortAscending`, `tableSortDescending`, `theme`, `themeSystem`, `themeLight`, `themeDark`,\n`breadcrumb`, `breadcrumbExpand`, `navigation`, `navBadge`, `sidebarCollapse`, `sidebarExpand`,\n`skipToContent`, `pagination`, `previousPage`, `nextPage`, `pageOf`, `goToPage`, `tabGroup`,\n`calendarPreviousMonth`, `calendarNextMonth`, `calendarChooseMonth`, `calendarChooseYear`,\n`statTrendUp`, `statTrendDown`, `statTrendFlat`, `comboboxEmpty`, `comboboxRemove`,\n`dateInputDay`, `dateInputMonth`, `dateInputYear`, `dateInputOpenCalendar`, `dateInputInvalid`,\n`dateInputUnavailable`, `timeInputHour`, `timeInputMinute`, `timeInputSecond`,\n`timeInputDayPeriod`, `timeInputOpenList`, `timeInputInvalid`, `timeInputMin`, `timeInputMax`,\n`chart`, `chartLegend`, `chartValues`, `chartShowData`, `chartHideData`, `chartCategory`,\n`chartValue`, `chartEmpty`, `chartError`, `validation`); the overlay services (`ok`, `cancel`,\n`actions`, `sheet`, `modal`, `close`, `expand`, `collapse`, `sheetPosition`, `dialog`,\n`notifications`) are root singletons and pick it up only when the caller passes its injector:\n`open(…, { injector: inject(Injector) })`.",
3173
+ "description": "Replaces built-in strings, merged over the parent's (validation merged key by key); a key left\nout or set to `undefined` keeps the parent's string. In `ApplicationConfig.providers` it covers\nevery string. In a component's `providers` it covers that sub-tree's widgets and form controls\n(`loading`, `dismiss`, `tabBar`, `tabBadge`, `back`, `refreshing`, `tableSelectAll`, `tableSortBy`,\n`tableSortNone`, `tableSortAscending`, `tableSortDescending`, `theme`, `themeSystem`, `themeLight`, `themeDark`,\n`breadcrumb`, `breadcrumbExpand`, `navigation`, `navBadge`, `sidebarCollapse`, `sidebarExpand`,\n`skipToContent`, `pagination`, `previousPage`, `nextPage`, `pageOf`, `goToPage`, `tabGroup`,\n`calendarPreviousMonth`, `calendarNextMonth`, `calendarChooseMonth`, `calendarChooseYear`,\n`statTrendUp`, `statTrendDown`, `statTrendFlat`, `comboboxEmpty`, `comboboxRemove`,\n`dateInputDay`, `dateInputMonth`, `dateInputYear`, `dateInputOpenCalendar`, `dateInputInvalid`,\n`dateInputUnavailable`, `timeInputHour`, `timeInputMinute`, `timeInputSecond`,\n`timeInputDayPeriod`, `timeInputOpenList`, `timeInputInvalid`, `timeInputMin`, `timeInputMax`,\n`chart`, `chartLegend`, `chartValues`, `chartShowData`, `chartHideData`, `chartCategory`,\n`chartValue`, `chartEmpty`, `chartError`, `listItemUnread`,\n`fileInputChoose`, `fileInputDropHint`, `fileInputDropzone`, `fileInputTapToChoose`, `fileInputRemove`,\n`fileInputDismiss`, `fileInputAdded`, `fileInputNotAdded`, `fileInputRemoved`, `fileInputCount`,\n`fileRejectedType`, `fileRejectedSize`, `fileRejectedCount`,\n`imageInputChoose`, `imageInputUpload`, `imageInputReplace`, `imageInputRemove`,\n`chatThread`, `chatJumpToLatest`, `chatMessageStopped`, `chatMessageFailed`, `chatComposer`,\n`chatSend`, `chatStop`, `mediaCardSelect`, `imageLoadFailed`, `validation`); the overlay\nservices (`ok`, `cancel`, `actions`, `sheet`, `modal`, `close`, `expand`, `collapse`,\n`sheetPosition`, `dialog`, `notifications`, `imageViewer`, `imageViewerPrevious`,\n`imageViewerNext`, `imageViewerPosition`) are root singletons and pick it up only when the caller passes its injector:\n`open(…, { injector: inject(Injector) })`.",
2612
3174
  "members": [],
2613
3175
  "methods": [
2614
3176
  {
@@ -2623,7 +3185,7 @@
2623
3185
  }
2624
3186
  ],
2625
3187
  "returns": "Provider",
2626
- "doc": "Replaces built-in strings, merged over the parent's (validation merged key by key); a key left\nout or set to `undefined` keeps the parent's string. In `ApplicationConfig.providers` it covers\nevery string. In a component's `providers` it covers that sub-tree's widgets and form controls\n(`loading`, `dismiss`, `tabBar`, `tabBadge`, `back`, `refreshing`, `tableSelectAll`, `tableSortBy`,\n`tableSortNone`, `tableSortAscending`, `tableSortDescending`, `theme`, `themeSystem`, `themeLight`, `themeDark`,\n`breadcrumb`, `breadcrumbExpand`, `navigation`, `navBadge`, `sidebarCollapse`, `sidebarExpand`,\n`skipToContent`, `pagination`, `previousPage`, `nextPage`, `pageOf`, `goToPage`, `tabGroup`,\n`calendarPreviousMonth`, `calendarNextMonth`, `calendarChooseMonth`, `calendarChooseYear`,\n`statTrendUp`, `statTrendDown`, `statTrendFlat`, `comboboxEmpty`, `comboboxRemove`,\n`dateInputDay`, `dateInputMonth`, `dateInputYear`, `dateInputOpenCalendar`, `dateInputInvalid`,\n`dateInputUnavailable`, `timeInputHour`, `timeInputMinute`, `timeInputSecond`,\n`timeInputDayPeriod`, `timeInputOpenList`, `timeInputInvalid`, `timeInputMin`, `timeInputMax`,\n`chart`, `chartLegend`, `chartValues`, `chartShowData`, `chartHideData`, `chartCategory`,\n`chartValue`, `chartEmpty`, `chartError`, `validation`); the overlay services (`ok`, `cancel`,\n`actions`, `sheet`, `modal`, `close`, `expand`, `collapse`, `sheetPosition`, `dialog`,\n`notifications`) are root singletons and pick it up only when the caller passes its injector:\n`open(…, { injector: inject(Injector) })`."
3188
+ "doc": "Replaces built-in strings, merged over the parent's (validation merged key by key); a key left\nout or set to `undefined` keeps the parent's string. In `ApplicationConfig.providers` it covers\nevery string. In a component's `providers` it covers that sub-tree's widgets and form controls\n(`loading`, `dismiss`, `tabBar`, `tabBadge`, `back`, `refreshing`, `tableSelectAll`, `tableSortBy`,\n`tableSortNone`, `tableSortAscending`, `tableSortDescending`, `theme`, `themeSystem`, `themeLight`, `themeDark`,\n`breadcrumb`, `breadcrumbExpand`, `navigation`, `navBadge`, `sidebarCollapse`, `sidebarExpand`,\n`skipToContent`, `pagination`, `previousPage`, `nextPage`, `pageOf`, `goToPage`, `tabGroup`,\n`calendarPreviousMonth`, `calendarNextMonth`, `calendarChooseMonth`, `calendarChooseYear`,\n`statTrendUp`, `statTrendDown`, `statTrendFlat`, `comboboxEmpty`, `comboboxRemove`,\n`dateInputDay`, `dateInputMonth`, `dateInputYear`, `dateInputOpenCalendar`, `dateInputInvalid`,\n`dateInputUnavailable`, `timeInputHour`, `timeInputMinute`, `timeInputSecond`,\n`timeInputDayPeriod`, `timeInputOpenList`, `timeInputInvalid`, `timeInputMin`, `timeInputMax`,\n`chart`, `chartLegend`, `chartValues`, `chartShowData`, `chartHideData`, `chartCategory`,\n`chartValue`, `chartEmpty`, `chartError`, `listItemUnread`,\n`fileInputChoose`, `fileInputDropHint`, `fileInputDropzone`, `fileInputTapToChoose`, `fileInputRemove`,\n`fileInputDismiss`, `fileInputAdded`, `fileInputNotAdded`, `fileInputRemoved`, `fileInputCount`,\n`fileRejectedType`, `fileRejectedSize`, `fileRejectedCount`,\n`imageInputChoose`, `imageInputUpload`, `imageInputReplace`, `imageInputRemove`,\n`chatThread`, `chatJumpToLatest`, `chatMessageStopped`, `chatMessageFailed`, `chatComposer`,\n`chatSend`, `chatStop`, `mediaCardSelect`, `imageLoadFailed`, `validation`); the overlay\nservices (`ok`, `cancel`, `actions`, `sheet`, `modal`, `close`, `expand`, `collapse`,\n`sheetPosition`, `dialog`, `notifications`, `imageViewer`, `imageViewerPrevious`,\n`imageViewerNext`, `imageViewerPosition`) are root singletons and pick it up only when the caller passes its injector:\n`open(…, { injector: inject(Injector) })`."
2627
3189
  }
2628
3190
  ],
2629
3191
  "slots": [],
@@ -3481,139 +4043,434 @@
3481
4043
  "signature": "interface BfDialogTemplateContext<D = unknown, R = unknown>"
3482
4044
  },
3483
4045
  {
3484
- "name": "BfMenuButtonVariant",
3485
- "slug": "bf-menu-button-variant",
3486
- "kind": "type",
3487
- "entryPoint": "@bitforgehq/ui/overlay",
3488
- "file": "overlay/menu-button/menu-button.component.ts",
3489
- "summary": "The three visual styles of a menu button, matching the button styles",
3490
- "description": "The visual style of a `bf-menu-button`: outline, text or tonal, as `bf-button`'s.",
3491
- "members": [],
3492
- "methods": [],
3493
- "slots": [],
3494
- "references": [],
3495
- "usedBy": ["bf-menu-button-component", "bf-theme-menu-button-component"],
3496
- "since": "0.3.0",
3497
- "signature": "type BfMenuButtonVariant = 'outline' | 'text' | 'tonal'",
3498
- "values": ["outline", "text", "tonal"]
3499
- },
3500
- {
3501
- "name": "BfMenuDividerDirective",
3502
- "slug": "bf-menu-divider-directive",
3503
- "kind": "directive",
4046
+ "name": "BfImageViewerActionsContext",
4047
+ "slug": "bf-image-viewer-actions-context",
4048
+ "kind": "interface",
3504
4049
  "entryPoint": "@bitforgehq/ui/overlay",
3505
- "file": "overlay/menu/menu-item.directive.ts",
3506
- "summary": "A line between groups of menu items that keyboard focus never lands on",
3507
- "description": "A line between groups of menu items (role `separator`, not focusable).",
3508
- "members": [],
4050
+ "file": "overlay/image-viewer/image-viewer-ref.ts",
4051
+ "summary": "What the viewer's actions template receives: the shown image, its index and the ref",
4052
+ "description": "Context of the `actions` template of `BfImageViewerService.open()`: `let-image`,\n`let-index=\"index\"` and `let-ref=\"ref\"`.",
4053
+ "members": [
4054
+ {
4055
+ "name": "$implicit",
4056
+ "kind": "property",
4057
+ "type": "BfImageViewerImage",
4058
+ "required": true,
4059
+ "doc": "The image the viewer shows (`let-image`)."
4060
+ },
4061
+ {
4062
+ "name": "index",
4063
+ "kind": "property",
4064
+ "type": "number",
4065
+ "required": true,
4066
+ "doc": "Its 0-based index in the set (`let-index=\"index\"`)."
4067
+ },
4068
+ {
4069
+ "name": "ref",
4070
+ "kind": "property",
4071
+ "type": "BfImageViewerRef",
4072
+ "required": true,
4073
+ "doc": "The viewer's ref (`let-ref=\"ref\"`), to close it or step."
4074
+ }
4075
+ ],
3509
4076
  "methods": [],
3510
4077
  "slots": [],
3511
- "references": [],
3512
- "usedBy": [],
3513
- "since": "0.3.0",
3514
- "selector": "[bfMenuDivider]"
4078
+ "references": ["bf-image-viewer-image", "bf-image-viewer-ref"],
4079
+ "usedBy": ["bf-image-viewer-options"],
4080
+ "since": "0.5.0"
3515
4081
  },
3516
4082
  {
3517
- "name": "BfMenuGroupDirective",
3518
- "slug": "bf-menu-group-directive",
3519
- "kind": "directive",
4083
+ "name": "BfImageViewerImage",
4084
+ "slug": "bf-image-viewer-image",
4085
+ "kind": "interface",
3520
4086
  "entryPoint": "@bitforgehq/ui/overlay",
3521
- "file": "overlay/menu/menu-item.directive.ts",
3522
- "summary": "Groups related menu items; radio items in one group exclude each other",
3523
- "description": "A group of menu items (role `group`); radio items in one group are exclusive. Name it with\n`aria-label` when its items share a topic (\"Density\").",
3524
- "members": [],
4087
+ "file": "overlay/image-viewer/image-viewer-ref.ts",
4088
+ "summary": "One image the viewer shows: its URL, its name as alternative text and a caption",
4089
+ "description": "One image of a `BfImageViewerService.open()` set.",
4090
+ "members": [
4091
+ {
4092
+ "name": "src",
4093
+ "kind": "property",
4094
+ "type": "string",
4095
+ "required": true,
4096
+ "doc": "URL of the full-size image."
4097
+ },
4098
+ {
4099
+ "name": "label",
4100
+ "kind": "property",
4101
+ "type": "string",
4102
+ "required": true,
4103
+ "doc": "The image's name: its alternative text (`alt`), read when it shows and announced after a step (required: the viewer shows nothing else that names it)."
4104
+ },
4105
+ {
4106
+ "name": "caption",
4107
+ "kind": "property",
4108
+ "type": "string",
4109
+ "required": false,
4110
+ "doc": "Text shown under the image; none shows no caption.",
4111
+ "optional": true
4112
+ }
4113
+ ],
3525
4114
  "methods": [],
3526
4115
  "slots": [],
3527
4116
  "references": [],
3528
- "usedBy": [],
3529
- "since": "0.3.0",
3530
- "selector": "[bfMenuGroup]"
4117
+ "usedBy": [
4118
+ "bf-image-viewer-actions-context",
4119
+ "bf-image-viewer-options",
4120
+ "bf-image-viewer-ref"
4121
+ ],
4122
+ "since": "0.5.0"
3531
4123
  },
3532
4124
  {
3533
- "name": "BfMenuItemCheckboxDirective",
3534
- "slug": "bf-menu-item-checkbox-directive",
3535
- "kind": "directive",
4125
+ "name": "BfImageViewerOptions",
4126
+ "slug": "bf-image-viewer-options",
4127
+ "kind": "interface",
3536
4128
  "entryPoint": "@bitforgehq/ui/overlay",
3537
- "file": "overlay/menu/menu-item.directive.ts",
3538
- "summary": "A menu row that toggles an option on and off with a check mark",
3539
- "description": "A toggle row of a `bf-menu` (role `menuitemcheckbox`) with a check mark while `checked`.\nActivating it (click, `Enter`, `Space`) flips its own `checked` (`aria-checked`), emits\n`triggered`, then `changed` (and `checkedChange`) with the new state, and closes the menu. Bind\nit two-way, `[(checked)]`, so your state always follows the item.",
4129
+ "file": "overlay/image-viewer/image-viewer.service.ts",
4130
+ "summary": "Options of an image viewer: its images, the first one, its thumbnail and actions",
4131
+ "description": "Options of `BfImageViewerService.open()`.",
3540
4132
  "members": [
3541
4133
  {
3542
- "name": "checked",
3543
- "kind": "model",
3544
- "type": "boolean",
4134
+ "name": "images",
4135
+ "kind": "property",
4136
+ "type": "readonly BfImageViewerImage[]",
4137
+ "required": true,
4138
+ "doc": "The images to step through, in order; at least one."
4139
+ },
4140
+ {
4141
+ "name": "index",
4142
+ "kind": "property",
4143
+ "type": "number",
3545
4144
  "required": false,
3546
- "doc": "Whether the item is checked. The item flips it itself on activation (and emits `checkedChange`), so bind it two-way: `[(checked)]`.",
3547
- "default": "false",
3548
- "twoWay": true
4145
+ "doc": "Index of the image shown first, wrapped into the set.",
4146
+ "optional": true,
4147
+ "default": "0"
3549
4148
  },
3550
4149
  {
3551
- "name": "changed",
3552
- "kind": "output",
3553
- "type": "boolean",
4150
+ "name": "origin",
4151
+ "kind": "property",
4152
+ "type": "BfImageViewerOrigin",
3554
4153
  "required": false,
3555
- "doc": "Emitted with the new state right after the user toggles the item."
4154
+ "doc": "The thumbnail the viewer zooms out of and back into (or a function returning the thumbnail of an image by index); none fades the viewer in and out.",
4155
+ "optional": true,
4156
+ "expandedType": "HTMLElement | (index: number) => HTMLElement | null | undefined"
3556
4157
  },
3557
4158
  {
3558
- "name": "bfMenuItemDisabled",
3559
- "kind": "input",
3560
- "type": "boolean",
4159
+ "name": "actions",
4160
+ "kind": "property",
4161
+ "type": "TemplateRef<BfImageViewerActionsContext>",
3561
4162
  "required": false,
3562
- "doc": "Whether the item is disabled: it stays focusable and announced, but does not activate."
4163
+ "doc": "Actions under the image, beside its caption (a download link, a \"Use this one\" button); its context is `{ $implicit: image, index, ref }`.",
4164
+ "optional": true
3563
4165
  },
3564
4166
  {
3565
- "name": "bfMenuItemTypeahead",
3566
- "kind": "input",
3567
- "type": "string | null",
4167
+ "name": "ariaLabel",
4168
+ "kind": "property",
4169
+ "type": "string",
3568
4170
  "required": false,
3569
- "doc": "The text typeahead matches the item by (default: its text content)."
4171
+ "doc": "Accessible name of the viewer; empty uses `provideBfLabels()`'s `imageViewer`.",
4172
+ "optional": true
3570
4173
  },
3571
4174
  {
3572
- "name": "triggered",
3573
- "kind": "output",
3574
- "type": "void",
4175
+ "name": "closeOnNavigation",
4176
+ "kind": "property",
4177
+ "type": "boolean",
3575
4178
  "required": false,
3576
- "doc": "Emits when the item is activated (click, `Enter` or `Space`), before `checked` flips."
4179
+ "doc": "A navigation to another URL path closes the viewer (default true).",
4180
+ "optional": true,
4181
+ "default": "true"
4182
+ },
4183
+ {
4184
+ "name": "injector",
4185
+ "kind": "property",
4186
+ "type": "Injector",
4187
+ "required": false,
4188
+ "doc": "Parent of the viewer's injector and source of its labels (default the root injector). Pass the opener's `inject(Injector)` so a feature-level `provideBfLabels()` reaches the viewer.",
4189
+ "optional": true
3577
4190
  }
3578
4191
  ],
3579
4192
  "methods": [],
3580
4193
  "slots": [],
4194
+ "references": [
4195
+ "bf-image-viewer-actions-context",
4196
+ "bf-image-viewer-image",
4197
+ "bf-image-viewer-origin"
4198
+ ],
4199
+ "usedBy": ["bf-image-viewer-service"],
4200
+ "since": "0.5.0"
4201
+ },
4202
+ {
4203
+ "name": "BfImageViewerOrigin",
4204
+ "slug": "bf-image-viewer-origin",
4205
+ "kind": "type",
4206
+ "entryPoint": "@bitforgehq/ui/overlay",
4207
+ "file": "overlay/image-viewer/image-viewer-ref.ts",
4208
+ "summary": "The thumbnail an image viewer zooms from and back into, or a lookup per image",
4209
+ "description": "Where the viewer zooms from and back to: the thumbnail that was clicked, or a function that\nreturns the thumbnail of any image of the set (so closing after stepping zooms into the right\none), `null` for none.",
4210
+ "members": [],
4211
+ "methods": [],
4212
+ "slots": [],
3581
4213
  "references": [],
3582
- "usedBy": [],
3583
- "since": "0.3.0",
3584
- "selector": "button[bfMenuItemCheckbox]"
4214
+ "usedBy": ["bf-image-viewer-options"],
4215
+ "since": "0.5.0",
4216
+ "signature": "type BfImageViewerOrigin = HTMLElement | ((index: number) => HTMLElement | null | undefined) | null"
3585
4217
  },
3586
4218
  {
3587
- "name": "BfMenuItemDirective",
3588
- "slug": "bf-menu-item-directive",
3589
- "kind": "directive",
4219
+ "name": "BfImageViewerRef",
4220
+ "slug": "bf-image-viewer-ref",
4221
+ "kind": "class",
3590
4222
  "entryPoint": "@bitforgehq/ui/overlay",
3591
- "file": "overlay/menu/menu-item.directive.ts",
3592
- "summary": "An action row of a menu on a native button or link, with keyboard rules",
3593
- "description": "An action row of a `bf-menu` (role `menuitem`), on a native `<button>` or a link (`<a>` with\n`href` or `routerLink`). Activating it (click, `Enter`, `Space`) emits `triggered`, closes every\nopen menu and returns focus to the trigger. With `[bfMenuTriggerFor]` on the same element it\nopens a submenu instead (and shows a chevron). A disabled item stays focusable and announces\nitself as disabled, but does not activate; a disabled link does not navigate either, also with\n`routerLink`.",
4223
+ "file": "overlay/image-viewer/image-viewer-ref.ts",
4224
+ "summary": "Handle on an open image viewer that steps through its images and closes it",
4225
+ "description": "Handle to an open image viewer, returned by `BfImageViewerService.open()` and injectable in\nits actions template (`inject(BfImageViewerRef)`). `index` is the shown image; `next()`,\n`previous()` and `goTo()` step through the set (wrapping at both ends), `close()` plays the\nexit motion and resolves `afterClosed`.",
3594
4226
  "members": [
3595
4227
  {
3596
- "name": "bfMenuItemDisabled",
3597
- "kind": "input",
3598
- "type": "boolean",
4228
+ "name": "id",
4229
+ "kind": "property",
4230
+ "type": "string",
3599
4231
  "required": false,
3600
- "doc": "Whether the item is disabled: it stays focusable and announced, but does not activate."
4232
+ "doc": "Unique id of the viewer (its overlay's `bf-overlay-N`).",
4233
+ "readonly": true
3601
4234
  },
3602
4235
  {
3603
- "name": "bfMenuItemTypeahead",
3604
- "kind": "input",
3605
- "type": "string | null",
4236
+ "name": "images",
4237
+ "kind": "property",
4238
+ "type": "readonly BfImageViewerImage[]",
3606
4239
  "required": false,
3607
- "doc": "The text typeahead matches the item by (default: its text content)."
4240
+ "doc": "The images of the set, in order.",
4241
+ "readonly": true
3608
4242
  },
3609
4243
  {
3610
- "name": "triggered",
3611
- "kind": "output",
3612
- "type": "void",
4244
+ "name": "afterClosed",
4245
+ "kind": "property",
4246
+ "type": "Promise<void>",
3613
4247
  "required": false,
3614
- "doc": "Emits when the item is activated (click, `Enter` or `Space`), unless it opens a submenu."
3615
- }
3616
- ],
4248
+ "doc": "Resolves once the viewer has closed and left the page.",
4249
+ "readonly": true
4250
+ },
4251
+ {
4252
+ "name": "closed",
4253
+ "kind": "property",
4254
+ "type": "Signal<boolean>",
4255
+ "required": false,
4256
+ "doc": "True once the viewer has been detached.",
4257
+ "readonly": true
4258
+ },
4259
+ {
4260
+ "name": "index",
4261
+ "kind": "property",
4262
+ "type": "Signal<number>",
4263
+ "required": false,
4264
+ "doc": "Index (0-based) of the image the viewer shows.",
4265
+ "readonly": true
4266
+ }
4267
+ ],
4268
+ "methods": [
4269
+ {
4270
+ "name": "next",
4271
+ "signature": "next(): void",
4272
+ "params": [],
4273
+ "returns": "void",
4274
+ "doc": "Shows the next image; after the last one, the first."
4275
+ },
4276
+ {
4277
+ "name": "previous",
4278
+ "signature": "previous(): void",
4279
+ "params": [],
4280
+ "returns": "void",
4281
+ "doc": "Shows the previous image; before the first one, the last."
4282
+ },
4283
+ {
4284
+ "name": "goTo",
4285
+ "signature": "goTo(index: number): void",
4286
+ "params": [
4287
+ {
4288
+ "name": "index",
4289
+ "type": "number",
4290
+ "optional": false,
4291
+ "doc": "The 0-based index of the image to show."
4292
+ }
4293
+ ],
4294
+ "returns": "void",
4295
+ "doc": "Shows the image at `index`, wrapped into the set (`-1` is the last one)."
4296
+ },
4297
+ {
4298
+ "name": "close",
4299
+ "signature": "close(): void",
4300
+ "params": [],
4301
+ "returns": "void",
4302
+ "doc": "Closes the viewer: it zooms back into its thumbnail, or fades out. Ignored once closing."
4303
+ }
4304
+ ],
4305
+ "slots": [],
4306
+ "references": ["bf-image-viewer-image"],
4307
+ "usedBy": ["bf-image-viewer-actions-context", "bf-image-viewer-service"],
4308
+ "since": "0.5.0"
4309
+ },
4310
+ {
4311
+ "name": "BfImageViewerService",
4312
+ "slug": "bf-image-viewer-service",
4313
+ "kind": "service",
4314
+ "entryPoint": "@bitforgehq/ui/overlay",
4315
+ "file": "overlay/image-viewer/image-viewer.service.ts",
4316
+ "summary": "Opens a full-screen image viewer that zooms from a thumbnail and steps through a set",
4317
+ "description": "Opens a full-screen image viewer (a lightbox) on the overlay core: one image large over a dark\nscrim, previous and next buttons, the arrow keys, Home and End to step through the set\n(wrapping at both ends), a counter, the caption and optional actions. It zooms out of the\nclicked thumbnail (`origin`) and back into it, cross-fades between images, and fades when there\nis no thumbnail on screen; reduced motion only fades. It is a modal dialog: focus moves to its\nclose button and is trapped, `Escape`, the close button and a click on the scrim close it, the\npage behind it is `inert` and does not scroll, and focus returns to the opener.",
4318
+ "members": [],
4319
+ "methods": [
4320
+ {
4321
+ "name": "open",
4322
+ "signature": "open(options: BfImageViewerOptions): BfImageViewerRef",
4323
+ "params": [
4324
+ {
4325
+ "name": "options",
4326
+ "type": "BfImageViewerOptions",
4327
+ "optional": false,
4328
+ "doc": "The images, the first index, the thumbnail, the actions and the injector."
4329
+ }
4330
+ ],
4331
+ "returns": "BfImageViewerRef",
4332
+ "doc": "Opens the viewer on `options.images`, showing `options.index` first."
4333
+ }
4334
+ ],
4335
+ "slots": [],
4336
+ "references": ["bf-image-viewer-options", "bf-image-viewer-ref"],
4337
+ "usedBy": [],
4338
+ "since": "0.5.0"
4339
+ },
4340
+ {
4341
+ "name": "BfMenuButtonVariant",
4342
+ "slug": "bf-menu-button-variant",
4343
+ "kind": "type",
4344
+ "entryPoint": "@bitforgehq/ui/overlay",
4345
+ "file": "overlay/menu-button/menu-button.component.ts",
4346
+ "summary": "The three visual styles of a menu button, matching the button styles",
4347
+ "description": "The visual style of a `bf-menu-button`: outline, text or tonal, as `bf-button`'s.",
4348
+ "members": [],
4349
+ "methods": [],
4350
+ "slots": [],
4351
+ "references": [],
4352
+ "usedBy": ["bf-menu-button-component", "bf-theme-menu-button-component"],
4353
+ "since": "0.3.0",
4354
+ "signature": "type BfMenuButtonVariant = 'outline' | 'text' | 'tonal'",
4355
+ "values": ["outline", "text", "tonal"]
4356
+ },
4357
+ {
4358
+ "name": "BfMenuDividerDirective",
4359
+ "slug": "bf-menu-divider-directive",
4360
+ "kind": "directive",
4361
+ "entryPoint": "@bitforgehq/ui/overlay",
4362
+ "file": "overlay/menu/menu-item.directive.ts",
4363
+ "summary": "A line between groups of menu items that keyboard focus never lands on",
4364
+ "description": "A line between groups of menu items (role `separator`, not focusable).",
4365
+ "members": [],
4366
+ "methods": [],
4367
+ "slots": [],
4368
+ "references": [],
4369
+ "usedBy": [],
4370
+ "since": "0.3.0",
4371
+ "selector": "[bfMenuDivider]"
4372
+ },
4373
+ {
4374
+ "name": "BfMenuGroupDirective",
4375
+ "slug": "bf-menu-group-directive",
4376
+ "kind": "directive",
4377
+ "entryPoint": "@bitforgehq/ui/overlay",
4378
+ "file": "overlay/menu/menu-item.directive.ts",
4379
+ "summary": "Groups related menu items; radio items in one group exclude each other",
4380
+ "description": "A group of menu items (role `group`); radio items in one group are exclusive. Name it with\n`aria-label` when its items share a topic (\"Density\").",
4381
+ "members": [],
4382
+ "methods": [],
4383
+ "slots": [],
4384
+ "references": [],
4385
+ "usedBy": [],
4386
+ "since": "0.3.0",
4387
+ "selector": "[bfMenuGroup]"
4388
+ },
4389
+ {
4390
+ "name": "BfMenuItemCheckboxDirective",
4391
+ "slug": "bf-menu-item-checkbox-directive",
4392
+ "kind": "directive",
4393
+ "entryPoint": "@bitforgehq/ui/overlay",
4394
+ "file": "overlay/menu/menu-item.directive.ts",
4395
+ "summary": "A menu row that toggles an option on and off with a check mark",
4396
+ "description": "A toggle row of a `bf-menu` (role `menuitemcheckbox`) with a check mark while `checked`.\nActivating it (click, `Enter`, `Space`) flips its own `checked` (`aria-checked`), emits\n`triggered`, then `changed` (and `checkedChange`) with the new state, and closes the menu. Bind\nit two-way, `[(checked)]`, so your state always follows the item.",
4397
+ "members": [
4398
+ {
4399
+ "name": "checked",
4400
+ "kind": "model",
4401
+ "type": "boolean",
4402
+ "required": false,
4403
+ "doc": "Whether the item is checked. The item flips it itself on activation (and emits `checkedChange`), so bind it two-way: `[(checked)]`.",
4404
+ "default": "false",
4405
+ "twoWay": true
4406
+ },
4407
+ {
4408
+ "name": "changed",
4409
+ "kind": "output",
4410
+ "type": "boolean",
4411
+ "required": false,
4412
+ "doc": "Emitted with the new state right after the user toggles the item."
4413
+ },
4414
+ {
4415
+ "name": "bfMenuItemDisabled",
4416
+ "kind": "input",
4417
+ "type": "boolean",
4418
+ "required": false,
4419
+ "doc": "Whether the item is disabled: it stays focusable and announced, but does not activate."
4420
+ },
4421
+ {
4422
+ "name": "bfMenuItemTypeahead",
4423
+ "kind": "input",
4424
+ "type": "string | null",
4425
+ "required": false,
4426
+ "doc": "The text typeahead matches the item by (default: its text content)."
4427
+ },
4428
+ {
4429
+ "name": "triggered",
4430
+ "kind": "output",
4431
+ "type": "void",
4432
+ "required": false,
4433
+ "doc": "Emits when the item is activated (click, `Enter` or `Space`), before `checked` flips."
4434
+ }
4435
+ ],
4436
+ "methods": [],
4437
+ "slots": [],
4438
+ "references": [],
4439
+ "usedBy": [],
4440
+ "since": "0.3.0",
4441
+ "selector": "button[bfMenuItemCheckbox]"
4442
+ },
4443
+ {
4444
+ "name": "BfMenuItemDirective",
4445
+ "slug": "bf-menu-item-directive",
4446
+ "kind": "directive",
4447
+ "entryPoint": "@bitforgehq/ui/overlay",
4448
+ "file": "overlay/menu/menu-item.directive.ts",
4449
+ "summary": "An action row of a menu on a native button or link, with keyboard rules",
4450
+ "description": "An action row of a `bf-menu` (role `menuitem`), on a native `<button>` or a link (`<a>` with\n`href` or `routerLink`). Activating it (click, `Enter`, `Space`) emits `triggered`, closes every\nopen menu and returns focus to the trigger. With `[bfMenuTriggerFor]` on the same element it\nopens a submenu instead (and shows a chevron). A disabled item stays focusable and announces\nitself as disabled, but does not activate; a disabled link does not navigate either, also with\n`routerLink`.",
4451
+ "members": [
4452
+ {
4453
+ "name": "bfMenuItemDisabled",
4454
+ "kind": "input",
4455
+ "type": "boolean",
4456
+ "required": false,
4457
+ "doc": "Whether the item is disabled: it stays focusable and announced, but does not activate."
4458
+ },
4459
+ {
4460
+ "name": "bfMenuItemTypeahead",
4461
+ "kind": "input",
4462
+ "type": "string | null",
4463
+ "required": false,
4464
+ "doc": "The text typeahead matches the item by (default: its text content)."
4465
+ },
4466
+ {
4467
+ "name": "triggered",
4468
+ "kind": "output",
4469
+ "type": "void",
4470
+ "required": false,
4471
+ "doc": "Emits when the item is activated (click, `Enter` or `Space`), unless it opens a submenu."
4472
+ }
4473
+ ],
3617
4474
  "methods": [],
3618
4475
  "slots": [],
3619
4476
  "references": [],
@@ -5359,6 +6216,30 @@
5359
6216
  "since": "0.3.0",
5360
6217
  "signature": "function provideBfDesktopToast(config?: Partial<BfDesktopToastConfig>): EnvironmentProviders"
5361
6218
  },
6219
+ {
6220
+ "name": "provideBfSelect",
6221
+ "slug": "provide-bf-select",
6222
+ "kind": "function",
6223
+ "entryPoint": "@bitforgehq/ui/overlay",
6224
+ "file": "overlay/select/provide-bf-select.ts",
6225
+ "summary": "Makes a stacked table's Sort by select the styled bf-select, app-wide",
6226
+ "description": "Makes the library's built-in selects use the styled `bf-select`: a stacked `bf-table` then\nrenders its Sort by select as a `bf-select` (the native `<select>` under a coarse pointer, as\n`bf-select` itself does) instead of the plain native one. Add it to\n`ApplicationConfig.providers`.",
6227
+ "members": [],
6228
+ "methods": [
6229
+ {
6230
+ "name": "provideBfSelect",
6231
+ "signature": "provideBfSelect(): EnvironmentProviders",
6232
+ "params": [],
6233
+ "returns": "EnvironmentProviders",
6234
+ "doc": "Makes the library's built-in selects use the styled `bf-select`: a stacked `bf-table` then\nrenders its Sort by select as a `bf-select` (the native `<select>` under a coarse pointer, as\n`bf-select` itself does) instead of the plain native one. Add it to\n`ApplicationConfig.providers`."
6235
+ }
6236
+ ],
6237
+ "slots": [],
6238
+ "references": [],
6239
+ "usedBy": [],
6240
+ "since": "0.5.0",
6241
+ "signature": "function provideBfSelect(): EnvironmentProviders"
6242
+ },
5362
6243
  {
5363
6244
  "name": "scaleIn",
5364
6245
  "slug": "scale-in",
@@ -8614,13 +9495,13 @@
8614
9495
  "signature": "class BfChartHarness extends ComponentHarness"
8615
9496
  },
8616
9497
  {
8617
- "name": "BfComboboxHarness",
8618
- "slug": "bf-combobox-harness",
9498
+ "name": "BfChatComposerHarness",
9499
+ "slug": "bf-chat-composer-harness",
8619
9500
  "kind": "class",
8620
9501
  "entryPoint": "@bitforgehq/ui/testing",
8621
- "file": "testing/harnesses/combobox.harness.ts",
8622
- "summary": "Test harness for the comboboxes: types, reads and picks options and tags",
8623
- "description": "Harness for `bf-combobox` and `bf-multi-combobox`. Its option list renders in the CDK overlay\ncontainer while open (found through the input's `aria-controls`); it works by option label, so a\ntest never needs the option values. Its `label` filter matches the visible label, else the\n`aria-label`.",
9502
+ "file": "testing/harnesses/chat-composer.harness.ts",
9503
+ "summary": "Test harness for the chat composer: types, sends, stops and reads its state",
9504
+ "description": "Harness for `bf-chat-composer` (`@bitforgehq/ui/overlay`). Its `label` filter matches the text\nfield's name: the visible label, else its `aria-label` (\"Message\" by default).",
8624
9505
  "members": [],
8625
9506
  "methods": [
8626
9507
  {
@@ -8628,53 +9509,147 @@
8628
9509
  "signature": "getLabel(): Promise<string>",
8629
9510
  "params": [],
8630
9511
  "returns": "Promise<string>",
8631
- "doc": "The visible label without the required mark, else the `aria-label`."
8632
- },
8633
- {
8634
- "name": "open",
8635
- "signature": "open(): Promise<void>",
8636
- "params": [],
8637
- "returns": "Promise<void>",
8638
- "doc": "Opens the option list with a click into the field; does nothing while it is open."
8639
- },
8640
- {
8641
- "name": "close",
8642
- "signature": "close(): Promise<void>",
8643
- "params": [],
8644
- "returns": "Promise<void>",
8645
- "doc": "Closes the option list with `Escape`, as a user would; does nothing while it is closed."
9512
+ "doc": "The text field's name: the visible label, else its `aria-label`."
8646
9513
  },
8647
9514
  {
8648
- "name": "isOpen",
8649
- "signature": "isOpen(): Promise<boolean>",
9515
+ "name": "getValue",
9516
+ "signature": "getValue(): Promise<string>",
8650
9517
  "params": [],
8651
- "returns": "Promise<boolean>",
8652
- "doc": "Whether the option list is open (`aria-expanded`)."
9518
+ "returns": "Promise<string>",
9519
+ "doc": "The text in the field."
8653
9520
  },
8654
9521
  {
8655
- "name": "type",
8656
- "signature": "type(query: string): Promise<void>",
9522
+ "name": "setValue",
9523
+ "signature": "setValue(text: string): Promise<void>",
8657
9524
  "params": [
8658
9525
  {
8659
- "name": "query",
9526
+ "name": "text",
8660
9527
  "type": "string",
8661
9528
  "optional": false,
8662
- "doc": "The text to type."
9529
+ "doc": "The new text."
8663
9530
  }
8664
9531
  ],
8665
9532
  "returns": "Promise<void>",
8666
- "doc": "Replaces the field's text with `query`, key by key as a user types; the list opens filtered."
9533
+ "doc": "Replaces the text as the user would type it (`changed` and the value update)."
8667
9534
  },
8668
9535
  {
8669
- "name": "getOptionLabels",
8670
- "signature": "getOptionLabels(): Promise<string[]>",
9536
+ "name": "send",
9537
+ "signature": "send(): Promise<void>",
8671
9538
  "params": [],
8672
- "returns": "Promise<string[]>",
8673
- "doc": "The labels of the listed options, in order, opening the list first when it is closed."
9539
+ "returns": "Promise<void>",
9540
+ "doc": "Sends the text with the send button, as a click does. Does nothing while it cannot send."
8674
9541
  },
8675
9542
  {
8676
- "name": "selectOption",
8677
- "signature": "selectOption(label: string): Promise<void>",
9543
+ "name": "pressEnter",
9544
+ "signature": "pressEnter(): Promise<void>",
9545
+ "params": [],
9546
+ "returns": "Promise<void>",
9547
+ "doc": "Sends the text with `Enter` in the field, as the keyboard does."
9548
+ },
9549
+ {
9550
+ "name": "stop",
9551
+ "signature": "stop(): Promise<void>",
9552
+ "params": [],
9553
+ "returns": "Promise<void>",
9554
+ "doc": "Stops the running reply with the stop button. Does nothing unless a reply is running."
9555
+ },
9556
+ {
9557
+ "name": "isRunning",
9558
+ "signature": "isRunning(): Promise<boolean>",
9559
+ "params": [],
9560
+ "returns": "Promise<boolean>",
9561
+ "doc": "Whether a reply is running, so the button stops instead of sending."
9562
+ },
9563
+ {
9564
+ "name": "isDisabled",
9565
+ "signature": "isDisabled(): Promise<boolean>",
9566
+ "params": [],
9567
+ "returns": "Promise<boolean>",
9568
+ "doc": "Whether the composer is disabled (its text field is)."
9569
+ },
9570
+ {
9571
+ "name": "canAct",
9572
+ "signature": "canAct(): Promise<boolean>",
9573
+ "params": [],
9574
+ "returns": "Promise<boolean>",
9575
+ "doc": "Whether the button can send (or stop) now: not disabled and, to send, with text."
9576
+ },
9577
+ {
9578
+ "name": "getButtonLabel",
9579
+ "signature": "getButtonLabel(): Promise<string>",
9580
+ "params": [],
9581
+ "returns": "Promise<string>",
9582
+ "doc": "The button's name, \"Send\" or \"Stop\" by default."
9583
+ }
9584
+ ],
9585
+ "slots": [],
9586
+ "references": [],
9587
+ "usedBy": [],
9588
+ "since": "0.5.0",
9589
+ "signature": "class BfChatComposerHarness extends ComponentHarness"
9590
+ },
9591
+ {
9592
+ "name": "BfComboboxHarness",
9593
+ "slug": "bf-combobox-harness",
9594
+ "kind": "class",
9595
+ "entryPoint": "@bitforgehq/ui/testing",
9596
+ "file": "testing/harnesses/combobox.harness.ts",
9597
+ "summary": "Test harness for the comboboxes: types, reads and picks options and tags",
9598
+ "description": "Harness for `bf-combobox` and `bf-multi-combobox`. Its option list renders in the CDK overlay\ncontainer while open (found through the input's `aria-controls`); it works by option label, so a\ntest never needs the option values. Its `label` filter matches the visible label, else the\n`aria-label`.",
9599
+ "members": [],
9600
+ "methods": [
9601
+ {
9602
+ "name": "getLabel",
9603
+ "signature": "getLabel(): Promise<string>",
9604
+ "params": [],
9605
+ "returns": "Promise<string>",
9606
+ "doc": "The visible label without the required mark, else the `aria-label`."
9607
+ },
9608
+ {
9609
+ "name": "open",
9610
+ "signature": "open(): Promise<void>",
9611
+ "params": [],
9612
+ "returns": "Promise<void>",
9613
+ "doc": "Opens the option list with a click into the field; does nothing while it is open."
9614
+ },
9615
+ {
9616
+ "name": "close",
9617
+ "signature": "close(): Promise<void>",
9618
+ "params": [],
9619
+ "returns": "Promise<void>",
9620
+ "doc": "Closes the option list with `Escape`, as a user would; does nothing while it is closed."
9621
+ },
9622
+ {
9623
+ "name": "isOpen",
9624
+ "signature": "isOpen(): Promise<boolean>",
9625
+ "params": [],
9626
+ "returns": "Promise<boolean>",
9627
+ "doc": "Whether the option list is open (`aria-expanded`)."
9628
+ },
9629
+ {
9630
+ "name": "type",
9631
+ "signature": "type(query: string): Promise<void>",
9632
+ "params": [
9633
+ {
9634
+ "name": "query",
9635
+ "type": "string",
9636
+ "optional": false,
9637
+ "doc": "The text to type."
9638
+ }
9639
+ ],
9640
+ "returns": "Promise<void>",
9641
+ "doc": "Replaces the field's text with `query`, key by key as a user types; the list opens filtered."
9642
+ },
9643
+ {
9644
+ "name": "getOptionLabels",
9645
+ "signature": "getOptionLabels(): Promise<string[]>",
9646
+ "params": [],
9647
+ "returns": "Promise<string[]>",
9648
+ "doc": "The labels of the listed options, in order, opening the list first when it is closed."
9649
+ },
9650
+ {
9651
+ "name": "selectOption",
9652
+ "signature": "selectOption(label: string): Promise<void>",
8678
9653
  "params": [
8679
9654
  {
8680
9655
  "name": "label",
@@ -9048,6 +10023,100 @@
9048
10023
  "since": "0.3.0",
9049
10024
  "signature": "class BfDialogHarness extends ComponentHarness"
9050
10025
  },
10026
+ {
10027
+ "name": "BfFileInputHarness",
10028
+ "slug": "bf-file-input-harness",
10029
+ "kind": "class",
10030
+ "entryPoint": "@bitforgehq/ui/testing",
10031
+ "file": "testing/harnesses/file-input.harness.ts",
10032
+ "summary": "Test harness for the file input: drops files and reads the list and rejections",
10033
+ "description": "Harness for `bf-file-input`, in both looks. `addFiles()` drops files on the field, so they go\nthrough the same `accept`, `maxSize` and `maxFiles` rules as a real drop; read the outcome with\n`getFileNames()` and `getRejected()`. It works by file name, so a test never needs the rows.",
10034
+ "members": [],
10035
+ "methods": [
10036
+ {
10037
+ "name": "getLabel",
10038
+ "signature": "getLabel(): Promise<string>",
10039
+ "params": [],
10040
+ "returns": "Promise<string>",
10041
+ "doc": "The visible label without the required mark, else `ariaLabel`."
10042
+ },
10043
+ {
10044
+ "name": "getErrorText",
10045
+ "signature": "getErrorText(): Promise<string>",
10046
+ "params": [],
10047
+ "returns": "Promise<string>",
10048
+ "doc": "The error text under the field (an explicit message, or the first form error once touched)."
10049
+ },
10050
+ {
10051
+ "name": "getVariant",
10052
+ "signature": "getVariant(): Promise<'field' | 'dropzone'>",
10053
+ "params": [],
10054
+ "returns": "Promise<'field' | 'dropzone'>",
10055
+ "doc": "The look of the field."
10056
+ },
10057
+ {
10058
+ "name": "isDisabled",
10059
+ "signature": "isDisabled(): Promise<boolean>",
10060
+ "params": [],
10061
+ "returns": "Promise<boolean>",
10062
+ "doc": "Whether the field is disabled."
10063
+ },
10064
+ {
10065
+ "name": "isReadonly",
10066
+ "signature": "isReadonly(): Promise<boolean>",
10067
+ "params": [],
10068
+ "returns": "Promise<boolean>",
10069
+ "doc": "Whether the field is read-only: it has no pick target."
10070
+ },
10071
+ {
10072
+ "name": "addFiles",
10073
+ "signature": "addFiles(files: File[]): Promise<void>",
10074
+ "params": [
10075
+ {
10076
+ "name": "files",
10077
+ "type": "File[]",
10078
+ "optional": false,
10079
+ "doc": "The files to drop."
10080
+ }
10081
+ ],
10082
+ "returns": "Promise<void>",
10083
+ "doc": "Drops files on the field, as a user would. On a disabled or read-only field it does nothing,\nlike the UI."
10084
+ },
10085
+ {
10086
+ "name": "getFileNames",
10087
+ "signature": "getFileNames(): Promise<string[]>",
10088
+ "params": [],
10089
+ "returns": "Promise<string[]>",
10090
+ "doc": "The names of the chosen files, in order (rejected files are not included)."
10091
+ },
10092
+ {
10093
+ "name": "getRejected",
10094
+ "signature": "getRejected(): Promise<{ name: string; message: string }[]>",
10095
+ "params": [],
10096
+ "returns": "Promise<{ name: string; message: string }[]>",
10097
+ "doc": "The files the last pick or drop refused, each with its reason, until they are dismissed."
10098
+ },
10099
+ {
10100
+ "name": "removeFile",
10101
+ "signature": "removeFile(name: string): Promise<void>",
10102
+ "params": [
10103
+ {
10104
+ "name": "name",
10105
+ "type": "string",
10106
+ "optional": false,
10107
+ "doc": "The file's name."
10108
+ }
10109
+ ],
10110
+ "returns": "Promise<void>",
10111
+ "doc": "Removes the chosen file with this name, as the row's remove button does. Throws when no\nchosen file has that name or the field cannot be edited."
10112
+ }
10113
+ ],
10114
+ "slots": [],
10115
+ "references": [],
10116
+ "usedBy": [],
10117
+ "since": "0.5.0",
10118
+ "signature": "class BfFileInputHarness extends ComponentHarness"
10119
+ },
9051
10120
  {
9052
10121
  "name": "BfHarnessFilters",
9053
10122
  "slug": "bf-harness-filters",
@@ -9073,6 +10142,222 @@
9073
10142
  "since": "0.3.0",
9074
10143
  "signature": "interface BfHarnessFilters extends BaseHarnessFilters"
9075
10144
  },
10145
+ {
10146
+ "name": "BfImageInputHarness",
10147
+ "slug": "bf-image-input-harness",
10148
+ "kind": "class",
10149
+ "entryPoint": "@bitforgehq/ui/testing",
10150
+ "file": "testing/harnesses/image-input.harness.ts",
10151
+ "summary": "Test harness for the image input: drops an image on it and reads the preview",
10152
+ "description": "Harness for `bf-image-input`. `addFile()` drops the image on the tile, so it goes through the\nsame `accept` and `maxSize` rules as a real drop; read the outcome with `hasPreview()`,\n`getPreviewSrc()` and `getRejectedMessage()`. jsdom has no `URL.createObjectURL`, so a picked\nimage shows no preview there: assert on the bound value, or stub `URL.createObjectURL` to read\nthe preview.",
10153
+ "members": [],
10154
+ "methods": [
10155
+ {
10156
+ "name": "getLabel",
10157
+ "signature": "getLabel(): Promise<string>",
10158
+ "params": [],
10159
+ "returns": "Promise<string>",
10160
+ "doc": "The visible label without the required mark, else the tile's `aria-label`."
10161
+ },
10162
+ {
10163
+ "name": "getErrorText",
10164
+ "signature": "getErrorText(): Promise<string>",
10165
+ "params": [],
10166
+ "returns": "Promise<string>",
10167
+ "doc": "The error text beside the tile (an explicit message, or the first form error once touched)."
10168
+ },
10169
+ {
10170
+ "name": "isDisabled",
10171
+ "signature": "isDisabled(): Promise<boolean>",
10172
+ "params": [],
10173
+ "returns": "Promise<boolean>",
10174
+ "doc": "Whether the control is disabled."
10175
+ },
10176
+ {
10177
+ "name": "isReadonly",
10178
+ "signature": "isReadonly(): Promise<boolean>",
10179
+ "params": [],
10180
+ "returns": "Promise<boolean>",
10181
+ "doc": "Whether the control is read-only: its tile is not a button and there are no Upload or Remove\nbuttons."
10182
+ },
10183
+ {
10184
+ "name": "hasPreview",
10185
+ "signature": "hasPreview(): Promise<boolean>",
10186
+ "params": [],
10187
+ "returns": "Promise<boolean>",
10188
+ "doc": "Whether the tile shows an image, picked or from `src`. A picked image needs\n`URL.createObjectURL`, which jsdom lacks: stub it to see one."
10189
+ },
10190
+ {
10191
+ "name": "getPreviewSrc",
10192
+ "signature": "getPreviewSrc(): Promise<string | null>",
10193
+ "params": [],
10194
+ "returns": "Promise<string | null>",
10195
+ "doc": "The `src` of the shown image."
10196
+ },
10197
+ {
10198
+ "name": "addFile",
10199
+ "signature": "addFile(file: File): Promise<void>",
10200
+ "params": [
10201
+ {
10202
+ "name": "file",
10203
+ "type": "File",
10204
+ "optional": false,
10205
+ "doc": "The image to drop."
10206
+ }
10207
+ ],
10208
+ "returns": "Promise<void>",
10209
+ "doc": "Drops an image on the tile, as a user would. On a disabled or read-only control it does\nnothing, like the UI. It waits on no timer, so it works under fake timers and `fakeAsync`."
10210
+ },
10211
+ {
10212
+ "name": "remove",
10213
+ "signature": "remove(): Promise<void>",
10214
+ "params": [],
10215
+ "returns": "Promise<void>",
10216
+ "doc": "Presses Remove, which clears the picked and the existing image. Throws while there is no\nimage or the control cannot be edited."
10217
+ },
10218
+ {
10219
+ "name": "getRejectedMessage",
10220
+ "signature": "getRejectedMessage(): Promise<string>",
10221
+ "params": [],
10222
+ "returns": "Promise<string>",
10223
+ "doc": "The reason the last pick was refused, until the next pick or Remove."
10224
+ }
10225
+ ],
10226
+ "slots": [],
10227
+ "references": [],
10228
+ "usedBy": [],
10229
+ "since": "0.5.0",
10230
+ "signature": "class BfImageInputHarness extends ComponentHarness"
10231
+ },
10232
+ {
10233
+ "name": "BfImageViewerHarness",
10234
+ "slug": "bf-image-viewer-harness",
10235
+ "kind": "class",
10236
+ "entryPoint": "@bitforgehq/ui/testing",
10237
+ "file": "testing/harnesses/image-viewer.harness.ts",
10238
+ "summary": "Test harness for an image viewer: its image, index, caption, steps and close",
10239
+ "description": "Harness for `bf-image-viewer`, the lightbox `BfImageViewerService.open()` renders. It renders\nin the CDK overlay container outside the tested component, so get it through\n`TestbedHarnessEnvironment.documentRootLoader(fixture)`. jsdom never loads images: call\n`loadImage()` to fire the shown image's `load` event.",
10240
+ "members": [],
10241
+ "methods": [
10242
+ {
10243
+ "name": "getLabel",
10244
+ "signature": "getLabel(): Promise<string>",
10245
+ "params": [],
10246
+ "returns": "Promise<string>",
10247
+ "doc": "The viewer's accessible name (`ariaLabel`, else the `imageViewer` label)."
10248
+ },
10249
+ {
10250
+ "name": "getIndex",
10251
+ "signature": "getIndex(): Promise<number>",
10252
+ "params": [],
10253
+ "returns": "Promise<number>",
10254
+ "doc": "The 0-based index of the shown image."
10255
+ },
10256
+ {
10257
+ "name": "getCount",
10258
+ "signature": "getCount(): Promise<number>",
10259
+ "params": [],
10260
+ "returns": "Promise<number>",
10261
+ "doc": "How many images the viewer steps through."
10262
+ },
10263
+ {
10264
+ "name": "getCounterText",
10265
+ "signature": "getCounterText(): Promise<string>",
10266
+ "params": [],
10267
+ "returns": "Promise<string>",
10268
+ "doc": "The counter's text (\"2 of 5\"); a viewer of one image shows none."
10269
+ },
10270
+ {
10271
+ "name": "getSrc",
10272
+ "signature": "getSrc(): Promise<string>",
10273
+ "params": [],
10274
+ "returns": "Promise<string>",
10275
+ "doc": "The URL of the shown image."
10276
+ },
10277
+ {
10278
+ "name": "getAlt",
10279
+ "signature": "getAlt(): Promise<string>",
10280
+ "params": [],
10281
+ "returns": "Promise<string>",
10282
+ "doc": "The alternative text of the shown image."
10283
+ },
10284
+ {
10285
+ "name": "getCaption",
10286
+ "signature": "getCaption(): Promise<string>",
10287
+ "params": [],
10288
+ "returns": "Promise<string>",
10289
+ "doc": "The caption under the shown image."
10290
+ },
10291
+ {
10292
+ "name": "isLoaded",
10293
+ "signature": "isLoaded(): Promise<boolean>",
10294
+ "params": [],
10295
+ "returns": "Promise<boolean>",
10296
+ "doc": "Whether the shown image has loaded (no spinner and no failure message)."
10297
+ },
10298
+ {
10299
+ "name": "hasFailed",
10300
+ "signature": "hasFailed(): Promise<boolean>",
10301
+ "params": [],
10302
+ "returns": "Promise<boolean>",
10303
+ "doc": "Whether the shown image failed to load (the failure message shows)."
10304
+ },
10305
+ {
10306
+ "name": "loadImage",
10307
+ "signature": "loadImage(): Promise<void>",
10308
+ "params": [],
10309
+ "returns": "Promise<void>",
10310
+ "doc": "Fires the shown image's `load` event, as a browser does when it arrives."
10311
+ },
10312
+ {
10313
+ "name": "failImage",
10314
+ "signature": "failImage(): Promise<void>",
10315
+ "params": [],
10316
+ "returns": "Promise<void>",
10317
+ "doc": "Fires the shown image's `error` event, as a browser does when it fails."
10318
+ },
10319
+ {
10320
+ "name": "next",
10321
+ "signature": "next(): Promise<void>",
10322
+ "params": [],
10323
+ "returns": "Promise<void>",
10324
+ "doc": "Clicks the next button. Throws for a viewer of one image (it has none)."
10325
+ },
10326
+ {
10327
+ "name": "previous",
10328
+ "signature": "previous(): Promise<void>",
10329
+ "params": [],
10330
+ "returns": "Promise<void>",
10331
+ "doc": "Clicks the previous button. Throws for a viewer of one image (it has none)."
10332
+ },
10333
+ {
10334
+ "name": "pressKey",
10335
+ "signature": "pressKey(key: 'ArrowLeft' | 'ArrowRight' | 'Home' | 'End' | 'Escape'): Promise<void>",
10336
+ "params": [
10337
+ {
10338
+ "name": "key",
10339
+ "type": "'ArrowLeft' | 'ArrowRight' | 'Home' | 'End' | 'Escape'",
10340
+ "optional": false,
10341
+ "doc": "The key to press."
10342
+ }
10343
+ ],
10344
+ "returns": "Promise<void>",
10345
+ "doc": "Presses a key inside the viewer: ArrowLeft and ArrowRight step, Home and End jump, Escape\ncloses."
10346
+ },
10347
+ {
10348
+ "name": "close",
10349
+ "signature": "close(): Promise<void>",
10350
+ "params": [],
10351
+ "returns": "Promise<void>",
10352
+ "doc": "Clicks the close button."
10353
+ }
10354
+ ],
10355
+ "slots": [],
10356
+ "references": [],
10357
+ "usedBy": [],
10358
+ "since": "0.5.0",
10359
+ "signature": "class BfImageViewerHarness extends ComponentHarness"
10360
+ },
9076
10361
  {
9077
10362
  "name": "BfJsdomShimOptions",
9078
10363
  "slug": "bf-jsdom-shim-options",
@@ -9107,6 +10392,100 @@
9107
10392
  "usedBy": ["install-bf-jsdom-shims"],
9108
10393
  "since": "0.3.0"
9109
10394
  },
10395
+ {
10396
+ "name": "BfMediaCardHarness",
10397
+ "slug": "bf-media-card-harness",
10398
+ "kind": "class",
10399
+ "entryPoint": "@bitforgehq/ui/testing",
10400
+ "file": "testing/harnesses/media-card.harness.ts",
10401
+ "summary": "Test harness for a media card: its image state, its messages and its selection",
10402
+ "description": "Harness for `bf-media-card`. jsdom never loads images, so `loadImage()` and `failImage()` fire\nthe image's `load` and `error` events the way a browser would; `getState()` then tells what the\nimage area shows.",
10403
+ "members": [],
10404
+ "methods": [
10405
+ {
10406
+ "name": "getTitle",
10407
+ "signature": "getTitle(): Promise<string>",
10408
+ "params": [],
10409
+ "returns": "Promise<string>",
10410
+ "doc": "The card's title: the text of the first heading in its body."
10411
+ },
10412
+ {
10413
+ "name": "getState",
10414
+ "signature": "getState(): Promise<'empty' | 'loading' | 'loaded' | 'failed'>",
10415
+ "params": [],
10416
+ "returns": "Promise<'empty' | 'loading' | 'loaded' | 'failed'>",
10417
+ "doc": "What the image area shows: `empty` (no `src`, not loading), `loading` (the skeleton),\n`loaded` (the image) or `failed` (the failure message)."
10418
+ },
10419
+ {
10420
+ "name": "getSrc",
10421
+ "signature": "getSrc(): Promise<string>",
10422
+ "params": [],
10423
+ "returns": "Promise<string>",
10424
+ "doc": "The URL of the image."
10425
+ },
10426
+ {
10427
+ "name": "getAlt",
10428
+ "signature": "getAlt(): Promise<string>",
10429
+ "params": [],
10430
+ "returns": "Promise<string>",
10431
+ "doc": "The alternative text of the image."
10432
+ },
10433
+ {
10434
+ "name": "getLoadingLabel",
10435
+ "signature": "getLoadingLabel(): Promise<string>",
10436
+ "params": [],
10437
+ "returns": "Promise<string>",
10438
+ "doc": "The caption over the skeleton while loading (the `loading` label when none is set)."
10439
+ },
10440
+ {
10441
+ "name": "getFailedMessage",
10442
+ "signature": "getFailedMessage(): Promise<string>",
10443
+ "params": [],
10444
+ "returns": "Promise<string>",
10445
+ "doc": "The failure message."
10446
+ },
10447
+ {
10448
+ "name": "loadImage",
10449
+ "signature": "loadImage(): Promise<void>",
10450
+ "params": [],
10451
+ "returns": "Promise<void>",
10452
+ "doc": "Fires the image's `load` event, as a browser does when it arrives. Throws without one."
10453
+ },
10454
+ {
10455
+ "name": "failImage",
10456
+ "signature": "failImage(): Promise<void>",
10457
+ "params": [],
10458
+ "returns": "Promise<void>",
10459
+ "doc": "Fires the image's `error` event, as a browser does when it fails. Throws without one."
10460
+ },
10461
+ {
10462
+ "name": "isSelectable",
10463
+ "signature": "isSelectable(): Promise<boolean>",
10464
+ "params": [],
10465
+ "returns": "Promise<boolean>",
10466
+ "doc": "Whether the card has a select button (`selectable`)."
10467
+ },
10468
+ {
10469
+ "name": "isSelected",
10470
+ "signature": "isSelected(): Promise<boolean>",
10471
+ "params": [],
10472
+ "returns": "Promise<boolean>",
10473
+ "doc": "Whether the card is selected (its select button is pressed)."
10474
+ },
10475
+ {
10476
+ "name": "toggleSelected",
10477
+ "signature": "toggleSelected(): Promise<void>",
10478
+ "params": [],
10479
+ "returns": "Promise<void>",
10480
+ "doc": "Clicks the select button, toggling the selection. Throws for a card that is not selectable."
10481
+ }
10482
+ ],
10483
+ "slots": [],
10484
+ "references": [],
10485
+ "usedBy": [],
10486
+ "since": "0.5.0",
10487
+ "signature": "class BfMediaCardHarness extends ComponentHarness"
10488
+ },
9110
10489
  {
9111
10490
  "name": "BfMenuButtonHarness",
9112
10491
  "slug": "bf-menu-button-harness",
@@ -9547,7 +10926,7 @@
9547
10926
  "entryPoint": "@bitforgehq/ui/testing",
9548
10927
  "file": "testing/harnesses/select.harness.ts",
9549
10928
  "summary": "Test harness for the select: reads its label and options and picks one",
9550
- "description": "Harness for `bf-select`. It works by option label, so a test never needs the native option\nvalues (an object option's native value is its index).",
10929
+ "description": "Harness for `bf-select`, in both modes: the styled list under a mouse (its options render in the\nCDK overlay container while open, found through the field's `aria-controls`) and the native\n`<select>` under a coarse pointer. It also drives the native select with `data-bf-select` that a\nstacked `bf-table` renders as its Sort by select without `provideBfSelect()`. It works by option\nlabel, so a test never needs the option values (an object option's native value is its index).",
9551
10930
  "members": [],
9552
10931
  "methods": [
9553
10932
  {
@@ -9557,6 +10936,13 @@
9557
10936
  "returns": "Promise<string>",
9558
10937
  "doc": "The visible label without the required mark, else the `aria-label`."
9559
10938
  },
10939
+ {
10940
+ "name": "isOpen",
10941
+ "signature": "isOpen(): Promise<boolean>",
10942
+ "params": [],
10943
+ "returns": "Promise<boolean>",
10944
+ "doc": "Whether the styled option list is open (`aria-expanded`). Always false for the native select,\nwhose list belongs to the platform."
10945
+ },
9560
10946
  {
9561
10947
  "name": "getValueLabel",
9562
10948
  "signature": "getValueLabel(): Promise<string>",
@@ -9583,7 +10969,7 @@
9583
10969
  }
9584
10970
  ],
9585
10971
  "returns": "Promise<void>",
9586
- "doc": "Chooses the option with this label, as a user would: the select's `value` becomes that\noption's value. Throws, leaving the value as it is, for an unknown or disabled option and\nwhile the select itself is disabled."
10972
+ "doc": "Chooses the option with this label, as a user would: the select's `value` becomes that\noption's value. Throws, leaving the value as it is, for an unknown or disabled option and\nwhile the select itself is disabled. On a read-only select it changes nothing, in both modes:\nthe styled list does not open, and the native select restores the shown option."
9587
10973
  },
9588
10974
  {
9589
10975
  "name": "isDisabled",
@@ -9625,14 +11011,14 @@
9625
11011
  "signature": "focus(): Promise<void>",
9626
11012
  "params": [],
9627
11013
  "returns": "Promise<void>",
9628
- "doc": "Focuses the native select."
11014
+ "doc": "Focuses the field, or the native select."
9629
11015
  },
9630
11016
  {
9631
11017
  "name": "blur",
9632
11018
  "signature": "blur(): Promise<void>",
9633
11019
  "params": [],
9634
11020
  "returns": "Promise<void>",
9635
- "doc": "Blurs the native select, which marks a bound form field touched."
11021
+ "doc": "Blurs the field, or the native select, which marks a bound form field touched."
9636
11022
  }
9637
11023
  ],
9638
11024
  "slots": [],
@@ -9827,6 +11213,32 @@
9827
11213
  "returns": "Promise<string>",
9828
11214
  "doc": "The text of one cell."
9829
11215
  },
11216
+ {
11217
+ "name": "getCellHarness",
11218
+ "signature": "getCellHarness<T extends ComponentHarness>(row: number, column: string, query: HarnessQuery<T>): Promise<T>",
11219
+ "params": [
11220
+ {
11221
+ "name": "row",
11222
+ "type": "number",
11223
+ "optional": false,
11224
+ "doc": "The row's position, from 0."
11225
+ },
11226
+ {
11227
+ "name": "column",
11228
+ "type": "string",
11229
+ "optional": false,
11230
+ "doc": "The column's header text."
11231
+ },
11232
+ {
11233
+ "name": "query",
11234
+ "type": "HarnessQuery<T>",
11235
+ "optional": false,
11236
+ "doc": "The harness type, or a predicate from its `with()`."
11237
+ }
11238
+ ],
11239
+ "returns": "Promise<T>",
11240
+ "doc": "A harness for a control in one cell, such as a `bf-toggle` of a settings matrix or a\n`bf-select` in a custom cell. Throws for an unknown row or column, or when the cell holds no\nmatching control."
11241
+ },
9830
11242
  {
9831
11243
  "name": "sortBy",
9832
11244
  "signature": "sortBy(column: string): Promise<void>",
@@ -10016,6 +11428,79 @@
10016
11428
  "since": "0.3.1",
10017
11429
  "signature": "class BfTimeInputHarness extends ComponentHarness"
10018
11430
  },
11431
+ {
11432
+ "name": "BfToggleHarness",
11433
+ "slug": "bf-toggle-harness",
11434
+ "kind": "class",
11435
+ "entryPoint": "@bitforgehq/ui/testing",
11436
+ "file": "testing/harnesses/toggle.harness.ts",
11437
+ "summary": "Test harness for the toggle: reads its name and state and switches it",
11438
+ "description": "Harness for `bf-toggle`. Its `label` filter matches the switch's name: the text of the elements\n`ariaLabelledby` names, else `ariaLabel`, else the visible label, so a label-less switch in a\ntable cell or a list row is found the same way.",
11439
+ "members": [],
11440
+ "methods": [
11441
+ {
11442
+ "name": "getLabel",
11443
+ "signature": "getLabel(): Promise<string>",
11444
+ "params": [],
11445
+ "returns": "Promise<string>",
11446
+ "doc": "The switch's name, as the browser computes it: the text of the elements `ariaLabelledby`\nnames, else `ariaLabel`, else the visible label (the `label` text and the default slot)."
11447
+ },
11448
+ {
11449
+ "name": "isChecked",
11450
+ "signature": "isChecked(): Promise<boolean>",
11451
+ "params": [],
11452
+ "returns": "Promise<boolean>",
11453
+ "doc": "Whether the switch is on."
11454
+ },
11455
+ {
11456
+ "name": "isDisabled",
11457
+ "signature": "isDisabled(): Promise<boolean>",
11458
+ "params": [],
11459
+ "returns": "Promise<boolean>",
11460
+ "doc": "Whether the switch is disabled."
11461
+ },
11462
+ {
11463
+ "name": "isReadonly",
11464
+ "signature": "isReadonly(): Promise<boolean>",
11465
+ "params": [],
11466
+ "returns": "Promise<boolean>",
11467
+ "doc": "Whether the switch is read-only (`aria-readonly`): it shows its state but a click does nothing."
11468
+ },
11469
+ {
11470
+ "name": "toggle",
11471
+ "signature": "toggle(): Promise<void>",
11472
+ "params": [],
11473
+ "returns": "Promise<void>",
11474
+ "doc": "Clicks the switch, as a user would, so it turns on or off. Throws while it is disabled (a\nuser's click would do nothing); a read-only switch takes the click and stays as it is."
11475
+ },
11476
+ {
11477
+ "name": "check",
11478
+ "signature": "check(): Promise<void>",
11479
+ "params": [],
11480
+ "returns": "Promise<void>",
11481
+ "doc": "Turns the switch on with a click; an on switch stays on. Throws while it is disabled."
11482
+ },
11483
+ {
11484
+ "name": "uncheck",
11485
+ "signature": "uncheck(): Promise<void>",
11486
+ "params": [],
11487
+ "returns": "Promise<void>",
11488
+ "doc": "Turns the switch off with a click; an off switch stays off. Throws while it is disabled."
11489
+ },
11490
+ {
11491
+ "name": "getErrorText",
11492
+ "signature": "getErrorText(): Promise<string>",
11493
+ "params": [],
11494
+ "returns": "Promise<string>",
11495
+ "doc": "The error text under the switch."
11496
+ }
11497
+ ],
11498
+ "slots": [],
11499
+ "references": [],
11500
+ "usedBy": [],
11501
+ "since": "0.4.0",
11502
+ "signature": "class BfToggleHarness extends ComponentHarness"
11503
+ },
10019
11504
  {
10020
11505
  "name": "BfTooltipHarness",
10021
11506
  "slug": "bf-tooltip-harness",