@bitforgehq/ui 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +4 -4
  3. package/ai/MANIFEST.index.json +36 -0
  4. package/ai/MANIFEST.json +436 -24
  5. package/ai/REFERENCE.index.json +35 -0
  6. package/ai/REFERENCE.json +202 -10
  7. package/ai/UI_GUIDE.md +25 -4
  8. package/ai/components/app-frame.md +14 -7
  9. package/ai/components/badge.md +39 -2
  10. package/ai/components/header.md +9 -0
  11. package/ai/components/list-item.md +105 -9
  12. package/ai/components/step.md +112 -0
  13. package/ai/components/steps.md +124 -0
  14. package/ai/components/table.md +119 -5
  15. package/ai/components/timeline-event.md +144 -0
  16. package/ai/components/timeline.md +201 -0
  17. package/ai/components/toggle.md +11 -1
  18. package/ai/reference/bf-action-directive.md +3 -1
  19. package/ai/reference/bf-badge-emphasis.md +27 -0
  20. package/ai/reference/bf-labels.md +2 -0
  21. package/ai/reference/bf-select-harness.md +4 -0
  22. package/ai/reference/bf-step-heading-level.md +28 -0
  23. package/ai/reference/bf-table-align.md +1 -1
  24. package/ai/reference/bf-table-column-align.md +33 -0
  25. package/ai/reference/bf-table-column.md +7 -7
  26. package/ai/reference/bf-table-harness.md +18 -0
  27. package/ai/reference/bf-timeline-tone.md +31 -0
  28. package/ai/reference/bf-toggle-harness.md +55 -0
  29. package/ai/reference/provide-bf-labels.md +2 -2
  30. package/dark-ink.css +124 -0
  31. package/fesm2022/bitforgehq-ui-mobile.mjs +13 -3
  32. package/fesm2022/bitforgehq-ui-mobile.mjs.map +1 -1
  33. package/fesm2022/bitforgehq-ui-testing.mjs +55 -2
  34. package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
  35. package/fesm2022/bitforgehq-ui.mjs +714 -46
  36. package/fesm2022/bitforgehq-ui.mjs.map +1 -1
  37. package/llms-full.txt +1128 -26
  38. package/llms.txt +9 -0
  39. package/package.json +2 -1
  40. package/theme.css +37 -0
  41. package/types/bitforgehq-ui-testing.d.ts +90 -1
  42. package/types/bitforgehq-ui.d.ts +306 -18
@@ -241,6 +241,11 @@ interface BfLabels {
241
241
  * @default 'Sort by'
242
242
  */
243
243
  readonly tableSortBy: string;
244
+ /**
245
+ * A stacked bf-table's first sort option: rows in the order given, no column sorted.
246
+ * @default 'Not sorted'
247
+ */
248
+ readonly tableSortNone: string;
244
249
  /**
245
250
  * A stacked bf-table's sort option for a column in ascending order.
246
251
  * @default (column) => `${column}, ascending`
@@ -507,6 +512,11 @@ interface BfLabels {
507
512
  * @default 'The data could not be loaded'
508
513
  */
509
514
  readonly chartError: string;
515
+ /**
516
+ * bf-list-item's visually hidden state text before the title of an `unread` row.
517
+ * @default 'Unread'
518
+ */
519
+ readonly listItemUnread: string;
510
520
  /** Default error text per validator kind (see `BfValidationMessages`). */
511
521
  readonly validation: BfValidationMessages;
512
522
  }
@@ -538,7 +548,7 @@ export declare const BF_LABELS: InjectionToken<BfLabels>;
538
548
  * out or set to `undefined` keeps the parent's string. In `ApplicationConfig.providers` it covers
539
549
  * every string. In a component's `providers` it covers that sub-tree's widgets and form controls
540
550
  * (`loading`, `dismiss`, `tabBar`, `tabBadge`, `back`, `refreshing`, `tableSelectAll`, `tableSortBy`,
541
- * `tableSortAscending`, `tableSortDescending`, `theme`, `themeSystem`, `themeLight`, `themeDark`,
551
+ * `tableSortNone`, `tableSortAscending`, `tableSortDescending`, `theme`, `themeSystem`, `themeLight`, `themeDark`,
542
552
  * `breadcrumb`, `breadcrumbExpand`, `navigation`, `navBadge`, `sidebarCollapse`, `sidebarExpand`,
543
553
  * `skipToContent`, `pagination`, `previousPage`, `nextPage`, `pageOf`, `goToPage`, `tabGroup`,
544
554
  * `calendarPreviousMonth`, `calendarNextMonth`, `calendarChooseMonth`, `calendarChooseYear`,
@@ -547,7 +557,7 @@ export declare const BF_LABELS: InjectionToken<BfLabels>;
547
557
  * `dateInputUnavailable`, `timeInputHour`, `timeInputMinute`, `timeInputSecond`,
548
558
  * `timeInputDayPeriod`, `timeInputOpenList`, `timeInputInvalid`, `timeInputMin`, `timeInputMax`,
549
559
  * `chart`, `chartLegend`, `chartValues`, `chartShowData`, `chartHideData`, `chartCategory`,
550
- * `chartValue`, `chartEmpty`, `chartError`, `validation`); the overlay services (`ok`, `cancel`,
560
+ * `chartValue`, `chartEmpty`, `chartError`, `listItemUnread`, `validation`); the overlay services (`ok`, `cancel`,
551
561
  * `actions`, `sheet`, `modal`, `close`, `expand`, `collapse`, `sheetPosition`, `dialog`,
552
562
  * `notifications`) are root singletons and pick it up only when the caller passes its injector:
