@bitforgehq/ui 0.4.0 → 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.
- package/CHANGELOG.md +303 -0
- package/README.md +12 -12
- package/ai/MANIFEST.index.json +65 -2
- package/ai/MANIFEST.json +2221 -737
- package/ai/REFERENCE.index.json +161 -0
- package/ai/REFERENCE.json +1336 -27
- package/ai/UI_GUIDE.md +61 -20
- package/ai/components/app-frame.md +1 -1
- package/ai/components/chat-composer.md +357 -0
- package/ai/components/chat-message.md +251 -0
- package/ai/components/chat-thread.md +521 -0
- package/ai/components/checkbox.md +7 -0
- package/ai/components/combobox.md +12 -0
- package/ai/components/date-input.md +9 -0
- package/ai/components/datetime-input.md +2 -0
- package/ai/components/field.md +10 -0
- package/ai/components/file-input.md +498 -0
- package/ai/components/header.md +1 -1
- package/ai/components/image-input.md +368 -0
- package/ai/components/image-viewer.md +309 -0
- package/ai/components/media-card.md +478 -0
- package/ai/components/menu-button.md +2 -0
- package/ai/components/menu.md +10 -0
- package/ai/components/multi-combobox.md +7 -0
- package/ai/components/nav-group.md +10 -3
- package/ai/components/nav-item.md +11 -2
- package/ai/components/number-input.md +2 -7
- package/ai/components/popover.md +13 -0
- package/ai/components/radio-group.md +6 -0
- package/ai/components/segmented.md +14 -2
- package/ai/components/select.md +100 -42
- package/ai/components/sidebar-toggle.md +16 -9
- package/ai/components/sidebar.md +41 -13
- package/ai/components/tab-group.md +18 -2
- package/ai/components/table.md +17 -2
- package/ai/components/theme-menu-button.md +1 -0
- package/ai/components/time-input.md +2 -0
- package/ai/components/toolbar.md +7 -18
- package/ai/reference/bf-chat-composer-harness.md +64 -0
- package/ai/reference/bf-chat-message-role.md +27 -0
- package/ai/reference/bf-chat-message-status.md +28 -0
- package/ai/reference/bf-fade-in-directive.md +18 -0
- package/ai/reference/bf-file-input-harness.md +67 -0
- package/ai/reference/bf-file-input-variant.md +27 -0
- package/ai/reference/bf-image-input-harness.md +67 -0
- package/ai/reference/bf-image-input-shape.md +27 -0
- package/ai/reference/bf-image-viewer-actions-context.md +29 -0
- package/ai/reference/bf-image-viewer-harness.md +87 -0
- package/ai/reference/bf-image-viewer-image.md +25 -0
- package/ai/reference/bf-image-viewer-options.md +33 -0
- package/ai/reference/bf-image-viewer-origin.md +23 -0
- package/ai/reference/bf-image-viewer-ref.md +55 -0
- package/ai/reference/bf-image-viewer-service.md +32 -0
- package/ai/reference/bf-labels.md +105 -75
- package/ai/reference/bf-media-card-aspect.md +28 -0
- package/ai/reference/bf-media-card-harness.md +66 -0
- package/ai/reference/bf-motion-list-directive.md +22 -0
- package/ai/reference/bf-prose-directive.md +16 -0
- package/ai/reference/bf-rejected-file-reason.md +28 -0
- package/ai/reference/bf-rejected-file.md +28 -0
- package/ai/reference/bf-select-harness.md +14 -5
- package/ai/reference/bf-select-option.md +2 -0
- package/ai/reference/bf-size.md +3 -0
- package/ai/reference/bf_table_sort_select.md +23 -0
- package/ai/reference/provide-bf-labels.md +10 -3
- package/ai/reference/provide-bf-select.md +20 -0
- package/bin/bf-ui.js +1 -0
- package/fesm2022/bitforgehq-ui-overlay.mjs +2649 -606
- package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -1
- package/fesm2022/bitforgehq-ui-testing.mjs +356 -10
- package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
- package/fesm2022/bitforgehq-ui.mjs +7531 -3989
- package/fesm2022/bitforgehq-ui.mjs.map +1 -1
- package/llms-full.txt +4151 -130
- package/llms.txt +31 -1
- package/package.json +1 -1
- package/theme.css +60 -0
- package/types/bitforgehq-ui-overlay.d.ts +684 -7
- package/types/bitforgehq-ui-testing.d.ts +434 -6
- package/types/bitforgehq-ui.d.ts +1473 -182
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
2
|
import { ComponentRef, DestroyRef, EnvironmentProviders, InjectionToken, Injector, Signal, StaticProvider, TemplateRef, Type } from "@angular/core";
|
|
3
3
|
import { LiveAnnouncer } from "@angular/cdk/a11y";
|
|
4
|
-
import { BfCalendarDisabledDate, BfColorScheme, BfCompareWith, BfSize } from "@bitforgehq/ui";
|
|
4
|
+
import { BfCalendarDisabledDate, BfColorScheme, BfCompareWith, BfSelectOption, BfSelectOption as BfSelectOption$1, BfSize } from "@bitforgehq/ui";
|
|
5
5
|
import * as i1 from "@angular/cdk/menu";
|
|
6
6
|
import { FormValueControl, ValidationError } from "@angular/forms/signals";
|
|
7
7
|
/**
|
|
@@ -390,7 +390,6 @@ declare function firstTabbable(panel: HTMLElement): HTMLElement | null;
|
|
|
390
390
|
* @since 0.2.0
|
|
391
391
|
*/
|
|
392
392
|
export declare class BfOverlayService {
|
|
393
|
-
private readonly overlay;
|
|
394
393
|
private readonly injector;
|
|
395
394
|
private readonly document;
|
|
396
395
|
private readonly stack;
|
|
@@ -1162,7 +1161,6 @@ interface BfDesktopToastOptions {
|
|
|
1162
1161
|
* @summary Shows brief desktop notifications in a stack at a corner of the viewport
|
|
1163
1162
|
*/
|
|
1164
1163
|
export declare class BfDesktopToastService {
|
|
1165
|
-
private readonly overlay;
|
|
1166
1164
|
private readonly injector;
|
|
1167
1165
|
private readonly document;
|
|
1168
1166
|
private readonly config;
|
|
@@ -1244,6 +1242,7 @@ export declare class BfMenuComponent {
|
|
|
1244
1242
|
readonly resolvedSize: import("@angular/core").Signal<BfSize>;
|
|
1245
1243
|
private readonly triggerId;
|
|
1246
1244
|
protected readonly labelledBy: import("@angular/core").Signal<string | null>;
|
|
1245
|
+
constructor();
|
|
1247
1246
|
static ɵfac: i0.ɵɵFactoryDeclaration<BfMenuComponent, never>;
|
|
1248
1247
|
static ɵcmp: i0.ɵɵComponentDeclaration<BfMenuComponent, "bf-menu", never, {
|
|
1249
1248
|
"size": {
|
|
@@ -1440,6 +1439,11 @@ export declare class BfMenuTriggerDirective {
|
|
|
1440
1439
|
* item, at the inline end, and ignores it. */
|
|
1441
1440
|
readonly bfMenuPlacement: import("@angular/core").InputSignal<BfMenuPlacement>;
|
|
1442
1441
|
constructor();
|
|
1442
|
+
/**
|
|
1443
|
+
* The trigger element, which the opening menu grows out of.
|
|
1444
|
+
* @internal
|
|
1445
|
+
*/
|
|
1446
|
+
anchorElement(): HTMLElement;
|
|
1443
1447
|
/** The trigger element's id (assigned when it has none), which names the menu it opens. It is
|
|
1444
1448
|
* read when the menu opens: an `[id]` bound on the trigger that changes while the menu is open
|
|
1445
1449
|
* names the menu from its next opening. */
|
|
@@ -1694,6 +1698,158 @@ export declare class BfSidebarToggleComponent {
|
|
|
1694
1698
|
};
|
|
1695
1699
|
}, {}, never, ["[bfSlot=collapse-icon]", "[bfSlot=expand-icon]"], true, never>;
|
|
1696
1700
|
}
|
|
1701
|
+
type BfChatComposerAction = 'send' | 'stop';
|
|
1702
|
+
/**
|
|
1703
|
+
* The input row of a chat: a `bf-textarea` that grows with the text (`autoResize`, up to
|
|
1704
|
+
* `maxRows`, then it scrolls), a start and an end slot for extra controls, and one button that
|
|
1705
|
+
* sends the text or, while a reply is `running`, stops it. `Enter` sends and `Shift+Enter`
|
|
1706
|
+
* starts a new line; nothing sends during IME composition or
|
|
1707
|
+
* when the text is only whitespace. After a send the text clears and focus stays in the field.
|
|
1708
|
+
* `disabled` with a `disabledReason` shows the reason as the button's tooltip and as the empty
|
|
1709
|
+
* field's placeholder.
|
|
1710
|
+
*
|
|
1711
|
+
* @example
|
|
1712
|
+
* <bf-chat-composer [(value)]="draft" [running]="replying()" (sent)="ask($event)" (stopped)="cancel()">
|
|
1713
|
+
* <bf-icon bfSlot="send-icon" [icon]="ArrowUp" />
|
|
1714
|
+
* <bf-icon bfSlot="stop-icon" [icon]="Square" />
|
|
1715
|
+
* </bf-chat-composer>
|
|
1716
|
+
* @summary Chat input that grows with the text and sends on Enter, or stops a reply
|
|
1717
|
+
* @category Forms
|
|
1718
|
+
* @since 0.5.0
|
|
1719
|
+
* @slot start Controls before the field, such as a preset picker or an attach button.
|
|
1720
|
+
* @slot end Controls between the field and the send button.
|
|
1721
|
+
* @slot send-icon The send button's icon; without one the button shows its text.
|
|
1722
|
+
* @slot stop-icon The stop button's icon; without one the button shows its text.
|
|
1723
|
+
*/
|
|
1724
|
+
export declare class BfChatComposerComponent {
|
|
1725
|
+
private readonly defaults;
|
|
1726
|
+
private readonly labels;
|
|
1727
|
+
/** The text being written; two-way bindable. Cleared after a send. */
|
|
1728
|
+
readonly value: import("@angular/core").ModelSignal<string>;
|
|
1729
|
+
/** A reply is running: the button stops it (`stopped`) instead of sending. */
|
|
1730
|
+
readonly running: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1731
|
+
/** Nothing can be written or sent. */
|
|
1732
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
1733
|
+
/** Why it is disabled, shown as the button's tooltip and the empty field's placeholder. */
|
|
1734
|
+
readonly disabledReason: import("@angular/core").InputSignal<string>;
|
|
1735
|
+
/** Visible label above the field; usually left empty in a chat. */
|
|
1736
|
+
readonly label: import("@angular/core").InputSignal<string>;
|
|
1737
|
+
/** The field's accessible name without a visible label; empty uses the `chatComposer` label
|
|
1738
|
+
* ("Message"). */
|
|
1739
|
+
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
1740
|
+
/** Id(s) of the element(s) that name the field without a visible label. */
|
|
1741
|
+
readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
|
|
1742
|
+
/** Example text shown while the field is empty. */
|
|
1743
|
+
readonly placeholder: import("@angular/core").InputSignal<string>;
|
|
1744
|
+
/** The lines the field grows to at most; past them it scrolls. */
|
|
1745
|
+
readonly maxRows: import("@angular/core").InputSignal<number>;
|
|
1746
|
+
/** Maximum number of characters (native `maxlength`). */
|
|
1747
|
+
readonly maxLength: import("@angular/core").InputSignal<number | undefined>;
|
|
1748
|
+
/** Native name attribute of the textarea. */
|
|
1749
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
1750
|
+
/** Padding, type and button step: sm, md, lg; unset follows `provideBfDefaults()`
|
|
1751
|
+
* (`fieldSize`, `md` by default). */
|
|
1752
|
+
readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
|
|
1753
|
+
/** Emitted with the new text right after the user changes it (each keystroke or paste). */
|
|
1754
|
+
readonly changed: import("@angular/core").OutputEmitterRef<string>;
|
|
1755
|
+
/** Emitted with the trimmed text when the user sends it (Enter or the send button). */
|
|
1756
|
+
readonly sent: import("@angular/core").OutputEmitterRef<string>;
|
|
1757
|
+
/** Emitted when the user presses the stop button while `running`. */
|
|
1758
|
+
readonly stopped: import("@angular/core").OutputEmitterRef<void>;
|
|
1759
|
+
private readonly field;
|
|
1760
|
+
protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
|
|
1761
|
+
/** The field's one-line height, matched to the button. */
|
|
1762
|
+
protected readonly fieldClasses: import("@angular/core").Signal<string>;
|
|
1763
|
+
protected readonly action: import("@angular/core").Signal<BfChatComposerAction>;
|
|
1764
|
+
/** Disabled with a reason: focusable, `aria-disabled`, with the reason as a tooltip. */
|
|
1765
|
+
protected readonly blocked: import("@angular/core").Signal<boolean>;
|
|
1766
|
+
/** Native `disabled`: disabled without a reason, or nothing to send yet. */
|
|
1767
|
+
protected readonly nativeDisabled: import("@angular/core").Signal<boolean>;
|
|
1768
|
+
protected readonly buttonName: import("@angular/core").Signal<string>;
|
|
1769
|
+
/** The field's `aria-label`: `ariaLabel`, else the label key while nothing else names it. */
|
|
1770
|
+
protected readonly fieldName: import("@angular/core").Signal<string>;
|
|
1771
|
+
protected readonly fieldPlaceholder: import("@angular/core").Signal<string>;
|
|
1772
|
+
protected readonly buttonClasses: import("@angular/core").Signal<string>;
|
|
1773
|
+
/** Sends the text: emits `sent` with it trimmed, clears the field and keeps focus in it. Does
|
|
1774
|
+
* nothing while disabled or running, or when the text is only whitespace. */
|
|
1775
|
+
send(): void;
|
|
1776
|
+
/** Focuses the text field. */
|
|
1777
|
+
focus(): void;
|
|
1778
|
+
/** @internal */
|
|
1779
|
+
onChanged(text: string): void;
|
|
1780
|
+
/** @internal */
|
|
1781
|
+
onButton(): void;
|
|
1782
|
+
/** @internal */
|
|
1783
|
+
onKeydown(event: KeyboardEvent): void;
|
|
1784
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BfChatComposerComponent, never>;
|
|
1785
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<BfChatComposerComponent, "bf-chat-composer", never, {
|
|
1786
|
+
"value": {
|
|
1787
|
+
"alias": "value";
|
|
1788
|
+
"required": false;
|
|
1789
|
+
"isSignal": true;
|
|
1790
|
+
};
|
|
1791
|
+
"running": {
|
|
1792
|
+
"alias": "running";
|
|
1793
|
+
"required": false;
|
|
1794
|
+
"isSignal": true;
|
|
1795
|
+
};
|
|
1796
|
+
"disabled": {
|
|
1797
|
+
"alias": "disabled";
|
|
1798
|
+
"required": false;
|
|
1799
|
+
"isSignal": true;
|
|
1800
|
+
};
|
|
1801
|
+
"disabledReason": {
|
|
1802
|
+
"alias": "disabledReason";
|
|
1803
|
+
"required": false;
|
|
1804
|
+
"isSignal": true;
|
|
1805
|
+
};
|
|
1806
|
+
"label": {
|
|
1807
|
+
"alias": "label";
|
|
1808
|
+
"required": false;
|
|
1809
|
+
"isSignal": true;
|
|
1810
|
+
};
|
|
1811
|
+
"ariaLabel": {
|
|
1812
|
+
"alias": "ariaLabel";
|
|
1813
|
+
"required": false;
|
|
1814
|
+
"isSignal": true;
|
|
1815
|
+
};
|
|
1816
|
+
"ariaLabelledby": {
|
|
1817
|
+
"alias": "ariaLabelledby";
|
|
1818
|
+
"required": false;
|
|
1819
|
+
"isSignal": true;
|
|
1820
|
+
};
|
|
1821
|
+
"placeholder": {
|
|
1822
|
+
"alias": "placeholder";
|
|
1823
|
+
"required": false;
|
|
1824
|
+
"isSignal": true;
|
|
1825
|
+
};
|
|
1826
|
+
"maxRows": {
|
|
1827
|
+
"alias": "maxRows";
|
|
1828
|
+
"required": false;
|
|
1829
|
+
"isSignal": true;
|
|
1830
|
+
};
|
|
1831
|
+
"maxLength": {
|
|
1832
|
+
"alias": "maxLength";
|
|
1833
|
+
"required": false;
|
|
1834
|
+
"isSignal": true;
|
|
1835
|
+
};
|
|
1836
|
+
"name": {
|
|
1837
|
+
"alias": "name";
|
|
1838
|
+
"required": false;
|
|
1839
|
+
"isSignal": true;
|
|
1840
|
+
};
|
|
1841
|
+
"size": {
|
|
1842
|
+
"alias": "size";
|
|
1843
|
+
"required": false;
|
|
1844
|
+
"isSignal": true;
|
|
1845
|
+
};
|
|
1846
|
+
}, {
|
|
1847
|
+
"value": "valueChange";
|
|
1848
|
+
"changed": "changed";
|
|
1849
|
+
"sent": "sent";
|
|
1850
|
+
"stopped": "stopped";
|
|
1851
|
+
}, never, ["[bfSlot=start]", "[bfSlot=end]", "[bfSlot=send-icon]", "[bfSlot=stop-icon]"], true, never>;
|
|
1852
|
+
}
|
|
1697
1853
|
/**
|
|
1698
1854
|
* Layout of a side panel opened with `BfSidePanelService`: a title row with a close button, a
|
|
1699
1855
|
* scrolling body and a footer of actions kept at the bottom. The panel is labelled by the title,
|
|
@@ -1932,7 +2088,7 @@ type BfTooltipPlacement = 'top' | 'bottom' | 'start' | 'end';
|
|
|
1932
2088
|
* @since 0.3.1
|
|
1933
2089
|
*/
|
|
1934
2090
|
export declare class BfTooltipDirective {
|
|
1935
|
-
private readonly
|
|
2091
|
+
private readonly environment;
|
|
1936
2092
|
private readonly document;
|
|
1937
2093
|
private readonly injector;
|
|
1938
2094
|
private readonly dir;
|
|
@@ -2037,7 +2193,7 @@ type BfPopoverPlacement = 'below-start' | 'below-end' | 'above-start' | 'above-e
|
|
|
2037
2193
|
* @since 0.3.1
|
|
2038
2194
|
*/
|
|
2039
2195
|
export declare class BfPopoverTriggerDirective {
|
|
2040
|
-
private readonly
|
|
2196
|
+
private readonly environment;
|
|
2041
2197
|
private readonly document;
|
|
2042
2198
|
private readonly injector;
|
|
2043
2199
|
private readonly viewContainer;
|
|
@@ -2060,6 +2216,7 @@ export declare class BfPopoverTriggerDirective {
|
|
|
2060
2216
|
/** The id the `bf-popover` panel takes, which the trigger's `aria-controls` points at. */
|
|
2061
2217
|
readonly panelId: string;
|
|
2062
2218
|
private anchored;
|
|
2219
|
+
private readonly motion;
|
|
2063
2220
|
private subscriptions;
|
|
2064
2221
|
private stopNavigation;
|
|
2065
2222
|
private stopHeading;
|
|
@@ -2089,6 +2246,10 @@ export declare class BfPopoverTriggerDirective {
|
|
|
2089
2246
|
* the trigger.
|
|
2090
2247
|
*/
|
|
2091
2248
|
private name;
|
|
2249
|
+
/**
|
|
2250
|
+
* Drops the listeners and closes the overlay: with its exit animation (it stays attached, inert,
|
|
2251
|
+
* until the exit has played), or at once when the directive is destroyed.
|
|
2252
|
+
*/
|
|
2092
2253
|
private teardown;
|
|
2093
2254
|
static ɵfac: i0.ɵɵFactoryDeclaration<BfPopoverTriggerDirective, never>;
|
|
2094
2255
|
static ɵdir: i0.ɵɵDirectiveDeclaration<BfPopoverTriggerDirective, "[bfPopoverTriggerFor]", ["bfPopoverTrigger"], {
|
|
@@ -2197,7 +2358,7 @@ interface ComboboxHost<T> {
|
|
|
2197
2358
|
*/
|
|
2198
2359
|
declare class ComboboxCore<T> {
|
|
2199
2360
|
readonly host: ComboboxHost<T>;
|
|
2200
|
-
private readonly
|
|
2361
|
+
private readonly environment;
|
|
2201
2362
|
private readonly injector;
|
|
2202
2363
|
private readonly viewContainer;
|
|
2203
2364
|
private readonly dir;
|
|
@@ -2220,6 +2381,9 @@ declare class ComboboxCore<T> {
|
|
|
2220
2381
|
/** `aria-controls`: the listbox while it is rendered. */
|
|
2221
2382
|
readonly controls: Signal<string | null>;
|
|
2222
2383
|
private anchored;
|
|
2384
|
+
/** The listbox component's view, frozen while the panel plays its exit. */
|
|
2385
|
+
private panelView;
|
|
2386
|
+
private readonly motion;
|
|
2223
2387
|
private subscriptions;
|
|
2224
2388
|
constructor(host: ComboboxHost<T>);
|
|
2225
2389
|
/**
|
|
@@ -2257,6 +2421,10 @@ declare class ComboboxCore<T> {
|
|
|
2257
2421
|
/** Moves the active option by `step` through the enabled ones, wrapping at the ends. */
|
|
2258
2422
|
private move;
|
|
2259
2423
|
private firstEnabled;
|
|
2424
|
+
/**
|
|
2425
|
+
* Drops the listeners and closes the overlay: with its exit animation (the list frozen as it
|
|
2426
|
+
* was, so a reset query never reflows it while it fades), or at once on destroy.
|
|
2427
|
+
*/
|
|
2260
2428
|
private teardown;
|
|
2261
2429
|
}
|
|
2262
2430
|
/** Equality of an option's value and a picked value under `compareWith`, never for `null`. */
|
|
@@ -2777,6 +2945,271 @@ export declare class BfMultiComboboxComponent<T = string> implements FormValueCo
|
|
|
2777
2945
|
"touch": "touch";
|
|
2778
2946
|
}, never, never, true, never>;
|
|
2779
2947
|
}
|
|
2948
|
+
/**
|
|
2949
|
+
* Single-choice dropdown styled like the text field, with a placeholder and Signal Forms binding.
|
|
2950
|
+
* Under a mouse it opens a styled list (the combobox's) that follows the select-only combobox
|
|
2951
|
+
* pattern: the arrow keys, `Home`, `End`, `PageUp`/`PageDown` and typeahead move through it,
|
|
2952
|
+
* `Enter`, `Space` or `Tab` pick. Under a coarse pointer (touch) it renders the platform's native
|
|
2953
|
+
* select instead. Generic over the option value (a string by default); `null` means nothing is
|
|
2954
|
+
* selected. Moved from `@bitforgehq/ui` to `@bitforgehq/ui/overlay` in 0.5.0.
|
|
2955
|
+
*
|
|
2956
|
+
* @example
|
|
2957
|
+
* <bf-select label="Project" placeholder="Pick a project" [options]="projects" [(value)]="projectId" />
|
|
2958
|
+
* <bf-select label="Team" placeholder="Pick a team" [options]="teams" [formField]="task.teamId" />
|
|
2959
|
+
* @summary Single-choice dropdown with a styled list, native under touch, with Signal Forms binding
|
|
2960
|
+
* @category Forms
|
|
2961
|
+
* @since 0.1.0
|
|
2962
|
+
*/
|
|
2963
|
+
export declare class BfSelectComponent<T = string> implements FormValueControl<T | null> {
|
|
2964
|
+
/** The selected option's value, `null` while nothing is selected; two-way bindable and bound by
|
|
2965
|
+
* `[formField]`. */
|
|
2966
|
+
readonly value: import("@angular/core").ModelSignal<T | null>;
|
|
2967
|
+
/** The options to choose from. */
|
|
2968
|
+
readonly options: import("@angular/core").InputSignal<readonly BfSelectOption$1<T>[]>;
|
|
2969
|
+
/** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */
|
|
2970
|
+
readonly compareWith: import("@angular/core").InputSignal<BfCompareWith<T>>;
|
|
2971
|
+
/** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`
|
|
2972
|
+
* by default). */
|
|
2973
|
+
readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
|
|
2974
|
+
/** Visible label above the control. */
|
|
2975
|
+
readonly label: import("@angular/core").InputSignal<string>;
|
|
2976
|
+
/**
|
|
2977
|
+
* Accessible name when no visible label is rendered (e.g. a table filter). Ignored when `label`
|
|
2978
|
+
* is set.
|
|
2979
|
+
*/
|
|
2980
|
+
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
2981
|
+
/**
|
|
2982
|
+
* Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when
|
|
2983
|
+
* `label` is set.
|
|
2984
|
+
*/
|
|
2985
|
+
readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
|
|
2986
|
+
/** Muted text shown while nothing is selected. */
|
|
2987
|
+
readonly placeholder: import("@angular/core").InputSignal<string>;
|
|
2988
|
+
/** Helper text under the control. */
|
|
2989
|
+
readonly helpText: import("@angular/core").InputSignal<string>;
|
|
2990
|
+
/** Explicit error text; takes precedence over Signal Forms errors. */
|
|
2991
|
+
readonly errorMessage: import("@angular/core").InputSignal<string>;
|
|
2992
|
+
/** Disables the control. */
|
|
2993
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2994
|
+
/** Shows the value but blocks changes; the select stays focusable and exposes `aria-readonly`. */
|
|
2995
|
+
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2996
|
+
/** Marks the control required. */
|
|
2997
|
+
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
2998
|
+
/** Field validity from Signal Forms. */
|
|
2999
|
+
readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
3000
|
+
/** Whether the user has left the field. */
|
|
3001
|
+
readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
3002
|
+
/** Validation errors from Signal Forms. */
|
|
3003
|
+
readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
3004
|
+
/** Form name: of a hidden input carrying the selected option's key, or of the native select. */
|
|
3005
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
3006
|
+
/** Control id; generated when not set. */
|
|
3007
|
+
readonly id: import("@angular/core").InputSignal<string>;
|
|
3008
|
+
/** Emitted with the chosen value after a user change (never `null`). */
|
|
3009
|
+
readonly changed: import("@angular/core").OutputEmitterRef<T>;
|
|
3010
|
+
/** Emitted when the control gains focus. */
|
|
3011
|
+
readonly focused: import("@angular/core").OutputEmitterRef<FocusEvent>;
|
|
3012
|
+
/** Emitted when the control loses focus. */
|
|
3013
|
+
readonly blurred: import("@angular/core").OutputEmitterRef<FocusEvent>;
|
|
3014
|
+
/** Emitted on blur so Signal Forms marks the field touched. */
|
|
3015
|
+
readonly touch: import("@angular/core").OutputEmitterRef<void>;
|
|
3016
|
+
private readonly fieldEl;
|
|
3017
|
+
private readonly anchorEl;
|
|
3018
|
+
private readonly nativeSelect;
|
|
3019
|
+
private readonly defaults;
|
|
3020
|
+
private readonly labels;
|
|
3021
|
+
private readonly document;
|
|
3022
|
+
/** Whether the primary pointer is coarse (touch), from `matchMedia`: the native mode. */
|
|
3023
|
+
protected readonly coarse: import("@angular/core").WritableSignal<boolean>;
|
|
3024
|
+
/** The size in effect: `size`, else the app's `fieldSize` default. */
|
|
3025
|
+
protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
|
|
3026
|
+
/** Index of the option matching `value`, `-1` while nothing (or `null`) is selected. */
|
|
3027
|
+
protected readonly selectedIndex: import("@angular/core").Signal<number>;
|
|
3028
|
+
/** The selected option's label, null while nothing is selected. */
|
|
3029
|
+
protected readonly selectedLabel: import("@angular/core").Signal<string | null>;
|
|
3030
|
+
/** The hidden input's value: the selected option's key (its index for an object), else `''`. */
|
|
3031
|
+
protected readonly formKey: import("@angular/core").Signal<string>;
|
|
3032
|
+
/** The options as the list shows them; the selected one is matched by identity. */
|
|
3033
|
+
private readonly listOptions;
|
|
3034
|
+
protected readonly core: ComboboxCore<T>;
|
|
3035
|
+
protected readonly errorText: import("@angular/core").Signal<string>;
|
|
3036
|
+
protected readonly showError: import("@angular/core").Signal<boolean>;
|
|
3037
|
+
protected readonly describedBy: import("@angular/core").Signal<string | null>;
|
|
3038
|
+
/** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */
|
|
3039
|
+
protected readonly errorMessageId: import("@angular/core").Signal<string | null>;
|
|
3040
|
+
/**
|
|
3041
|
+
* `aria-label` value: only when there is no visible label, so the label stays the sole accessible
|
|
3042
|
+
* name.
|
|
3043
|
+
*/
|
|
3044
|
+
protected readonly ariaLabelAttr: import("@angular/core").Signal<string | null>;
|
|
3045
|
+
/**
|
|
3046
|
+
* `aria-labelledby` value while there is no visible label; with one, the field points
|
|
3047
|
+
* `aria-labelledby` at the label's id instead (a `<label for>` cannot name a div).
|
|
3048
|
+
*/
|
|
3049
|
+
protected readonly ariaLabelledbyAttr: import("@angular/core").Signal<string | null>;
|
|
3050
|
+
protected readonly wrapperClasses: import("@angular/core").Signal<string>;
|
|
3051
|
+
protected readonly classes: import("@angular/core").Signal<string>;
|
|
3052
|
+
/** The typed typeahead text and when its last key came. */
|
|
3053
|
+
private typeahead;
|
|
3054
|
+
private typedAt;
|
|
3055
|
+
constructor();
|
|
3056
|
+
/**
|
|
3057
|
+
* Focuses the field, or the native select under a coarse pointer; Signal Forms calls it from
|
|
3058
|
+
* `focusBoundControl()`.
|
|
3059
|
+
* @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
|
|
3060
|
+
*/
|
|
3061
|
+
focus(options?: FocusOptions): void;
|
|
3062
|
+
/**
|
|
3063
|
+
* A click on the label focuses the field (a label's `for` cannot name a div).
|
|
3064
|
+
* @internal
|
|
3065
|
+
*/
|
|
3066
|
+
onHostClick(event: MouseEvent): void;
|
|
3067
|
+
/**
|
|
3068
|
+
* A click on the field opens or closes the list.
|
|
3069
|
+
* @internal
|
|
3070
|
+
*/
|
|
3071
|
+
onClick(): void;
|
|
3072
|
+
/**
|
|
3073
|
+
* The select-only combobox keys: `Enter`, `Space` and the arrows open; while open the arrows,
|
|
3074
|
+
* `Home`, `End`, `PageUp` and `PageDown` move, `Enter`, `Space` and `Tab` pick; printable keys
|
|
3075
|
+
* search by label. `Escape` on an open list is the panel's: it closes it.
|
|
3076
|
+
* @internal
|
|
3077
|
+
*/
|
|
3078
|
+
onKeydown(event: KeyboardEvent): void;
|
|
3079
|
+
/**
|
|
3080
|
+
* Leaving the field closes the list, emits `blurred` and marks the field touched. A press in the
|
|
3081
|
+
* list never moves the focus (the listbox cancels it), so this runs only when the field is left.
|
|
3082
|
+
* @internal
|
|
3083
|
+
*/
|
|
3084
|
+
onBlur(event: FocusEvent): void;
|
|
3085
|
+
/** Opens the list with the selected option active, else the first enabled one. */
|
|
3086
|
+
private openList;
|
|
3087
|
+
/** Picks an option: the value and `changed` when it differs, and the list closes. */
|
|
3088
|
+
private pick;
|
|
3089
|
+
private pickActive;
|
|
3090
|
+
/** Moves the active option by `step` enabled options, stopping at the ends. */
|
|
3091
|
+
private page;
|
|
3092
|
+
/** Whether a typeahead search is still being typed. */
|
|
3093
|
+
private typing;
|
|
3094
|
+
/**
|
|
3095
|
+
* Adds a key to the typeahead search, opens the list and activates the next enabled option whose
|
|
3096
|
+
* label starts with the search, ignoring case and accents. One letter repeated cycles through the
|
|
3097
|
+
* options starting with it; a longer search keeps the active option while it still matches.
|
|
3098
|
+
*/
|
|
3099
|
+
private search;
|
|
3100
|
+
/** The list's enabled options in list order. */
|
|
3101
|
+
private enabledItems;
|
|
3102
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BfSelectComponent<any>, never>;
|
|
3103
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<BfSelectComponent<any>, "bf-select", never, {
|
|
3104
|
+
"value": {
|
|
3105
|
+
"alias": "value";
|
|
3106
|
+
"required": false;
|
|
3107
|
+
"isSignal": true;
|
|
3108
|
+
};
|
|
3109
|
+
"options": {
|
|
3110
|
+
"alias": "options";
|
|
3111
|
+
"required": true;
|
|
3112
|
+
"isSignal": true;
|
|
3113
|
+
};
|
|
3114
|
+
"compareWith": {
|
|
3115
|
+
"alias": "compareWith";
|
|
3116
|
+
"required": false;
|
|
3117
|
+
"isSignal": true;
|
|
3118
|
+
};
|
|
3119
|
+
"size": {
|
|
3120
|
+
"alias": "size";
|
|
3121
|
+
"required": false;
|
|
3122
|
+
"isSignal": true;
|
|
3123
|
+
};
|
|
3124
|
+
"label": {
|
|
3125
|
+
"alias": "label";
|
|
3126
|
+
"required": false;
|
|
3127
|
+
"isSignal": true;
|
|
3128
|
+
};
|
|
3129
|
+
"ariaLabel": {
|
|
3130
|
+
"alias": "ariaLabel";
|
|
3131
|
+
"required": false;
|
|
3132
|
+
"isSignal": true;
|
|
3133
|
+
};
|
|
3134
|
+
"ariaLabelledby": {
|
|
3135
|
+
"alias": "ariaLabelledby";
|
|
3136
|
+
"required": false;
|
|
3137
|
+
"isSignal": true;
|
|
3138
|
+
};
|
|
3139
|
+
"placeholder": {
|
|
3140
|
+
"alias": "placeholder";
|
|
3141
|
+
"required": false;
|
|
3142
|
+
"isSignal": true;
|
|
3143
|
+
};
|
|
3144
|
+
"helpText": {
|
|
3145
|
+
"alias": "helpText";
|
|
3146
|
+
"required": false;
|
|
3147
|
+
"isSignal": true;
|
|
3148
|
+
};
|
|
3149
|
+
"errorMessage": {
|
|
3150
|
+
"alias": "errorMessage";
|
|
3151
|
+
"required": false;
|
|
3152
|
+
"isSignal": true;
|
|
3153
|
+
};
|
|
3154
|
+
"disabled": {
|
|
3155
|
+
"alias": "disabled";
|
|
3156
|
+
"required": false;
|
|
3157
|
+
"isSignal": true;
|
|
3158
|
+
};
|
|
3159
|
+
"readonly": {
|
|
3160
|
+
"alias": "readonly";
|
|
3161
|
+
"required": false;
|
|
3162
|
+
"isSignal": true;
|
|
3163
|
+
};
|
|
3164
|
+
"required": {
|
|
3165
|
+
"alias": "required";
|
|
3166
|
+
"required": false;
|
|
3167
|
+
"isSignal": true;
|
|
3168
|
+
};
|
|
3169
|
+
"invalid": {
|
|
3170
|
+
"alias": "invalid";
|
|
3171
|
+
"required": false;
|
|
3172
|
+
"isSignal": true;
|
|
3173
|
+
};
|
|
3174
|
+
"touched": {
|
|
3175
|
+
"alias": "touched";
|
|
3176
|
+
"required": false;
|
|
3177
|
+
"isSignal": true;
|
|
3178
|
+
};
|
|
3179
|
+
"errors": {
|
|
3180
|
+
"alias": "errors";
|
|
3181
|
+
"required": false;
|
|
3182
|
+
"isSignal": true;
|
|
3183
|
+
};
|
|
3184
|
+
"name": {
|
|
3185
|
+
"alias": "name";
|
|
3186
|
+
"required": false;
|
|
3187
|
+
"isSignal": true;
|
|
3188
|
+
};
|
|
3189
|
+
"id": {
|
|
3190
|
+
"alias": "id";
|
|
3191
|
+
"required": false;
|
|
3192
|
+
"isSignal": true;
|
|
3193
|
+
};
|
|
3194
|
+
}, {
|
|
3195
|
+
"value": "valueChange";
|
|
3196
|
+
"changed": "changed";
|
|
3197
|
+
"focused": "focused";
|
|
3198
|
+
"blurred": "blurred";
|
|
3199
|
+
"touch": "touch";
|
|
3200
|
+
}, never, never, true, never>;
|
|
3201
|
+
}
|
|
3202
|
+
/**
|
|
3203
|
+
* Makes the library's built-in selects use the styled `bf-select`: a stacked `bf-table` then
|
|
3204
|
+
* renders its Sort by select as a `bf-select` (the native `<select>` under a coarse pointer, as
|
|
3205
|
+
* `bf-select` itself does) instead of the plain native one. Add it to
|
|
3206
|
+
* `ApplicationConfig.providers`.
|
|
3207
|
+
*
|
|
3208
|
+
* @returns The providers that fill `BF_TABLE_SORT_SELECT` with `BfSelectComponent`.
|
|
3209
|
+
* @summary Makes a stacked table's Sort by select the styled bf-select, app-wide
|
|
3210
|
+
* @since 0.5.0
|
|
3211
|
+
*/
|
|
3212
|
+
export declare function provideBfSelect(): EnvironmentProviders;
|
|
2780
3213
|
/**
|
|
2781
3214
|
* How `bf-date-input` picks a date besides typing: `calendar` adds a button that opens a
|
|
2782
3215
|
* `bf-calendar` in a popover, `none` keeps the field typed only.
|
|
@@ -3399,4 +3832,248 @@ export declare class BfDateTimeInputComponent implements FormValueControl<string
|
|
|
3399
3832
|
"touch": "touch";
|
|
3400
3833
|
}, never, never, true, never>;
|
|
3401
3834
|
}
|
|
3402
|
-
|
|
3835
|
+
/**
|
|
3836
|
+
* One image of a `BfImageViewerService.open()` set.
|
|
3837
|
+
*
|
|
3838
|
+
* @summary One image the viewer shows: its URL, its name as alternative text and a caption
|
|
3839
|
+
* @since 0.5.0
|
|
3840
|
+
*/
|
|
3841
|
+
interface BfImageViewerImage {
|
|
3842
|
+
/** URL of the full-size image. */
|
|
3843
|
+
src: string;
|
|
3844
|
+
/**
|
|
3845
|
+
* The image's name: its alternative text (`alt`), read when it shows and announced after a step
|
|
3846
|
+
* (required: the viewer shows nothing else that names it).
|
|
3847
|
+
*/
|
|
3848
|
+
label: string;
|
|
3849
|
+
/** Text shown under the image; none shows no caption. */
|
|
3850
|
+
caption?: string;
|
|
3851
|
+
}
|
|
3852
|
+
/**
|
|
3853
|
+
* Handle to an open image viewer, returned by `BfImageViewerService.open()` and injectable in
|
|
3854
|
+
* its actions template (`inject(BfImageViewerRef)`). `index` is the shown image; `next()`,
|
|
3855
|
+
* `previous()` and `goTo()` step through the set (wrapping at both ends), `close()` plays the
|
|
3856
|
+
* exit motion and resolves `afterClosed`.
|
|
3857
|
+
*
|
|
3858
|
+
* @example
|
|
3859
|
+
* const ref = inject(BfImageViewerService).open({ images, index: 2, origin: thumb });
|
|
3860
|
+
* ref.next();
|
|
3861
|
+
* await ref.afterClosed;
|
|
3862
|
+
* @summary Handle on an open image viewer that steps through its images and closes it
|
|
3863
|
+
* @since 0.5.0
|
|
3864
|
+
*/
|
|
3865
|
+
export declare class BfImageViewerRef {
|
|
3866
|
+
private readonly overlayRef;
|
|
3867
|
+
/** Unique id of the viewer (its overlay's `bf-overlay-N`). */
|
|
3868
|
+
readonly id: string;
|
|
3869
|
+
/** The images of the set, in order. */
|
|
3870
|
+
readonly images: readonly BfImageViewerImage[];
|
|
3871
|
+
/** Resolves once the viewer has closed and left the page. */
|
|
3872
|
+
readonly afterClosed: Promise<void>;
|
|
3873
|
+
/** True once the viewer has been detached. */
|
|
3874
|
+
readonly closed: Signal<boolean>;
|
|
3875
|
+
private readonly current;
|
|
3876
|
+
/** Index (0-based) of the image the viewer shows. */
|
|
3877
|
+
readonly index: Signal<number>;
|
|
3878
|
+
/** @internal Created by `BfImageViewerService`; apps never construct it. */
|
|
3879
|
+
constructor(overlayRef: BfOverlayRef<unknown>, images: readonly BfImageViewerImage[], start: number);
|
|
3880
|
+
/** Shows the next image; after the last one, the first. */
|
|
3881
|
+
next(): void;
|
|
3882
|
+
/** Shows the previous image; before the first one, the last. */
|
|
3883
|
+
previous(): void;
|
|
3884
|
+
/**
|
|
3885
|
+
* Shows the image at `index`, wrapped into the set (`-1` is the last one).
|
|
3886
|
+
* @param index The 0-based index of the image to show.
|
|
3887
|
+
*/
|
|
3888
|
+
goTo(index: number): void;
|
|
3889
|
+
/** Closes the viewer: it zooms back into its thumbnail, or fades out. Ignored once closing. */
|
|
3890
|
+
close(): void;
|
|
3891
|
+
}
|
|
3892
|
+
/**
|
|
3893
|
+
* Where the viewer zooms from and back to: the thumbnail that was clicked, or a function that
|
|
3894
|
+
* returns the thumbnail of any image of the set (so closing after stepping zooms into the right
|
|
3895
|
+
* one), `null` for none.
|
|
3896
|
+
*
|
|
3897
|
+
* @summary The thumbnail an image viewer zooms from and back into, or a lookup per image
|
|
3898
|
+
* @since 0.5.0
|
|
3899
|
+
*/
|
|
3900
|
+
type BfImageViewerOrigin = HTMLElement | ((index: number) => HTMLElement | null | undefined) | null;
|
|
3901
|
+
/**
|
|
3902
|
+
* Context of the `actions` template of `BfImageViewerService.open()`: `let-image`,
|
|
3903
|
+
* `let-index="index"` and `let-ref="ref"`.
|
|
3904
|
+
*
|
|
3905
|
+
* @summary What the viewer's actions template receives: the shown image, its index and the ref
|
|
3906
|
+
* @since 0.5.0
|
|
3907
|
+
*/
|
|
3908
|
+
interface BfImageViewerActionsContext {
|
|
3909
|
+
/** The image the viewer shows (`let-image`). */
|
|
3910
|
+
$implicit: BfImageViewerImage;
|
|
3911
|
+
/** Its 0-based index in the set (`let-index="index"`). */
|
|
3912
|
+
index: number;
|
|
3913
|
+
/** The viewer's ref (`let-ref="ref"`), to close it or step. */
|
|
3914
|
+
ref: BfImageViewerRef;
|
|
3915
|
+
}
|
|
3916
|
+
/** @internal What `BfImageViewerService` hands the `bf-image-viewer` it opens. */
|
|
3917
|
+
interface BfImageViewerContext {
|
|
3918
|
+
readonly start: number;
|
|
3919
|
+
/** The viewer's accessible name. */
|
|
3920
|
+
readonly label: string;
|
|
3921
|
+
readonly origin: BfImageViewerOrigin;
|
|
3922
|
+
readonly actions: TemplateRef<BfImageViewerActionsContext> | null;
|
|
3923
|
+
/** Called by the viewer as it is created, so the overlay's enter and exit can run its motion. */
|
|
3924
|
+
readonly register: (motion: BfImageViewerMotion) => void;
|
|
3925
|
+
}
|
|
3926
|
+
/** @internal The open and close motion of a `bf-image-viewer`. */
|
|
3927
|
+
interface BfImageViewerMotion {
|
|
3928
|
+
enter(): Animation;
|
|
3929
|
+
exit(): Animation;
|
|
3930
|
+
}
|
|
3931
|
+
/** @internal Provided by `BfImageViewerService` to the viewer it opens. */
|
|
3932
|
+
declare const BF_IMAGE_VIEWER_CONTEXT: InjectionToken<BfImageViewerContext>;
|
|
3933
|
+
/** How far one image got. */
|
|
3934
|
+
type ImageStatus = 'pending' | 'loaded' | 'error';
|
|
3935
|
+
/**
|
|
3936
|
+
* The full-screen image viewer (lightbox) `BfImageViewerService.open()` renders: one image large
|
|
3937
|
+
* over a dark scrim, with a counter, previous and next buttons, a close button, an optional
|
|
3938
|
+
* caption and actions. It opens with a zoom out of the clicked thumbnail and steps with a
|
|
3939
|
+
* cross-fade. Apps do not place it in templates; open it with the service.
|
|
3940
|
+
*
|
|
3941
|
+
* @example
|
|
3942
|
+
* const ref = inject(BfImageViewerService).open({
|
|
3943
|
+
* images: [{ src: '/art/1.jpg', label: 'Neon skyline', caption: 'Concept 1' }],
|
|
3944
|
+
* index: 0,
|
|
3945
|
+
* origin: thumbnailElement,
|
|
3946
|
+
* });
|
|
3947
|
+
* @summary Full-screen image viewer that zooms from a thumbnail and steps through a set
|
|
3948
|
+
* @category Overlays
|
|
3949
|
+
* @since 0.5.0
|
|
3950
|
+
*/
|
|
3951
|
+
export declare class BfImageViewerComponent implements BfImageViewerMotion {
|
|
3952
|
+
protected readonly labels: import("@bitforgehq/ui").BfLabels;
|
|
3953
|
+
protected readonly ref: BfImageViewerRef;
|
|
3954
|
+
protected readonly context: BfImageViewerContext;
|
|
3955
|
+
protected readonly injector: Injector;
|
|
3956
|
+
private readonly document;
|
|
3957
|
+
private readonly host;
|
|
3958
|
+
protected readonly closeIcon: import("lucide").IconNode;
|
|
3959
|
+
protected readonly previousIcon: import("lucide").IconNode;
|
|
3960
|
+
protected readonly nextIcon: import("lucide").IconNode;
|
|
3961
|
+
protected readonly previousClasses = "pointer-events-auto absolute top-1/2 -translate-y-1/2 start-3";
|
|
3962
|
+
protected readonly nextClasses = "pointer-events-auto absolute top-1/2 -translate-y-1/2 end-3";
|
|
3963
|
+
private readonly frame;
|
|
3964
|
+
private readonly scrim;
|
|
3965
|
+
private readonly top;
|
|
3966
|
+
private readonly bottom;
|
|
3967
|
+
/** The progress of every image shown so far, by index. */
|
|
3968
|
+
private readonly statuses;
|
|
3969
|
+
/** The aspect ratio (width / height) of every image that has loaded, by index. */
|
|
3970
|
+
private readonly ratios;
|
|
3971
|
+
protected readonly count: import("@angular/core").Signal<number>;
|
|
3972
|
+
protected readonly index: import("@angular/core").Signal<number>;
|
|
3973
|
+
protected readonly image: import("@angular/core").Signal<BfImageViewerImage>;
|
|
3974
|
+
protected readonly status: import("@angular/core").Signal<ImageStatus>;
|
|
3975
|
+
/** The shown image, keyed by index so a step replaces the element (and cross-fades); none
|
|
3976
|
+
* once it failed, so the failure message is not drawn over a broken-image box. */
|
|
3977
|
+
protected readonly shown: import("@angular/core").Signal<{
|
|
3978
|
+
index: number;
|
|
3979
|
+
image: BfImageViewerImage;
|
|
3980
|
+
}[]>;
|
|
3981
|
+
protected readonly counter: import("@angular/core").Signal<string>;
|
|
3982
|
+
/** Announced politely after each step (never on open, where the dialog itself is read). */
|
|
3983
|
+
private readonly stepped;
|
|
3984
|
+
protected readonly announcement: import("@angular/core").Signal<string>;
|
|
3985
|
+
/** The thumbnail of the shown image, under it until the large one arrives. */
|
|
3986
|
+
protected readonly placeholder: import("@angular/core").Signal<string | null>;
|
|
3987
|
+
/** Width / height of the shown image: once loaded its own, before that its thumbnail's. */
|
|
3988
|
+
protected readonly ratio: import("@angular/core").Signal<number | null>;
|
|
3989
|
+
protected readonly frameClasses: import("@angular/core").Signal<"relative max-h-full max-w-full aspect-(--bf-image-viewer-ratio) w-[min(100cqw,calc(100cqh*var(--bf-image-viewer-ratio)))]" | "relative max-h-full max-w-full size-full">;
|
|
3990
|
+
protected readonly actionsContext: import("@angular/core").Signal<BfImageViewerActionsContext>;
|
|
3991
|
+
constructor();
|
|
3992
|
+
/** @internal Plays the open motion; called by `BfImageViewerService` as the overlay's enter. */
|
|
3993
|
+
enter(): Animation;
|
|
3994
|
+
/** @internal Plays the close motion; called by `BfImageViewerService` as the overlay's exit. */
|
|
3995
|
+
exit(): Animation;
|
|
3996
|
+
/** @internal An image loaded: it shows, and the frame takes its aspect ratio. */
|
|
3997
|
+
imageLoaded(event: Event, index: number): void;
|
|
3998
|
+
/** @internal An image failed: the frame shows the failure message. */
|
|
3999
|
+
imageFailed(index: number): void;
|
|
4000
|
+
/** @internal Arrow keys step (mirrored under rtl), Home and End jump to the ends. */
|
|
4001
|
+
keydown(event: KeyboardEvent): void;
|
|
4002
|
+
/** @internal A click on the scrim or around the image closes the viewer. */
|
|
4003
|
+
clicked(event: MouseEvent): void;
|
|
4004
|
+
/** The thumbnail of image `index`, when the opener gave one. */
|
|
4005
|
+
private originFor;
|
|
4006
|
+
private parts;
|
|
4007
|
+
private reduced;
|
|
4008
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BfImageViewerComponent, never>;
|
|
4009
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<BfImageViewerComponent, "bf-image-viewer", never, {}, {}, never, never, true, never>;
|
|
4010
|
+
}
|
|
4011
|
+
/**
|
|
4012
|
+
* Options of `BfImageViewerService.open()`.
|
|
4013
|
+
*
|
|
4014
|
+
* @summary Options of an image viewer: its images, the first one, its thumbnail and actions
|
|
4015
|
+
* @since 0.5.0
|
|
4016
|
+
*/
|
|
4017
|
+
interface BfImageViewerOptions {
|
|
4018
|
+
/** The images to step through, in order; at least one. */
|
|
4019
|
+
images: readonly BfImageViewerImage[];
|
|
4020
|
+
/**
|
|
4021
|
+
* Index of the image shown first, wrapped into the set.
|
|
4022
|
+
* @default 0
|
|
4023
|
+
*/
|
|
4024
|
+
index?: number;
|
|
4025
|
+
/**
|
|
4026
|
+
* The thumbnail the viewer zooms out of and back into (or a function returning the thumbnail
|
|
4027
|
+
* of an image by index); none fades the viewer in and out.
|
|
4028
|
+
*/
|
|
4029
|
+
origin?: BfImageViewerOrigin;
|
|
4030
|
+
/**
|
|
4031
|
+
* Actions under the image, beside its caption (a download link, a "Use this one" button); its
|
|
4032
|
+
* context is `{ $implicit: image, index, ref }`.
|
|
4033
|
+
*/
|
|
4034
|
+
actions?: TemplateRef<BfImageViewerActionsContext>;
|
|
4035
|
+
/** Accessible name of the viewer; empty uses `provideBfLabels()`'s `imageViewer`. */
|
|
4036
|
+
ariaLabel?: string;
|
|
4037
|
+
/**
|
|
4038
|
+
* A navigation to another URL path closes the viewer (default true).
|
|
4039
|
+
* @default true
|
|
4040
|
+
*/
|
|
4041
|
+
closeOnNavigation?: boolean;
|
|
4042
|
+
/**
|
|
4043
|
+
* Parent of the viewer's injector and source of its labels (default the root injector). Pass
|
|
4044
|
+
* the opener's `inject(Injector)` so a feature-level `provideBfLabels()` reaches the viewer.
|
|
4045
|
+
*/
|
|
4046
|
+
injector?: Injector;
|
|
4047
|
+
}
|
|
4048
|
+
/**
|
|
4049
|
+
* Opens a full-screen image viewer (a lightbox) on the overlay core: one image large over a dark
|
|
4050
|
+
* scrim, previous and next buttons, the arrow keys, Home and End to step through the set
|
|
4051
|
+
* (wrapping at both ends), a counter, the caption and optional actions. It zooms out of the
|
|
4052
|
+
* clicked thumbnail (`origin`) and back into it, cross-fades between images, and fades when there
|
|
4053
|
+
* is no thumbnail on screen; reduced motion only fades. It is a modal dialog: focus moves to its
|
|
4054
|
+
* close button and is trapped, `Escape`, the close button and a click on the scrim close it, the
|
|
4055
|
+
* page behind it is `inert` and does not scroll, and focus returns to the opener.
|
|
4056
|
+
*
|
|
4057
|
+
* @example
|
|
4058
|
+
* const ref = inject(BfImageViewerService).open({
|
|
4059
|
+
* images: shots.map((s) => ({ src: s.full, label: s.alt, caption: s.title })),
|
|
4060
|
+
* index: 2,
|
|
4061
|
+
* origin: (i) => thumbnails[i],
|
|
4062
|
+
* });
|
|
4063
|
+
* await ref.afterClosed;
|
|
4064
|
+
* @summary Opens a full-screen image viewer that zooms from a thumbnail and steps through a set
|
|
4065
|
+
* @since 0.5.0
|
|
4066
|
+
*/
|
|
4067
|
+
export declare class BfImageViewerService {
|
|
4068
|
+
private readonly overlays;
|
|
4069
|
+
private readonly injector;
|
|
4070
|
+
/**
|
|
4071
|
+
* Opens the viewer on `options.images`, showing `options.index` first.
|
|
4072
|
+
* @param options The images, the first index, the thumbnail, the actions and the injector.
|
|
4073
|
+
* @returns The viewer's ref.
|
|
4074
|
+
*/
|
|
4075
|
+
open(options: BfImageViewerOptions): BfImageViewerRef;
|
|
4076
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BfImageViewerService, never>;
|
|
4077
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
4078
|
+
}
|
|
4079
|
+
export { type BfComboboxFilter, type BfComboboxOption, type BfConfirmButton, type BfConfirmButtonRole, type BfConfirmOptions, type BfConfirmSize, type BfDateInputPicker, type BfDateTimeInputPicker, type BfDesktopToastConfig, type BfDesktopToastOptions, type BfDesktopToastPosition, type BfDialogConfig, type BfDialogRole, type BfDialogSize, type BfDialogTemplateContext, type BfImageViewerActionsContext, type BfImageViewerImage, type BfImageViewerOptions, type BfImageViewerOrigin, type BfMenuButtonVariant, type BfMenuPlacement, type BfOverlayAutoFocus, type BfOverlayController, type BfOverlayHost, type BfOverlayOptions, type BfOverlayPlacement, type BfOverlayPosition, type BfOverlayRole, type BfOverlayStackOptions, type BfOverlayTemplateContext, type BfPopoverPlacement, type BfSelectOption, type BfSidePanelConfig, type BfSidePanelTemplateContext, type BfSidePanelWidth, type BfStackedOverlay, type BfTimeInputHourCycle, type BfTimeInputPicker, type BfToastAction, type BfToastController, type BfToastDismissReason, type BfTooltipPlacement, type ɵBfToastHandle, type ɵBfToastPresenter, type ɵBfToastQueueOptions, type ɵBfToastRequest, type ɵBfToastView, labelPanelByHeading as ɵlabelPanelByHeading, watchPanelHeading as ɵwatchPanelHeading };
|