@forgeroute/ui 0.4.21 → 0.4.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeroute/ui",
3
- "version": "0.4.21",
3
+ "version": "0.4.22",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -660,12 +660,45 @@ export declare class BadgeComponent {
660
660
  };
661
661
  }, {}, never, never, true, never>;
662
662
  }
663
+ /**
664
+ * Round avatar: initials on a colour derived from them (default), or a photo when `imageUrl` is set. The photo falls back to the
665
+ * initials by itself when it fails to load (and tries again when `imageUrl` changes).
666
+ *
667
+ * <ui-avatar initials="JS" name="Jane Smith" [size]="72" [imageUrl]="photoUrl()" />
668
+ *
669
+ * Editable (a profile picture the user can change): `[editable]="true"` makes the avatar a keyboard button (role="button",
670
+ * tabindex 0, Enter / Space / click) that emits `editClick` — the host opens its file picker and uploads — with a small camera
671
+ * badge in the corner. `editLabel` is its name for assistive tech and tooltip (default "Change photo"). `[busy]="true"` while the
672
+ * upload runs: spinner in the badge, the photo is dimmed, `aria-busy` is set and clicks / keys do nothing.
673
+ *
674
+ * <ui-avatar initials="JS" name="Jane Smith" [size]="72" [imageUrl]="photoUrl()" [editable]="canEdit()" [busy]="uploading()" (editClick)="picker.open()" />
675
+ *
676
+ * Without `imageUrl` and `editable` nothing changes from the plain initials avatar.
677
+ */
663
678
  export declare class AvatarComponent {
664
679
  readonly initials: import("@angular/core").InputSignal<string>;
665
680
  readonly name: import("@angular/core").InputSignal<string>;
666
681
  readonly size: import("@angular/core").InputSignal<number>;
682
+ /** Photo URL. Empty / null = initials. A photo that fails to load falls back to the initials until the URL changes. */
683
+ readonly imageUrl: import("@angular/core").InputSignal<string | null | undefined>;
684
+ /** true = the avatar is a button that emits `editClick` (change the photo), with a camera badge. Default false: unchanged. */
685
+ readonly editable: import("@angular/core").InputSignal<boolean>;
686
+ /** Name of the editable avatar for assistive tech and the tooltip. */
687
+ readonly editLabel: import("@angular/core").InputSignal<string>;
688
+ /** The host is uploading: spinner badge, dimmed photo, aria-busy, no clicks. */
689
+ readonly busy: import("@angular/core").InputSignal<boolean>;
690
+ /** Fires on click / Enter / Space of an editable avatar (not while busy). */
691
+ readonly editClick: import("@angular/core").OutputEmitterRef<void>;
692
+ /** Fires when the photo could not be loaded (the initials are shown instead). */
693
+ readonly imageError: import("@angular/core").OutputEmitterRef<void>;
694
+ private readonly failedUrl;
695
+ protected readonly showImage: import("@angular/core").Signal<boolean>;
696
+ protected readonly badgeSize: import("@angular/core").Signal<number>;
667
697
  protected readonly bg: import("@angular/core").Signal<string>;
668
698
  protected readonly color: import("@angular/core").Signal<string>;
699
+ protected onImageError(): void;
700
+ protected onEdit(): void;
701
+ protected onKey(event: Event): void;
669
702
  static ɵfac: i0.ɵɵFactoryDeclaration<AvatarComponent, never>;
670
703
  static ɵcmp: i0.ɵɵComponentDeclaration<AvatarComponent, "ui-avatar", never, {
671
704
  "initials": {
@@ -683,7 +716,30 @@ export declare class AvatarComponent {
683
716
  "required": false;
684
717
  "isSignal": true;
685
718
  };
686
- }, {}, never, never, true, never>;
719
+ "imageUrl": {
720
+ "alias": "imageUrl";
721
+ "required": false;
722
+ "isSignal": true;
723
+ };
724
+ "editable": {
725
+ "alias": "editable";
726
+ "required": false;
727
+ "isSignal": true;
728
+ };
729
+ "editLabel": {
730
+ "alias": "editLabel";
731
+ "required": false;
732
+ "isSignal": true;
733
+ };
734
+ "busy": {
735
+ "alias": "busy";
736
+ "required": false;
737
+ "isSignal": true;
738
+ };
739
+ }, {
740
+ "editClick": "editClick";
741
+ "imageError": "imageError";
742
+ }, never, never, true, never>;
687
743
  }