553
563
  * `open(…, { injector: inject(Injector) })`.
@@ -1007,11 +1017,20 @@ type BfBadgeVariant = 'neutral' | 'primary' | 'success' | 'warning' | 'danger';
1007
1017
  * @since 0.3.1
1008
1018
  */
1009
1019
  type BfBadgeAppearance = BfBadgeVariant | 'info';
1020
+ /**
1021
+ * How loud a `bf-badge` is: `soft`, a pale tint with tinted text (the default), or `strong`, a
1022
+ * solid fill with contrasting text for the one state that must stand out, such as "Critical".
1023
+ *
1024
+ * @summary The two badge emphases, the soft tint or the solid strong fill
1025
+ * @since 0.4.0
1026
+ */
1027
+ type BfBadgeEmphasis = 'soft' | 'strong';
1010
1028
  /**
1011
1029
  * Status label ("On track", "At risk") or, with `count`, a compact numeric pill for unread counts.
1012
1030
  *
1013
1031
  * @example
1014
1032
  * <bf-badge variant="warning">At risk</bf-badge>
1033
+ * <bf-badge variant="danger" emphasis="strong">Critical</bf-badge>
1015
1034
  * <bf-badge [count]="unread()" countLabel="unread messages" />
1016
1035
  * @summary Small status label in semantic tones, or a compact numeric pill for counts
1017
1036
  * @category Data display
@@ -1019,9 +1038,12 @@ type BfBadgeAppearance = BfBadgeVariant | 'info';
1019
1038
  * @slot default The badge text, shown when no `count` is set.
1020
1039
  */
1021
1040
  export declare class BfBadgeComponent {
1022
- /** Tint for the label style: neutral, primary, success, warning, danger or info. Ignored when
1023
- * `count` is set. */
1041
+ /** Tint for the label style: neutral, primary, success, warning, danger or info. Ignored by a
1042
+ * soft count pill; a strong one takes its fill from it. */
1024
1043
  readonly variant: import("@angular/core").InputSignal<BfBadgeAppearance>;
1044
+ /** `soft` (a pale tint, the default) or `strong` (a solid fill with contrasting text, also for
1045
+ * the count pill). */
1046
+ readonly emphasis: import("@angular/core").InputSignal<BfBadgeEmphasis>;
1025
1047
  /** Switches to the count pill; values above 99 render as "99+". */
1026
1048
  readonly count: import("@angular/core").InputSignal<number | undefined>;
1027
1049
  /** What the count counts ("unread messages"), read by assistive tech after the number ("99+
@@ -1029,7 +1051,7 @@ export declare class BfBadgeComponent {
1029
1051
  readonly countLabel: import("@angular/core").InputSignal<string>;
1030
1052
  readonly classes: import("@angular/core").Signal<string>;
1031
1053
  readonly countText: import("@angular/core").Signal<string | null>;
1032
- readonly countClasses = "inline-flex h-box min-w-box items-center justify-center rounded-control bg-primary px-1.75 text-micro font-bold leading-none text-on-primary";
1054
+ readonly countClasses: import("@angular/core").Signal<string>;
1033
1055
  static ɵfac: i0.ɵɵFactoryDeclaration<BfBadgeComponent, never>;
1034
1056
  static ɵcmp: i0.ɵɵComponentDeclaration<BfBadgeComponent, "bf-badge", never, {
1035
1057
  "variant": {
@@ -1037,6 +1059,11 @@ export declare class BfBadgeComponent {
1037
1059
  "required": false;
1038
1060
  "isSignal": true;
1039
1061
  };
1062
+ "emphasis": {
1063
+ "alias": "emphasis";
1064
+ "required": false;
1065
+ "isSignal": true;
1066
+ };
1040
1067
  "count": {
1041
1068
  "alias": "count";
1042
1069
  "required": false;
@@ -3168,12 +3195,18 @@ interface BfActionHost {
3168
3195
  registerAction(): () => void;
3169
3196
  /** Whether the surface's action has keyboard focus (`:focus-visible`), for the focus ring. */
3170
3197
  setActionFocusVisible(visible: boolean): void;
3198
+ /**
3199
+ * The id of an element whose text starts the action's accessible name (a list row's visually
3200
+ * hidden "Unread"), or `null`; the action then names itself `aria-labelledby="<id> <own id>"`.
3201
+ */
3202
+ readonly actionLabelPrefix?: Signal<string | null>;
3171
3203
  }
3172
3204
  declare const BF_ACTION_HOST: InjectionToken<BfActionHost>;
3173
3205
  /**
3174
3206
  * One row of a list: leading slot (avatar, icon tile), title and subtitle, trailing slot
3175
3207
  * (time, toggle, badge) and an optional chevron for rows that navigate. A navigation row puts a
3176
3208
  * `bfAction` link in the `title` slot, so the row stays a list item and the link covers it.
3209
+ * `unread` marks a row not yet opened with a dot and a bolder title.
3177
3210
  *
3178
3211
  * @example
3179
3212
  * <bf-list-item subtitle="lena@studio.ch" chevron>
@@ -3205,13 +3238,26 @@ export declare class BfListItemComponent implements BfActionHost {
3205
3238
  * default they wrap, so nothing is lost at large text sizes.
3206
3239
  */
3207
3240
  readonly truncate: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
3241
+ /** Mark the row as not yet opened: a dot at the inline start, a bolder title and a visually
3242
+ * hidden state (the `listItemUnread` label) read before the title. */
3243
+ readonly unread: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
3208
3244
  /** Emitted when an interactive row is activated. */
3209
3245
  readonly clicked: import("@angular/core").OutputEmitterRef<Event>;
3210
3246
  /** `listitem` inside a `bf-list`, else no role. */
3211
3247
  protected readonly role: string | null;
3248
+ protected readonly labels: import("@bitforgehq/ui").BfLabels;
3249
+ protected readonly unreadDot = "absolute -start-2.5 mt-[7px] size-1.5 rounded-full bg-primary forced-colors:bg-[CanvasText]";
3212
3250
  private readonly actions;
3213
3251
  private readonly actionFocusVisible;
3214
3252
  private readonly actionState;
3253
+ protected readonly hasAction: import("@angular/core").Signal<boolean>;
3254
+ private unreadIdValue;
3255
+ /** The id of the unread state text, while `unread` is set. */
3256
+ protected readonly unreadId: import("@angular/core").Signal<string | null>;
3257
+ /** @internal The unread state starts the name of the row's `bfAction`. */
3258
+ readonly actionLabelPrefix: import("@angular/core").Signal<string | null>;
3259
+ /** The title weight: bolder on an unread row. */
3260
+ protected readonly titleWeight: import("@angular/core").Signal<"font-extrabold" | "font-bold">;
3215
3261
  /** Wrap or truncate classes of the title, the title slot and the subtitle. */
3216
3262
  protected readonly textClasses: import("@angular/core").Signal<string>;
3217
3263
  readonly classes: import("@angular/core").Signal<string>;
@@ -3251,6 +3297,11 @@ export declare class BfListItemComponent implements BfActionHost {
3251
3297
  "required": false;
3252
3298
  "isSignal": true;
3253
3299
  };
3300
+ "unread": {
3301
+ "alias": "unread";
3302
+ "required": false;
3303
+ "isSignal": true;
3304
+ };
3254
3305
  }, {
3255
3306
  "clicked": "clicked";
3256
3307
  }, never, ["[bfSlot=leading]", "[bfSlot=title]", "*", "[bfSlot=trailing]"], true, never>;