688
744
  export interface MenuItem {
689
745
  type: string;
@@ -4215,6 +4271,11 @@ export declare class ConfirmOutletComponent implements OnInit, OnDestroy {
4215
4271
  static ɵfac: i0.ɵɵFactoryDeclaration<ConfirmOutletComponent, never>;
4216
4272
  static ɵcmp: i0.ɵɵComponentDeclaration<ConfirmOutletComponent, "ui-confirm-outlet", never, {}, {}, never, never, true, never>;
4217
4273
  }
4274
+ /**
4275
+ * Centered empty state: icon in a round tile, optional bold title, message and a projected action.
4276
+ * `iconType`: search, table, chart, users, person, message, email, task, house, money, star, video, shield, pipeline (funnel),
4277
+ * property (building), clipboard (clipboard with check and lines), document (default; any unknown value also draws it).
4278
+ */
4218
4279
  export declare class EmptyStateComponent {
4219
4280
  readonly message: import("@angular/core").InputSignal<string>;
4220
4281
  readonly title: import("@angular/core").InputSignal<string>;
@@ -6276,6 +6337,11 @@ export interface NoteItem {
6276
6337
  createdAt: string;
6277
6338
  updatedAt: string;
6278
6339
  }
6340
+ /**
6341
+ * Longest note body, in characters, counted AFTER trimming. Matches the backend `NoteController` cap (10000 after trim; the server trims first,
6342
+ * so leading / trailing spaces never count). The add box and the edit box block Add Note / Save above it and show "Too long (max 10000 characters).".
6343
+ */
6344
+ export declare const NOTES_MAX_LENGTH = 10000;
6279
6345
  /**
6280
6346
  * Notes for one record: a soft "Add a note" panel, then one clean card per note (author avatar, name, date, edit / delete icons, the text),
6281
6347
  * inline edit and a delete confirmation. Notes are listed 5 per page in the server's order. It talks to the notes API itself, so a page only names the record:
@@ -6290,6 +6356,8 @@ export interface NoteItem {
6290
6356
  *
6291
6357
  * `readOnly` lists the notes only (no box, no edit / delete). `totalChange` emits the total after every load. Failures show a
6292
6358
  * library toast with the server's message. Put it in a `ui-detail-card`: the card's body padding is the only outer inset.
6359
+ * A note may hold at most `NOTES_MAX_LENGTH` (10000) characters after trimming; longer text (typed or pasted) shows the field's
6360
+ * "Too long" message at once and Add Note / Save stay disabled, so no request is sent.
6293
6361
  * Pagination is the library `ui-pagination` (shown only above one page). Cmd/Ctrl+Enter in the add box adds the note.
6294
6362
  */
6295
6363
  export declare class NotesComponent {
@@ -6305,6 +6373,8 @@ export declare class NotesComponent {
6305
6373
  private readonly destroyRef;
6306
6374
  private readonly apiBase;
6307
6375
  readonly pageSize = 5;
6376
+ /** The character limit of a note (see `NOTES_MAX_LENGTH`). */
6377
+ readonly maxLength = 10000;
6308
6378
  readonly notes: import("@angular/core").WritableSignal<NoteItem[]>;
6309
6379
  readonly loading: import("@angular/core").WritableSignal<boolean>;
6310
6380
  readonly saving: import("@angular/core").WritableSignal<boolean>;
@@ -6317,6 +6387,10 @@ export declare class NotesComponent {
6317
6387
  editBody: string;
6318
6388
  /** Up to two initials of the author's name for the avatar ("Ana Lopez" -> "AL"); "Y" for the current user's own unnamed notes. */
6319
6389
  protected initials(name: string): string;
6390
+ /** True when the trimmed text is longer than the limit. */
6391
+ protected tooLong(text: string): boolean;
6392
+ /** True when the trimmed text is not empty and within the limit. */
6393
+ protected validBody(text: string): boolean;
6320
6394
  private get listUrl();
6321
6395
  constructor();
6322
6396
  loadPage(p: number): void;
@@ -6821,6 +6895,11 @@ export declare class PanelInfoListComponent {
6821
6895
  * Default false = the label and value as before.
6822
6896
  */
6823
6897
  readonly labelColon: import("@angular/core").InputSignal<boolean>;
6898
+ /**
6899
+ * The list stretches to the height of its container (a grid cell or flex item with a definite height), so lists side by side in
6900
+ * one grid row end at the same height; with one section, that section's box fills the height. Default false = as tall as its content.
6901
+ */
6902
+ readonly fill: import("@angular/core").InputSignal<boolean>;
6824
6903
  readonly displaySections: import("@angular/core").Signal<PanelInfoSection[]>;
6825
6904
  /**
6826
6905
  * The safe href of an item, or null: `href` first, else `mailto:`/`tel:` built from `email`/`phone`. Only mailto, tel, http and https
@@ -6848,6 +6927,11 @@ export declare class PanelInfoListComponent {
6848
6927
  "required": false;
6849
6928
  "isSignal": true;
6850
6929
  };
6930
+ "fill": {
6931
+ "alias": "fill";
6932
+ "required": false;
6933
+ "isSignal": true;
6934
+ };
6851
6935
  }, {}, never, never, true, never>;
6852
6936
  }
6853
6937
  /**
@@ -7363,6 +7447,8 @@ export interface TimelineItem {
7363
7447
  * { id: 'b', title: 'Letter sent', description: 'Mailed to the owner.', tone: 'success', icon: 'email' },
7364
7448
  * ]" />
7365
7449
  *
7450
+ * `groupByDay` adds a heading per calendar day (see the inputs `groupByDay`, `timeZone`, `now`, `dayHeadingLevel`).
7451
+ *
7366
7452
  * Semantics: `<ol>` / `<li>`; the line and dots are decorative (aria-hidden). `time` is the visible text; `dateTime` goes into
7367
7453
  * `<time datetime>`. With no items, `emptyMessage` (if set) is shown as a hint, otherwise nothing is rendered.
7368
7454
  */
@@ -7376,6 +7462,26 @@ export declare class TimelineComponent {
7376
7462
  readonly maxHeight: import("@angular/core").InputSignal<string>;
7377
7463
  /** `below` (default): the time is under the title / description. `end`: the time sits right-aligned on the title row. */
7378
7464
  readonly timePosition: import("@angular/core").InputSignal<"end" | "below">;
7465
+ /**
7466
+ * Group the items under a heading per calendar day of `dateTime` ("Today", "Yesterday", "Oct 3", "Oct 3, 2025"). Default false = no headings,
7467
+ * DOM unchanged. The given order is kept: consecutive items of one day share a heading, the same day appearing again later starts a new group.
7468
+ * An item without a parseable ISO `dateTime` joins the group it follows (a heading-less group at the top when first).
7469
+ * Grouped markup: `<ol class="tl"><li class="tl-day-group"><div class="tl-day" role="heading" aria-level>…</div><ol class="tl-sub">…items…</ol></li></ol>`.
7470
+ */
7471
+ readonly groupByDay: import("@angular/core").InputSignal<boolean>;
7472
+ /** IANA time zone (e.g. `America/Chicago`) for the day grouping and the labels. A `dateTime` with a trailing Z / offset = an instant shown in this zone; a date or a wall-clock time without offset is taken as already being in that day. Empty (default) = the browser's local zone; an unknown zone also falls back to it. */
7473
+ readonly timeZone: import("@angular/core").InputSignal<string>;
7474
+ /** The moment "Today" / "Yesterday" are measured from. `null` (default) = the real current time; a Date or ISO string pins it (tests, replays). The real time is read when the groups are computed, not on a timer: a long-lived page should pass `now` (or re-bind `items`) to refresh Today / Yesterday after midnight. */
7475
+ readonly now: import("@angular/core").InputSignal<string | Date | null>;
7476
+ /** Heading level 1-6 of the day headings (role="heading" + aria-level); anything else becomes 3. */
7477
+ readonly dayHeadingLevel: import("@angular/core").InputSignal<number>;
7478
+ protected readonly headingLevel: import("@angular/core").Signal<number>;
7479
+ /** The items split into day groups (only used when `groupByDay` is on). */
7480
+ protected readonly groups: import("@angular/core").Signal<{
7481
+ key: string;
7482
+ label: string;
7483
+ items: TimelineItem[];
7484
+ }[]>;
7379
7485
  /** Solid dot colour of an item's `dotVariant`, or null (then `tone` colours it). */
7380
7486
  dotColor(item: TimelineItem): string | null;
7381
7487
  static ɵfac: i0.ɵɵFactoryDeclaration<TimelineComponent, never>;
@@ -7405,6 +7511,26 @@ export declare class TimelineComponent {
7405
7511
  "required": false;
7406
7512
  "isSignal": true;
7407
7513
  };
7514
+ "groupByDay": {
7515
+ "alias": "groupByDay";
7516
+ "required": false;
7517
+ "isSignal": true;
7518
+ };
7519
+ "timeZone": {
7520
+ "alias": "timeZone";
7521
+ "required": false;
7522
+ "isSignal": true;
7523
+ };
7524
+ "now": {
7525
+ "alias": "now";
7526
+ "required": false;
7527
+ "isSignal": true;
7528
+ };
7529
+ "dayHeadingLevel": {
7530
+ "alias": "dayHeadingLevel";
7531
+ "required": false;
7532
+ "isSignal": true;
7533
+ };
7408
7534
  }, {}, never, never, true, never>;
7409
7535
  }
7410
7536
  /**
@@ -9052,12 +9178,24 @@ export interface BoardCardContext<T = unknown> {
9052
9178
  $implicit: T;
9053
9179
  }>;
9054
9180
  }
9055
- /** Marks the template that renders the INSIDE of a card (the board draws the card frame, menu and drag handling). */
9181
+ /**
9182
+ * Marks the template that renders the INSIDE of a card (the board draws the card frame, menu and drag handling).
9183
+ * Bind the board's columns to type the card item: `<ng-template [uiBoardCard]="columns()" let-lead>` gives `lead` the
9184
+ * columns' item type. The bare `<ng-template uiBoardCard let-item>` still works; `item` is then `unknown`.
9185
+ */
9056
9186
  export declare class BoardCardDirective<T = unknown> {
9187
+ /** Only used to infer the item type in the template; the value is never read. */
9188
+ readonly typeFrom: import("@angular/core").InputSignal<"" | BoardColumn<T>[]>;
9057
9189
  readonly template: TemplateRef<BoardCardContext<T>>;
9058
9190
  static ngTemplateContextGuard<T>(_dir: BoardCardDirective<T>, _ctx: unknown): _ctx is BoardCardContext<T>;
9059
9191
  static ɵfac: i0.ɵɵFactoryDeclaration<BoardCardDirective<any>, never>;
9060
- static ɵdir: i0.ɵɵDirectiveDeclaration<BoardCardDirective<any>, "ng-template[uiBoardCard]", never, {}, {}, never, never, true, never>;
9192
+ static ɵdir: i0.ɵɵDirectiveDeclaration<BoardCardDirective<any>, "ng-template[uiBoardCard]", never, {
9193
+ "typeFrom": {
9194
+ "alias": "uiBoardCard";
9195
+ "required": false;
9196
+ "isSignal": true;
9197
+ };
9198
+ }, {}, never, never, true, never>;
9061
9199
  }
9062
9200
  /**
9063
9201
  * Kanban board: columns of cards that can be dragged between columns. Data and saving stay with the host.
@@ -9065,7 +9203,7 @@ export declare class BoardCardDirective<T = unknown> {
9065
9203
  * <ui-board [columns]="columns()" [itemKey]="key" [itemLabel]="label" [cardActions]="actions" [readOnly]="perm() !== 'full'"
9066
9204
  * [loading]="loading()" [error]="error()" (retry)="load()"
9067
9205
  * (cardClick)="open($event)" (cardAction)="onAction($event)" (itemMove)="onMove($event)">
9068
- * <ng-template uiBoardCard let-deal let-menu="menu">
9206
+ * <ng-template [uiBoardCard]="columns()" let-deal let-menu="menu">
9069
9207
  * <div class="ub-card__top"><span class="ub-card__title">{{ deal.title }}</span>
9070
9208
  * <ng-container [ngTemplateOutlet]="menu" [ngTemplateOutletContext]="{ $implicit: deal }" /></div>
9071
9209
  * <div class="ub-card__contact">{{ deal.contactName }}</div>
@@ -9101,21 +9239,42 @@ export declare class BoardComponent<T = unknown> {
9101
9239
  readonly itemNoun: import("@angular/core").InputSignal<string>;
9102
9240
  readonly itemNounPlural: import("@angular/core").InputSignal<string>;
9103
9241
  readonly retryLabel: import("@angular/core").InputSignal<string>;
9242
+ /**
9243
+ * Cards drawn per column at first, and added by each "Show more" click (0 = draw every card). The board loads every item
9244
+ * at once, so drawing only a page of each column keeps the first paint fast however many items there are. Column counts
9245
+ * and summaries still cover every item; a card moved into a column is drawn at its top, so it is always on screen.
9246
+ */
9247
+ readonly pageSize: import("@angular/core").InputSignal<number>;
9104
9248
  readonly cardClick: import("@angular/core").OutputEmitterRef<T>;
9105
9249
  readonly cardAction: import("@angular/core").OutputEmitterRef<BoardCardActionEvent<T>>;
9106
9250
  readonly itemMove: import("@angular/core").OutputEmitterRef<BoardMoveEvent<T>>;
9107
9251
  readonly retry: import("@angular/core").OutputEmitterRef<void>;
9108
- protected readonly card: import("@angular/core").Signal<BoardCardDirective<any> | undefined>;
9252
+ protected readonly card: import("@angular/core").Signal<BoardCardDirective<T> | undefined>;
9109
9253
  /** The columns as shown: the host's value, plus any move not yet replaced by new data. */
9110
9254
  protected readonly cols: import("@angular/core").WritableSignal<BoardColumn<T>[]>;
9255
+ /** Cards drawn per column. Kept when the host re-sends columns (a saved move, a search), so the board never jumps back; back to the first page on a reload (`loading`). */
9256
+ private readonly drawn;
9257
+ /** The card the user last moved and where it went: it stays drawn even if the host re-sends it far down the column. */
9258
+ private readonly movedTo;
9259
+ protected readonly shownCols: import("@angular/core").Signal<{
9260
+ col: BoardColumn<T>;
9261
+ shown: T[];
9262
+ hidden: number;
9263
+ next: number;
9264
+ }[]>;
9265
+ /** How many cards of `col` are drawn: the pages shown so far, extended so the card the user moved is always on screen. */
9266
+ private limitOf;
9267
+ protected showMore(key: string): void;
9268
+ /** Id of the keyboard-move hint that describes the board region. */
9269
+ protected readonly hintId: string;
9111
9270
  protected readonly overKey: import("@angular/core").WritableSignal<string | null>;
9112
9271
  protected readonly draggingKey: import("@angular/core").WritableSignal<string | null>;
9113
9272
  protected readonly announcement: import("@angular/core").WritableSignal<string>;
9114
9273
  private readonly host;
9274
+ constructor();
9115
9275
  private drag;
9116
9276
  protected readonly skeletonColumns: import("@angular/core").Signal<number[]>;
9117
9277
  protected readonly canDrag: import("@angular/core").Signal<boolean>;
9118
- protected readonly canMoveAny: import("@angular/core").Signal<boolean>;
9119
9278
  protected dot(color?: string): string;
9120
9279
  protected onDragStart(event: DragEvent, item: T, col: BoardColumn<T>): void;
9121
9280
  protected onDragEnd(): void;
@@ -9202,6 +9361,11 @@ export declare class BoardComponent<T = unknown> {
9202
9361
  "required": false;
9203
9362
  "isSignal": true;
9204
9363
  };
9364
+ "pageSize": {
9365
+ "alias": "pageSize";
9366
+ "required": false;
9367
+ "isSignal": true;
9368
+ };
9205
9369
  }, {
9206
9370
  "cardClick": "cardClick";
9207
9371
  "cardAction": "cardAction";
@@ -9809,6 +9973,103 @@ export declare class StackComponent {
9809
9973
  };
9810
9974
  }, {}, never, ["*"], true, never>;
9811
9975
  }
9976
+ export type SidebarPosition = 'start' | 'end';
9977
+ /** Viewport width at and below which the layout becomes one column: sm = 640px, md = 900px, lg = 1200px, never = always two columns. */
9978
+ export type SidebarCollapse = 'sm' | 'md' | 'lg' | 'never';
9979
+ /**
9980
+ * Detail-page layout: a MAIN column plus a SIDE column of fixed width.
9981
+ *
9982
+ * Replaces the page-level grid / `position: sticky` CSS each detail page used to carry. Project the two columns with
9983
+ * the `layout-main` and `layout-side` attributes:
9984
+ *
9985
+ * <ui-sidebar-layout sideWidth="340px" gap="md" collapseAt="md">
9986
+ * <div layout-main> ...tabs, tables, timeline... </div>
9987
+ * <aside layout-side aria-label="Contact summary"> ...profile card, quick actions... </aside>
9988
+ * </ui-sidebar-layout>
9989
+ *
9990
+ * - `sideWidth`: any CSS length (default `320px`). The main column takes the rest (`minmax(0, 1fr)` track and
9991
+ * `min-width: 0`, so a wide table cannot stretch the grid).
9992
+ * - `sidePosition`: `end` (default, side on the right) | `start` (side on the left). The DOM order is always main then
9993
+ * side; only the visual position changes.
9994
+ * - `gap`: layout gap token (none | xs | sm | md | lg | xl) or a CSS length. Default `md` (16px). It is the space between
9995
+ * the columns and, when collapsed, between the stacked columns.
9996
+ * - `stickySide` (default true): at wide widths the side column is `position: sticky` at `stickyTop` px (default 16) with
9997
+ * `max-height: 100vh - (stickyTop + stickyOffset)` (default offset 32px; `100vh` first, `100dvh` after it for browsers
9998
+ * that know it) and `overflow-y: auto`, so only the main column scrolls the page; a side column taller than the viewport
9999
+ * scrolls inside itself. `false` = a plain static column.
10000
+ * - `collapseAt`: sm (640px) | md (900px, default) | lg (1200px) | never. At and below that viewport width there is ONE
10001
+ * column and the side column is static (never sticky, no max-height). `sideFirstWhenCollapsed` (default true) puts the
10002
+ * side column first there; `false` puts the main column first.
10003
+ * - An empty side slot (no `layout-side` element) hides the side column and the main column takes the full width.
10004
+ *
10005
+ * Plain media queries only (no `:has()`, no container queries) so it behaves the same in Chrome, Edge, Firefox and Safari.
10006
+ * The column gap is a margin on the side column (not a grid `column-gap`), so an empty side column leaves no stray gap.
10007
+ */
10008
+ export declare class SidebarLayoutComponent {
10009
+ /** Width of the side column: any CSS length (default `320px`). */
10010
+ readonly sideWidth: import("@angular/core").InputSignal<string>;
10011
+ readonly sidePosition: import("@angular/core").InputSignal<SidebarPosition>;
10012
+ /** Space between the columns (and between them when collapsed): a layout gap token or a CSS length (default `md` = 16px). */
10013
+ readonly gap: import("@angular/core").InputSignal<string>;
10014
+ /** Keep the side column pinned while the main column scrolls (wide widths only). */
10015
+ readonly stickySide: import("@angular/core").InputSignal<boolean>;
10016
+ /** Distance in px from the top of the viewport at which the side column sticks (default 16). */
10017
+ readonly stickyTop: import("@angular/core").InputSignal<number>;
10018
+ /** Total px of non-viewport space above and below the side column, used for its max-height (default 32). */
10019
+ readonly stickyOffset: import("@angular/core").InputSignal<number>;
10020
+ readonly collapseAt: import("@angular/core").InputSignal<SidebarCollapse>;
10021
+ /** When collapsed to one column: side column first (default) or main column first. */
10022
+ readonly sideFirstWhenCollapsed: import("@angular/core").InputSignal<boolean>;
10023
+ protected readonly position: import("@angular/core").Signal<SidebarPosition>;
10024
+ protected readonly sideCss: import("@angular/core").Signal<string>;
10025
+ protected readonly gapCss: import("@angular/core").Signal<string>;
10026
+ protected readonly topCss: import("@angular/core").Signal<string>;
10027
+ protected readonly offCss: import("@angular/core").Signal<string>;
10028
+ protected readonly rootClass: import("@angular/core").Signal<string>;
10029
+ static ɵfac: i0.ɵɵFactoryDeclaration<SidebarLayoutComponent, never>;
10030
+ static ɵcmp: i0.ɵɵComponentDeclaration<SidebarLayoutComponent, "ui-sidebar-layout", never, {
10031
+ "sideWidth": {
10032
+ "alias": "sideWidth";
10033
+ "required": false;
10034
+ "isSignal": true;
10035
+ };
10036
+ "sidePosition": {
10037
+ "alias": "sidePosition";
10038
+ "required": false;
10039
+ "isSignal": true;
10040
+ };
10041
+ "gap": {
10042
+ "alias": "gap";
10043
+ "required": false;
10044
+ "isSignal": true;
10045
+ };
10046
+ "stickySide": {
10047
+ "alias": "stickySide";
10048
+ "required": false;
10049
+ "isSignal": true;
10050
+ };
10051
+ "stickyTop": {
10052
+ "alias": "stickyTop";
10053
+ "required": false;
10054
+ "isSignal": true;
10055
+ };
10056
+ "stickyOffset": {
10057
+ "alias": "stickyOffset";
10058
+ "required": false;
10059
+ "isSignal": true;
10060
+ };
10061
+ "collapseAt": {
10062
+ "alias": "collapseAt";
10063
+ "required": false;
10064
+ "isSignal": true;
10065
+ };
10066
+ "sideFirstWhenCollapsed": {
10067
+ "alias": "sideFirstWhenCollapsed";
10068
+ "required": false;
10069
+ "isSignal": true;
10070
+ };
10071
+ }, {}, never, ["[layout-main]", "[layout-side]"], true, never>;
10072
+ }
9812
10073
  export type ActionBarAlign = 'start' | 'center' | 'end' | 'between';
9813
10074
  /**
9814
10075
  * Bar for page-level actions (Save / Cancel) that stays at the bottom of the scrolling area.