@@ -3977,7 +4028,9 @@ export declare class BfTabBarComponent implements BfTabBarHost {
3977
4028
  * with the nearest card or row, which then draws the pointer, the hover and, while the action has
3978
4029
  * keyboard focus, the focus ring; a card is never lit by the actions of rows nested in it. Give
3979
4030
  * secondary controls inside the surface `class="relative z-1"` so they stay clickable above the
3980
- * stretched area.
4031
+ * stretched area. When the surface marks a state that belongs in the name (an `unread` list
4032
+ * row), the directive names the element `aria-labelledby="<state id> <own id>"`, so the link reads
4033
+ * "Unread, Account", and restores the element's own `aria-labelledby` when the state goes.
3981
4034
  *
3982
4035
  * @example
3983
4036
  * <bf-card>
@@ -4338,6 +4391,15 @@ export declare class BfTableCellDirective<T = unknown> {
4338
4391
  * @since 0.3.1
4339
4392
  */
4340
4393
  type BfTableAlign = 'start' | 'end';
4394
+ /**
4395
+ * Where a `bf-table` column lines up its header and cells: a `BfTableAlign`, or `center` for a
4396
+ * column of controls such as the toggles of a settings matrix. A new type, so `Record`s over the
4397
+ * released `BfTableAlign` keep compiling.
4398
+ *
4399
+ * @summary The inline alignment of a table column: start, end, or centred for controls
4400
+ * @since 0.4.0
4401
+ */
4402
+ type BfTableColumnAlign = BfTableAlign | 'center';
4341
4403
  /**
4342
4404
  * The direction of a sorted `bf-table` column, as `aria-sort` names it.
4343
4405
  *
@@ -4371,10 +4433,11 @@ interface BfTableColumn {
4371
4433
  */
4372
4434
  sortable?: boolean;
4373
4435
  /**
4374
- * The inline alignment of the header and cells; `end` also sets tabular figures.
4436
+ * The inline alignment of the header and cells; `end` also sets tabular figures, `center`
4437
+ * centres a cell's control (a toggle, a checkbox) in the column.
4375
4438
  * @default 'start'
4376
4439
  */
4377
- align?: BfTableAlign;
4440
+ align?: BfTableColumnAlign;
4378
4441
  }
4379
4442
  /**
4380
4443
  * The column a `bf-table` is sorted by and the direction; the consumer sorts the rows.
@@ -4467,10 +4530,11 @@ export declare class BfTableComponent<T = unknown> {
4467
4530
  /** Whether the table can stack its rows (any `stack` but `never`); it then sets explicit
4468
4531
  * table roles, because some browsers drop a table's semantics once its display changes. */
4469
4532
  protected readonly stacks: import("@angular/core").Signal<boolean>;
4470
- /** The Sort by select's options: each sortable column ascending and descending. */
4533
+ /** The Sort by select's options: Not sorted (`''`), then each sortable column ascending and
4534
+ * descending; none without a sortable column. */
4471
4535
  protected readonly sortOptions: import("@angular/core").Signal<BfSelectOption<string>[]>;
4472
- /** The Sort by select's value: the option of `sort`, `null` while unsorted. */
4473
- protected readonly sortValue: import("@angular/core").Signal<string | null>;
4536
+ /** The Sort by select's value: the option of `sort`, Not sorted while `sort` is null. */
4537
+ protected readonly sortValue: import("@angular/core").Signal<string>;
4474
4538
  protected readonly hostClasses: import("@angular/core").Signal<string>;
4475
4539
  protected readonly stackBarClasses: import("@angular/core").Signal<string>;
4476
4540
  protected readonly tableClasses: import("@angular/core").Signal<string>;
@@ -4526,7 +4590,8 @@ export declare class BfTableComponent<T = unknown> {
4526
4590
  */
4527
4591
  sortBy(key: string): void;
4528
4592
  /**
4529
- * Sorts by a Sort by option (`<key>:<direction>`) of a stacked table.
4593
+ * Sorts by a Sort by option (`<key>:<direction>`) of a stacked table; Not sorted sets `sort` to
4594
+ * null.
4530
4595
  * @internal
4531
4596
  */
4532
4597
  sortFromOption(value: string): void;
@@ -4783,6 +4848,132 @@ export declare class BfStatComponent {
4783
4848
  };
4784
4849
  }, {}, never, ["[bfSlot=icon]", "*"], true, never>;
4785
4850
  }
4851
+ /** The default format of an event's time: a medium date and a short time (12 Oct 2026, 14:30). */
4852
+ declare const TIMELINE_TIME_FORMAT: Intl.DateTimeFormatOptions;
4853
+ /** What a `bf-timeline-event` reads from its `bf-timeline`. */
4854
+ interface BfTimelineHost {
4855
+ /** The `Intl.DateTimeFormat` options of the events' times. */
4856
+ readonly timeFormat: Signal<Intl.DateTimeFormatOptions>;
4857
+ /** The locale of the events' times, `''` for the app's `LOCALE_ID`. */
4858
+ readonly locale: Signal<string>;
4859
+ }
4860
+ /**
4861
+ * Provided by `bf-timeline` so each `bf-timeline-event` claims `role="listitem"` and formats its
4862
+ * time with the timeline's options, without `timeline-event.component.ts` importing
4863
+ * `timeline.component.ts`.
4864
+ */
4865
+ declare const BF_TIMELINE: InjectionToken<BfTimelineHost>;
4866
+ /**
4867
+ * A dated history of events, newest first or oldest first as the consumer orders them: who did
4868
+ * what and when, each event a `bf-timeline-event` with a marker on a vertical line.
4869
+ *
4870
+ * @example
4871
+ * <bf-timeline label="History">
4872
+ * <bf-timeline-event actor="Lena Meier" time="2026-10-28T14:30:00Z" tone="success">
4873
+ * Marked the finding as fixed
4874
+ * </bf-timeline-event>
4875
+ * </bf-timeline>
4876
+ * @summary Dated list of events with who did what and when, on a vertical line
4877
+ * @category Data display
4878
+ * @since 0.4.0
4879
+ * @slot default The events, each a `bf-timeline-event`, in the order to show them.
4880
+ */
4881
+ export declare class BfTimelineComponent implements BfTimelineHost {
4882
+ /** The list's accessible name, such as "History"; empty leaves the list unnamed (a visible
4883
+ * heading above it already names the section). */
4884
+ readonly label: import("@angular/core").InputSignal<string>;
4885
+ /** `Intl.DateTimeFormat` options of every event's time; by default a medium date and a short
4886
+ * time (`dateStyle: 'medium'`, `timeStyle: 'short'`). */
4887
+ readonly timeFormat: import("@angular/core").InputSignal<Intl.DateTimeFormatOptions>;
4888
+ /** BCP 47 locale of the times, such as `de-CH`; empty follows the app's `LOCALE_ID`. */
4889
+ readonly locale: import("@angular/core").InputSignal<string>;
4890
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfTimelineComponent, never>;
4891
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfTimelineComponent, "bf-timeline", never, {
4892
+ "label": {
4893
+ "alias": "label";
4894
+ "required": false;
4895
+ "isSignal": true;
4896
+ };
4897
+ "timeFormat": {
4898
+ "alias": "timeFormat";
4899
+ "required": false;
4900
+ "isSignal": true;
4901
+ };
4902
+ "locale": {
4903
+ "alias": "locale";
4904
+ "required": false;
4905
+ "isSignal": true;
4906
+ };
4907
+ }, {}, never, ["*"], true, never>;
4908
+ }
4909
+ /**
4910
+ * The colour of a `bf-timeline-event`'s marker: `neutral` (the default), `primary`, or a status
4911
+ * (`success`, `warning`, `danger`, `info`), such as danger for a failed CI run.
4912
+ *
4913
+ * @summary The marker colour of a timeline event, neutral, primary or a status
4914
+ * @since 0.4.0
4915
+ */
4916
+ type BfTimelineTone = 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
4917
+ /**
4918
+ * One event of a `bf-timeline`: a marker coloured by `tone`, the event text (the default slot,
4919
+ * which may hold links), then who did it (`actor`) and when (`time`, in a `time` element).
4920
+ *
4921
+ * @example
4922
+ * <bf-timeline-event actor="CI" time="2026-10-28T09:12:00Z" tone="danger">
4923
+ * CI failed on <a href="/pulls/123">PR #123</a>
4924
+ * </bf-timeline-event>
4925
+ * @summary One timeline event with a coloured marker, its text, actor and time
4926
+ * @category Data display
4927
+ * @since 0.4.0
4928
+ * @slot default The event text; links in it take the link style.
4929
+ * @slot end Content at the inline end on a wide timeline and below the text on a narrow one, such as a button.
4930
+ */
4931
+ export declare class BfTimelineEventComponent {
4932
+ /** Who did it, such as a person or a bot; empty for a system event. */
4933
+ readonly actor: import("@angular/core").InputSignal<string>;
4934
+ /** When it happened: a Date or an ISO 8601 string; empty or invalid shows no time. */
4935
+ readonly time: import("@angular/core").InputSignal<string | Date | null>;
4936
+ /** Shown in place of the formatted time, such as "vor 2 Std."; the `time` element's `datetime`
4937
+ * keeps the exact value. */
4938
+ readonly timeText: import("@angular/core").InputSignal<string>;
4939
+ /** The marker's colour. */
4940
+ readonly tone: import("@angular/core").InputSignal<BfTimelineTone>;
4941
+ private readonly timeline;
4942
+ private readonly appLocale;
4943
+ /** `listitem` inside a `bf-timeline`, else no role. */
4944
+ protected readonly role: string | null;
4945
+ private readonly date;
4946
+ /** The `time` element's machine value: the ISO string as given, a Date's ISO string, else null. */
4947
+ protected readonly datetime: import("@angular/core").Signal<string | null>;
4948
+ /** The visible time: `timeText`, else the date formatted with the timeline's options. */
4949
+ protected readonly timeLabel: import("@angular/core").Signal<string>;
4950
+ protected readonly markerClasses: string;
4951
+ protected readonly textClasses: string;
4952
+ readonly dotClasses: import("@angular/core").Signal<string>;
4953
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfTimelineEventComponent, never>;
4954
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfTimelineEventComponent, "bf-timeline-event", never, {
4955
+ "actor": {
4956
+ "alias": "actor";
4957
+ "required": false;
4958
+ "isSignal": true;
4959
+ };
4960
+ "time": {
4961
+ "alias": "time";
4962
+ "required": false;
4963
+ "isSignal": true;
4964
+ };
4965
+ "timeText": {
4966
+ "alias": "timeText";
4967
+ "required": false;
4968
+ "isSignal": true;
4969
+ };
4970
+ "tone": {
4971
+ "alias": "tone";
4972
+ "required": false;
4973
+ "isSignal": true;
4974
+ };
4975
+ }, {}, never, ["*", "[bfSlot=end]"], true, never>;
4976
+ }
4786
4977
  /**
4787
4978
  * What a `li[bfBreadcrumbItem]` reads from its enclosing `bf-breadcrumb`, provided through an
4788
4979
  * injection token so `breadcrumb.component.ts` and `breadcrumb-item.component.ts` never import each
@@ -5108,22 +5299,23 @@ type BfAppFrameBreakpoint = 'md' | 'lg';
5108
5299
  type BfAppFrameContentWidth = 'md' | 'lg' | 'xl' | 'full';
5109
5300
  /**
5110
5301
  * The frame of a desktop web app: a skip link, a sticky full-height sidebar column from the
5111
- * breakpoint up, a header bar with the brand, the narrow-screen menu and actions below it, and
5302
+ * breakpoint up, a header bar with the narrow-screen menu, the brand and actions below it, and
5112
5303
  * the `main` landmark with a content column of a set maximum width.
5113
5304
  *
5114
5305
  * @example
5115
5306
  * <bf-app-frame>
5116
5307
  * <bf-sidebar bfSlot="sidebar" label="Main">…</bf-sidebar>
5117
- * <span bfSlot="brand" class="text-heading">Atlas</span>
5118
5308
  * <bf-menu-button bfSlot="menu" [menu]="navMenu">Sections</bf-menu-button>
5309
+ * <span bfSlot="brand" class="text-heading">Atlas</span>
5119
5310
  * <router-outlet />
5120
5311
  * </bf-app-frame>
5121
5312
  * @summary Desktop app frame with skip link, sticky sidebar, narrow header and main content
5122
5313
  * @category Navigation
5123
5314
  * @since 0.3.2
5124
5315
  * @slot sidebar The `bf-sidebar`, shown from the breakpoint up; it fills the column's height.
5125
- * @slot brand The app's name or logo in the narrow header bar.
5126
- * @slot menu The narrow-screen navigation: a `bf-menu-button` of `a[bfMenuItem]` links.
5316
+ * @slot brand The app's name or logo in the narrow header bar, after the menu.
5317
+ * @slot menu The narrow-screen navigation: a `bf-menu-button` of `a[bfMenuItem]` links, at the
5318
+ * header bar's inline start.
5127
5319
  * @slot actions End actions of the narrow header bar, such as the theme menu.
5128
5320
  * @slot default The page: what the router shows, inside the `main` landmark.
5129
5321
  */
@@ -5168,7 +5360,7 @@ export declare class BfAppFrameComponent {
5168
5360
  "required": false;
5169
5361
  "isSignal": true;
5170
5362
  };
5171
- }, {}, never, ["[bfSlot=sidebar]", "[bfSlot=brand]", "[bfSlot=menu]", "[bfSlot=actions]", "*"], true, never>;
5363
+ }, {}, never, ["[bfSlot=sidebar]", "[bfSlot=menu]", "[bfSlot=brand]", "[bfSlot=actions]", "*"], true, never>;
5172
5364
  }
5173
5365
  /**
5174
5366
  * The shape of a `bf-skeleton`: text lines, a rectangle (an image, a chart, a field) or a circle
@@ -5726,6 +5918,102 @@ export declare class BfCalendarComponent implements FormValueControl<string | nu
5726
5918
  "touch": "touch";
5727
5919
  }, never, never, true, never>;
5728
5920
  }
5921
+ /**
5922
+ * Provided by `bf-steps` so each `bf-step` knows its number and may claim `role="listitem"`,
5923
+ * without `step.component.ts` importing `steps.component.ts`.
5924
+ */
5925
+ interface BfStepsHost {
5926
+ /** The number of the first step. */
5927
+ readonly start: Signal<number>;
5928
+ /** How many steps the list holds. */
5929
+ readonly count: Signal<number>;
5930
+ /** The zero-based position of a step among the list's steps, or -1. */
5931
+ indexOf(step: object): number;
5932
+ }
5933
+ declare const BF_STEPS: InjectionToken<BfStepsHost>;
5934
+ /**
5935
+ * Numbered instructions a user follows in order, such as setting up an app on a phone: an
5936
+ * ordered list of `bf-step` items, each with a numbered marker joined to the next by a line.
5937
+ *
5938
+ * @example
5939
+ * <bf-steps>
5940
+ * <bf-step title="Install the app">Download it from the App Store or Google Play.</bf-step>
5941
+ * <bf-step title="Sign in">Use your work email address.</bf-step>
5942
+ * <bf-step title="Turn on notifications">Allow them when the app asks.</bf-step>
5943
+ * </bf-steps>
5944
+ * @summary Numbered instruction steps a user follows in order, with joined markers
5945
+ * @category Data display
5946
+ * @since 0.4.0
5947
+ * @slot default The steps, each a `bf-step`.
5948
+ */
5949
+ export declare class BfStepsComponent implements BfStepsHost {
5950
+ /** The number of the first step, for a list continued from an earlier one. */
5951
+ readonly start: import("@angular/core").InputSignalWithTransform<number, unknown>;
5952
+ private readonly steps;
5953
+ /** @internal How many steps the list holds. */
5954
+ readonly count: import("@angular/core").Signal<number>;
5955
+ /** @internal The zero-based position of a step, read by the step for its number. */
5956
+ indexOf(step: object): number;
5957
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfStepsComponent, never>;
5958
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfStepsComponent, "bf-steps", never, {
5959
+ "start": {
5960
+ "alias": "start";
5961
+ "required": false;
5962
+ "isSignal": true;
5963
+ };
5964
+ }, {}, ["steps"], ["*"], true, never>;
5965
+ }
5966
+ /**
5967
+ * The heading level of a `bf-step` title, for a guide whose steps hold enough content (screenshots,
5968
+ * code) that a screen-reader user moves between them by heading.
5969
+ *
5970
+ * @summary The heading level a step title can take, two, three or four
5971
+ * @since 0.4.0
5972
+ */
5973
+ type BfStepHeadingLevel = 2 | 3 | 4;
5974
+ /**
5975
+ * One step of a `bf-steps` list: a numbered marker, a short instruction as its title and the
5976
+ * step's details in the content.
5977
+ *
5978
+ * @example
5979
+ * <bf-steps>
5980
+ * <bf-step title="Install the app">Download it from the App Store or Google Play.</bf-step>
5981
+ * <bf-step title="Sign in">Use your work email address.</bf-step>
5982
+ * </bf-steps>
5983
+ * @summary One numbered step of an instruction list, with a title and its details
5984
+ * @category Data display
5985
+ * @since 0.4.0
5986
+ * @slot default The step's details: text, a code snippet, an image or a button.
5987
+ */
5988
+ export declare class BfStepComponent {
5989
+ private readonly steps;
5990
+ /** The step's short instruction ("Install the app"), shown next to the number. */
5991
+ readonly title: import("@angular/core").InputSignal<string>;
5992
+ /** Renders the title as a heading of this level instead of text; leave it off for short steps. */
5993
+ readonly headingLevel: import("@angular/core").InputSignal<BfStepHeadingLevel | undefined>;
5994
+ /** `listitem` inside a `bf-steps`, else no role. */
5995
+ protected readonly role: string | null;
5996
+ protected readonly markerClasses = "flex size-6 shrink-0 items-center justify-center rounded-full bg-primary-soft text-label-sm font-bold text-primary-strong forced-colors:outline forced-colors:outline-[CanvasText]";
5997
+ protected readonly lineClasses = "my-1 w-0 flex-1 border-s border-border group-last/bf-step:hidden";
5998
+ protected readonly titleClasses = "pt-0.5 text-label font-bold text-text wrap-anywhere";
5999
+ /** The step's number: the list's `start` plus its position. */
6000
+ protected readonly number: import("@angular/core").Signal<number>;
6001
+ protected readonly positionInSet: import("@angular/core").Signal<number | null>;
6002
+ protected readonly setSize: import("@angular/core").Signal<number | null>;
6003
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfStepComponent, never>;
6004
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfStepComponent, "bf-step", never, {
6005
+ "title": {
6006
+ "alias": "title";
6007
+ "required": false;
6008
+ "isSignal": true;
6009
+ };
6010
+ "headingLevel": {
6011
+ "alias": "headingLevel";
6012
+ "required": false;
6013
+ "isSignal": true;
6014
+ };
6015
+ }, {}, never, ["*"], true, never>;
6016
+ }
5729
6017
  /** An error as a field reads it: its kind and optional message; limit fields (`minLength`,
5730
6018
  * `context.requiredLength`, …) are read through type guards by `bfValidationMessage`. */
5731
6019
  type FieldErrorLike = Pick<ValidationError, 'kind' | 'message'>;
@@ -5844,4 +6132,4 @@ declare const BF_NAV: InjectionToken<BfNavHost>;
5844
6132
  declare function resetBfDocument(document: Document): void;
5845
6133
  /** Runs `resetBfDocument()` when the environment injector that holds it is destroyed. Internal. */
5846
6134
  declare function provideBfDocumentReset(): EnvironmentProviders;
5847
- export { type BfAlertVariant, type BfAppFrameBreakpoint, type BfAppFrameContentWidth, type BfAutocapitalize, type BfAvatarSize, type BfAvatarVariant, type BfBadgeAppearance, type BfBadgeVariant, type BfButtonAppearance, type BfButtonSize, type BfButtonType, type BfButtonVariant, type BfCalendarDisabledDate, type BfCalendarWeekday, type BfCardPadding, type BfCardVariant, type BfChipGroupMode, type BfChipVariant, type BfColorScheme, type BfCompareWith, type BfDefaults, type BfDefaultsOptions, type BfDescriptionListLayout, type BfEmptyStateHeading, type BfEmptyStateHeadingLevel, type BfEnterKeyHint, type BfFieldControlState, type BfFieldSize, type BfIconButtonVariant, type BfInputAutocapitalize, type BfInputEnterKeyHint, type BfInputInputMode, type BfInputMode, type BfInputType, type BfLabels, type BfLabelsOverrides, type BfPageHeaderHeadingLevel, type BfProgressSize, type BfProgressTone, type BfRadioGroupOrientation, type BfRadioOption, type BfSegmentOption, type BfSegmentedSize, type BfSelectOption, type BfSize, type BfSkeletonShape, type BfSpinnerSize, type BfStatAppearance, type BfStatTrend, type BfStatTrendIntent, type BfStatVariant, type BfTabBarController, type BfTabBarHost, type BfTabLinks, type BfTableAlign, type BfTableCellContext, type BfTableColumn, type BfTableRowKey, type BfTableSort, type BfTableSortDirection, type BfTableStack, type BfToggleLabelPosition, type BfValidationMessages, BUTTON_CLASSES as ɵBF_BUTTON_CLASSES, ICON_BUTTON_CLASSES as ɵBF_ICON_BUTTON_CLASSES, BF_NAV as ɵBF_NAV, type BfNavHost as ɵBfNavHost, FIELD_BOX as ɵFIELD_BOX, FIELD_ICON_END as ɵFIELD_ICON_END, FIELD_ICON_START as ɵFIELD_ICON_START, FIELD_PADDING_END as ɵFIELD_PADDING_END, FIELD_PADDING_START as ɵFIELD_PADDING_START, PILL_HIT as ɵPILL_HIT, compareIso as ɵcompareIso, createMemoryColorSchemeStorage as ɵcreateMemoryColorSchemeStorage, daysInMonth as ɵdaysInMonth, fieldDescribedBy as ɵfieldDescribedBy, fieldErrorMessageId as ɵfieldErrorMessageId, fieldErrorText as ɵfieldErrorText, fieldShowsError as ɵfieldShowsError, formatIsoDate as ɵformatIsoDate, localIsoDate as ɵlocalIsoDate, parseIsoDate as ɵparseIsoDate, provideBfDocumentReset as ɵprovideBfDocumentReset, uniqueId as ɵuniqueId, validIsoDate as ɵvalidIsoDate };
6135
+ export { type BfAlertVariant, type BfAppFrameBreakpoint, type BfAppFrameContentWidth, type BfAutocapitalize, type BfAvatarSize, type BfAvatarVariant, type BfBadgeAppearance, type BfBadgeEmphasis, type BfBadgeVariant, type BfButtonAppearance, type BfButtonSize, type BfButtonType, type BfButtonVariant, type BfCalendarDisabledDate, type BfCalendarWeekday, type BfCardPadding, type BfCardVariant, type BfChipGroupMode, type BfChipVariant, type BfColorScheme, type BfCompareWith, type BfDefaults, type BfDefaultsOptions, type BfDescriptionListLayout, type BfEmptyStateHeading, type BfEmptyStateHeadingLevel, type BfEnterKeyHint, type BfFieldControlState, type BfFieldSize, type BfIconButtonVariant, type BfInputAutocapitalize, type BfInputEnterKeyHint, type BfInputInputMode, type BfInputMode, type BfInputType, type BfLabels, type BfLabelsOverrides, type BfPageHeaderHeadingLevel, type BfProgressSize, type BfProgressTone, type BfRadioGroupOrientation, type BfRadioOption, type BfSegmentOption, type BfSegmentedSize, type BfSelectOption, type BfSize, type BfSkeletonShape, type BfSpinnerSize, type BfStatAppearance, type BfStatTrend, type BfStatTrendIntent, type BfStatVariant, type BfStepHeadingLevel, type BfTabBarController, type BfTabBarHost, type BfTabLinks, type BfTableAlign, type BfTableCellContext, type BfTableColumn, type BfTableColumnAlign, type BfTableRowKey, type BfTableSort, type BfTableSortDirection, type BfTableStack, type BfTimelineTone, type BfToggleLabelPosition, type BfValidationMessages, BUTTON_CLASSES as ɵBF_BUTTON_CLASSES, ICON_BUTTON_CLASSES as ɵBF_ICON_BUTTON_CLASSES, BF_NAV as ɵBF_NAV, type BfNavHost as ɵBfNavHost, FIELD_BOX as ɵFIELD_BOX, FIELD_ICON_END as ɵFIELD_ICON_END, FIELD_ICON_START as ɵFIELD_ICON_START, FIELD_PADDING_END as ɵFIELD_PADDING_END, FIELD_PADDING_START as ɵFIELD_PADDING_START, PILL_HIT as ɵPILL_HIT, compareIso as ɵcompareIso, createMemoryColorSchemeStorage as ɵcreateMemoryColorSchemeStorage, daysInMonth as ɵdaysInMonth, fieldDescribedBy as ɵfieldDescribedBy, fieldErrorMessageId as ɵfieldErrorMessageId, fieldErrorText as ɵfieldErrorText, fieldShowsError as ɵfieldShowsError, formatIsoDate as ɵformatIsoDate, localIsoDate as ɵlocalIsoDate, parseIsoDate as ɵparseIsoDate, provideBfDocumentReset as ɵprovideBfDocumentReset, uniqueId as ɵuniqueId, validIsoDate as ɵvalidIsoDate };