@forgeroute/ui 0.4.68 → 0.4.69

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.68",
3
+ "version": "0.4.69",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -115,7 +115,7 @@ export declare class TemplatePickerComponent {
115
115
  private readonly host;
116
116
  private readonly search$;
117
117
  /** Filter results to a specific channel: 'email', 'text', or omit for all. */
118
- readonly channel: import("@angular/core").InputSignal<"" | "email" | "text">;
118
+ readonly channel: import("@angular/core").InputSignal<"" | "text" | "email">;
119
119
  readonly selectedId: import("@angular/core").InputSignal<string | null>;
120
120
  readonly label: import("@angular/core").InputSignal<string>;
121
121
  /** Shows the red required asterisk (same as the library inputs) — e.g. when a template must be picked to send. */
@@ -543,7 +543,7 @@ export declare class DocumentSendOptionsComponent implements UiFieldValidity {
543
543
  /** API root from FORGEROUTE_CONFIG (e.g. a cross-origin prod API); falls back to same-origin `/api`. */
544
544
  private readonly apiBase;
545
545
  /** `email` → purpose select + attachment allowed; `text` → link only (purpose fixed to e-signature). */
546
- readonly channel: import("@angular/core").InputSignal<"email" | "text">;
546
+ readonly channel: import("@angular/core").InputSignal<"text" | "email">;
547
547
  readonly label: import("@angular/core").InputSignal<string>;
548
548
  /** When true, at least one document must be chosen. The message forms leave it false: documents are optional there. */
549
549
  readonly required: import("@angular/core").InputSignal<boolean>;
@@ -608,7 +608,7 @@ export declare class DocumentSendOptionsComponent implements UiFieldValidity {
608
608
  /** Roles of documents whose row had no `signerRoles` and that the host resolves (`signers().resolveRoles`). */
609
609
  readonly roleStates: import("@angular/core").WritableSignal<Record<string, RoleState>>;
610
610
  /** The envelope's documents: `loading` / `error` while the panel reads them (`loadDocuments`), `ready` once known. */
611
- readonly envelopeStatus: import("@angular/core").WritableSignal<"idle" | "loading" | "ready" | "error">;
611
+ readonly envelopeStatus: import("@angular/core").WritableSignal<"error" | "loading" | "ready" | "idle">;
612
612
  private envelopeSub;
613
613
  private readonly roleSubs;
614
614
  /** The sender opened the collapsed "Signing options" line. */
@@ -1997,7 +1997,7 @@ export declare class SendMessagePanelComponent {
1997
1997
  readonly activeContact: import("@angular/core").WritableSignal<MessageContact | null>;
1998
1998
  /** What the sender should know about the picked contact before sending (why a channel is missing, what to add). */
1999
1999
  readonly contactNotices: import("@angular/core").Signal<string[]>;
2000
- readonly channel: import("@angular/core").WritableSignal<"email" | "text">;
2000
+ readonly channel: import("@angular/core").WritableSignal<"text" | "email">;
2001
2001
  readonly valid: import("@angular/core").WritableSignal<boolean>;
2002
2002
  /** Bumped on every fresh open / new contact — re-creates the email and text forms so no draft carries over. */
2003
2003
  readonly formEpoch: import("@angular/core").WritableSignal<number>;
@@ -1300,7 +1300,7 @@ export declare class StripeConnectComponent {
1300
1300
  readonly navigateTab: import("@angular/core").InputSignal<((url: string) => void) | null>;
1301
1301
  protected readonly visible: import("@angular/core").Signal<boolean>;
1302
1302
  /** Which screen the card shows. */
1303
- protected readonly state: import("@angular/core").Signal<"none" | "complete" | "verifying" | "incomplete">;
1303
+ protected readonly state: import("@angular/core").Signal<"complete" | "verifying" | "incomplete" | "none">;
1304
1304
  /** What the persistent status region says: the current state, plus "Loading." while a request runs. Empty while nothing is shown. */
1305
1305
  protected readonly liveText: import("@angular/core").Signal<string>;
1306
1306
  /** The user pressed a button that started a request: when the screen then changes, focus moves to the new screen (the pressed button is gone). */
@@ -2,7 +2,7 @@ import * as i0 from "@angular/core";
2
2
  import { EnvironmentProviders, InjectionToken, OnDestroy, OnInit, Signal, TemplateRef, WritableSignal } from "@angular/core";
3
3
  import { UrlTree } from "@angular/router";
4
4
  import { Observable } from "rxjs";
5
- import { AbstractControl, ControlValueAccessor, FormControl, ValidationErrors, Validator } from "@angular/forms";
5
+ import { AbstractControl, ControlValueAccessor, FormControl, ValidationErrors, Validator, ValidatorFn } from "@angular/forms";
6
6
  import { HttpInterceptorFn } from "@angular/common/http";
7
7
  import { SafeHtml } from "@angular/platform-browser";
8
8
  export interface ForgerouteConfig {
@@ -2407,6 +2407,8 @@ export declare class ToastService implements OnDestroy {
2407
2407
  private _remaining;
2408
2408
  private _paused;
2409
2409
  show(msg: string, duration?: number): void;
2410
+ /** Green success toast, the explicit name for `show()` (same type, same 3000ms default, same behaviour). */
2411
+ success(msg: string, duration?: number): void;
2410
2412
  /** Neutral (blue) toast for a result that is neither a success nor a failure, e.g. "No changes to save.". */
2411
2413
  info(msg: string, duration?: number): void;
2412
2414
  error(msg: string, duration?: number): void;
@@ -3965,7 +3967,7 @@ export declare class ButtonComponent {
3965
3967
  * `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
3966
3968
  * background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
3967
3969
  */
3968
- readonly variant: import("@angular/core").InputSignal<"link" | "primary" | "secondary" | "danger" | "warning" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3970
+ readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3969
3971
  /** Renders an anchor to this route instead of a button (use with `variant="link"` for an inline text link). `['/settings']` or `'/settings'`. While `disabled` or `loading` it renders a non-clickable `<span role="link" aria-disabled>` with no href (like `href`). */
3970
3972
  readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
3971
3973
  /** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
@@ -4011,7 +4013,7 @@ export declare class ButtonComponent {
4011
4013
  readonly color: import("@angular/core").InputSignal<string | undefined>;
4012
4014
  readonly active: import("@angular/core").InputSignal<boolean>;
4013
4015
  readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xs">;
4014
- readonly type: import("@angular/core").InputSignal<"button" | "reset" | "submit">;
4016
+ readonly type: import("@angular/core").InputSignal<"reset" | "submit" | "button">;
4015
4017
  readonly disabled: import("@angular/core").InputSignal<boolean>;
4016
4018
  readonly loading: import("@angular/core").InputSignal<boolean>;
4017
4019
  readonly fullWidth: import("@angular/core").InputSignal<boolean>;
@@ -4283,9 +4285,9 @@ export interface ContactLookup {
4283
4285
  email: string | null;
4284
4286
  smsOptedIn: boolean;
4285
4287
  }
4286
- declare function formatPhone(raw: string | null | undefined): string;
4288
+ declare function formatPhone$1(raw: string | null | undefined): string;
4287
4289
  export declare class ContactPickerComponent {
4288
- readonly formatPhone: typeof formatPhone;
4290
+ readonly formatPhone: typeof formatPhone$1;
4289
4291
  readonly label: import("@angular/core").InputSignal<string>;
4290
4292
  readonly placeholder: import("@angular/core").InputSignal<string>;
4291
4293
  /** Helper text under the picker (linked to the search input via aria-describedby). */
@@ -4959,7 +4961,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4959
4961
  * `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
4960
4962
  * It only picks the keyboard; it does not restrict what can be typed or pasted.
4961
4963
  */
4962
- readonly inputmode: import("@angular/core").InputSignal<"" | "search" | "none" | "text" | "email" | "tel" | "url" | "decimal" | "numeric">;
4964
+ readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
4963
4965
  readonly readonly: import("@angular/core").InputSignal<boolean>;
4964
4966
  readonly hint: import("@angular/core").InputSignal<string>;
4965
4967
  /** Id(s) of an external element that also describes this control (e.g. one shared error text for a group of fields). Space separated; MERGED after the control's own hint / error id in `aria-describedby`, never replacing it. Empty = unchanged. */
@@ -5216,6 +5218,26 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
5216
5218
  "invalidChange": "invalidChange";
5217
5219
  }, never, ["[uiLabelEnd]"], true, never>;
5218
5220
  }
5221
+ /** Longest password the apps' servers accept (128 characters); use it as the password input's `maxlength`. */
5222
+ export declare const PASSWORD_MAX_LENGTH = 128;
5223
+ /**
5224
+ * Policy of servers that accept only these special characters: 8+ characters, an uppercase letter, a lowercase letter, a digit and one of
5225
+ * `@ $ ! % * ? & #`. (Anything else, e.g. `^` or a space, does NOT count as the special character.)
5226
+ */
5227
+ export declare const LISTED_SPECIAL_PASSWORD_RULES: readonly PasswordRule[];
5228
+ /**
5229
+ * Policy of servers that accept any ASCII symbol as the special character (character codes 33-126 that are not letters or digits): 8+ characters,
5230
+ * an uppercase letter, a lowercase letter, a digit and one ASCII symbol. A space and non-ASCII characters (e.g. `é`) do NOT count.
5231
+ */
5232
+ export declare const ASCII_SPECIAL_PASSWORD_RULES: readonly PasswordRule[];
5233
+ /**
5234
+ * A form validator for a sign-up / reset-password control: the value must satisfy every rule and be at most `maxLength` characters. The error key
5235
+ * is `passwordRules` (value `true`). A null / undefined value counts as an empty string (so it fails the rules; combine with `Validators.required`
5236
+ * when an empty field should show a different message).
5237
+ *
5238
+ * password = new FormControl('', [createPasswordPolicyValidator(LISTED_SPECIAL_PASSWORD_RULES)]);
5239
+ */
5240
+ export declare function createPasswordPolicyValidator(rules: readonly PasswordRule[], maxLength?: number): ValidatorFn;
5219
5241
  /**
5220
5242
  * Number pad for short numeric codes such as a PIN. Shows one dot per allowed digit (filled as digits are entered) above a 3x4 grid of
5221
5243
  * 44px+ touch targets. The value is the digit string (`''` = nothing entered); it works with `[(value)]` and with `ngModel` / `FormControl`.
@@ -6495,7 +6517,7 @@ export declare class DropdownComponent {
6495
6517
  readonly loader: import("@angular/core").InputSignal<(() => Promise<DropdownItem[]>) | null>;
6496
6518
  readonly active: import("@angular/core").InputSignal<boolean>;
6497
6519
  readonly activeValue: import("@angular/core").InputSignal<string>;
6498
- readonly variant: import("@angular/core").InputSignal<"button" | "badge">;
6520
+ readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
6499
6521
  /** Trigger size for `variant="button"`: `sm` (default, the compact toolbar look) or `md` (same padding and type as a medium `ui-button`). */
6500
6522
  readonly size: import("@angular/core").InputSignal<"sm" | "md">;
6501
6523
  readonly menuWidth: import("@angular/core").InputSignal<string>;
@@ -8048,6 +8070,39 @@ export interface UsStateOption {
8048
8070
  label: string;
8049
8071
  }
8050
8072
  export declare const US_STATES: UsStateOption[];
8073
+ /**
8074
+ * The 50 US states (no DC) with their major cities, keyed by two-letter state code: `US_LOCATIONS['TX']` -> `['Abilene', ...]`. Cities are unique and
8075
+ * trimmed per state. Use it for a city picker that follows a state select (the state names are in `US_STATES`).
8076
+ */
8077
+ export declare const US_LOCATIONS: Record<string, string[]>;
8078
+ /**
8079
+ * Look of the record-card groups on detail pages (the section header's title, icon and tint), so groups that exist in several apps look identical.
8080
+ * Icon names are from the library's icon list; `background` is the section header's own light tint.
8081
+ *
8082
+ * const GROUPS = { ...COMMON_DETAIL_GROUP_STYLES, deals: { title: 'Deals & Money', icon: 'opportunity', background: '#ecfdf5' } };
8083
+ */
8084
+ export interface DetailGroupStyle {
8085
+ title: string;
8086
+ icon: string;
8087
+ background: string;
8088
+ }
8089
+ /** The groups every app's detail pages share (the same title, icon and tint everywhere). An app adds its own groups next to these. */
8090
+ export declare const COMMON_DETAIL_GROUP_STYLES: {
8091
+ readonly activity: {
8092
+ readonly title: "Activity";
8093
+ readonly icon: "message";
8094
+ readonly background: "#eff6ff";
8095
+ };
8096
+ readonly notes: {
8097
+ readonly title: "Notes";
8098
+ readonly icon: "add-note";
8099
+ readonly background: "#f1f5f9";
8100
+ };
8101
+ };
8102
+ /** Header background of every record card on the detail pages (bound as the library card's `headerBackground`). */
8103
+ export declare const DETAIL_CARD_HEADER_BG = "#f8fafc";
8104
+ /** Light blue behind every group section header on the detail pages (large header with an icon tile and a description). */
8105
+ export declare const DETAIL_GROUP_HEADER_BG = "#eaf3ff";
8051
8106
  export interface NavLink {
8052
8107
  label: string;
8053
8108
  route: string;
@@ -11374,6 +11429,26 @@ declare function layoutLanes(boxes: {
11374
11429
  top: number;
11375
11430
  height: number;
11376
11431
  }[]): Record<string, CalendarLane>;
11432
+ /** A heading shared by consecutive agenda days (`ui-calendar` `agendaGroupFn`). Days that return the same `key` one after another sit under one heading. */
11433
+ interface CalendarAgendaGroup {
11434
+ key: string;
11435
+ label: string;
11436
+ }
11437
+ /**
11438
+ * Ready-made `agendaGroupFn` for `ui-calendar`: Overdue (before `todayStr`), Today, Tomorrow, This Week (the rest of the current Sunday-first
11439
+ * week) and Later (everything after). Pure `YYYY-MM-DD` string math (a day is added with the local `Date(y, m, d + n)` constructor, so a daylight
11440
+ * saving change never shifts it); nothing parses a non-ISO string. A `todayStr` that is not a real day, or a day that is not a real
11441
+ * `YYYY-MM-DD`, gives `null` (no heading) instead of a wrong group.
11442
+ *
11443
+ * readonly group = computed(() => periodGroup(this.todayIso())); // <ui-calendar [agendaGroupFn]="group()" />
11444
+ */
11445
+ export declare function periodGroup(todayStr: string): (dateStr: string) => CalendarAgendaGroup | null;
11446
+ /** Level of a day's decoration (`ui-calendar` `dayDecorationFn`), lowest to highest. */
11447
+ type CalendarDayLevel = 'low' | 'medium' | 'high' | 'critical';
11448
+ /** What a screen reader hears for a decorated day (added to the cell's label, and shown as hidden text in the week view header). */
11449
+ declare const DAY_LEVEL_TEXT: Record<CalendarDayLevel, string>;
11450
+ /** True for the four known levels (an unknown string from a loosely typed host is ignored, not drawn). */
11451
+ declare function isDayLevel(level: unknown): level is CalendarDayLevel;
11377
11452
  /** One thing on the calendar. The host maps its own records to this shape. */
11378
11453
  export interface CalendarItem {
11379
11454
  /** Unique across ALL items passed in (prefix ids by source when merging lists, e.g. `task-…`, `event-…`). */
@@ -11428,6 +11503,29 @@ export interface CalendarSlotClick {
11428
11503
  /** `HH:00` of the clicked hour row. */
11429
11504
  time: string;
11430
11505
  }
11506
+ /** What `dayDecorationFn` returns for one day: a tint level and/or a tooltip. */
11507
+ export interface CalendarDayDecoration {
11508
+ /** Tints the day (month cell background + a coloured top bar; week view day header) and adds "<level> activity" to its screen-reader label. */
11509
+ level?: CalendarDayLevel;
11510
+ /** Hover / keyboard-focus tooltip of the day (library `uiTooltip`). Empty = none. */
11511
+ tooltip?: string;
11512
+ }
11513
+ /** One quick action offered on an item (`itemActionsFn`). */
11514
+ export interface CalendarItemAction {
11515
+ /** Unique per item; reported back in `itemAction`. */
11516
+ id: string;
11517
+ /** Visible text (or the hover title and accessible name when `icon` is set). */
11518
+ label: string;
11519
+ /** Icon key of `<ui-icon>` (e.g. `check`, `edit`, `delete`). With an icon the button shows only the icon; without one it shows the label. */
11520
+ icon?: string;
11521
+ disabled?: boolean;
11522
+ /** `danger` draws it red (destructive actions). */
11523
+ variant?: 'default' | 'danger';
11524
+ }
11525
+ export interface CalendarItemActionEvent {
11526
+ item: CalendarItem;
11527
+ actionId: string;
11528
+ }
11431
11529
  /**
11432
11530
  * Month / week / agenda calendar. The host owns the data: it listens to `(rangeChange)`, loads that range and passes
11433
11531
  * the result as `items`. The calendar owns navigation, the view switcher, type filters, layout and keyboard access.
@@ -11507,8 +11605,28 @@ export declare class CalendarComponent {
11507
11605
  readonly startHour: import("@angular/core").InputSignal<number>;
11508
11606
  readonly endHour: import("@angular/core").InputSignal<number>;
11509
11607
  readonly emptyMessage: import("@angular/core").InputSignal<string>;
11510
- /** Builds the screen-reader name of a month cell; default "<weekday, date>, N events". */
11608
+ /** Builds the screen-reader name of a month cell; default "<weekday, date>, N events" (plus ", <level> activity" when `dayDecorationFn` gives a level). */
11511
11609
  readonly dayLabelFn: import("@angular/core").InputSignal<((dateStr: string, items: CalendarItem[]) => string) | null>;
11610
+ /**
11611
+ * Optional per-day decoration (e.g. a workload heat map): called for every visible day with its items after the active filters. A `level`
11612
+ * (`low` / `medium` / `high` / `critical`) tints the month cell (background + a coloured bar on top, so the level is not colour alone) and the
11613
+ * week view day header, and adds "<level> activity" to the cell's default screen-reader label (a custom `dayLabelFn` label is used as given)
11614
+ * and as hidden text in the week header. A `tooltip` shows on hover and keyboard focus (library `uiTooltip`). Null / `null` result = no change.
11615
+ */
11616
+ readonly dayDecorationFn: import("@angular/core").InputSignal<((dateStr: string, items: CalendarItem[]) => CalendarDayDecoration | null) | null>;
11617
+ /**
11618
+ * Optional quick actions on items (e.g. Confirm / Complete): called once per item, return `[]` for none. The actions are real buttons next to the
11619
+ * item (month chip, all-day chip, timed event, agenda row) that appear on hover AND when keyboard focus is inside the item; they emit `itemAction`
11620
+ * and never `itemClick`. On touch screens the agenda view always shows them (month and week chips show them while tapped / focused). Escape inside the
11621
+ * actions returns focus to the item. Null = no actions and no extra DOM.
11622
+ */
11623
+ readonly itemActionsFn: import("@angular/core").InputSignal<((item: CalendarItem) => CalendarItemAction[]) | null>;
11624
+ /**
11625
+ * Optional agenda headings: called with each agenda day; consecutive days that return the same `key` share one `<h3>` heading (a `<section>`
11626
+ * labelled by it). A `null` result draws that day without a heading. `periodGroup(today)` is a ready-made Overdue / Today / Tomorrow / This Week /
11627
+ * Later grouping. Null = one block per date, as before.
11628
+ */
11629
+ readonly agendaGroupFn: import("@angular/core").InputSignal<((dateStr: string) => CalendarAgendaGroup | null) | null>;
11512
11630
  /** Fires on first render and whenever the view or the visible range changes: load this range, then pass `items`. */
11513
11631
  readonly rangeChange: import("@angular/core").OutputEmitterRef<CalendarRange>;
11514
11632
  readonly itemClick: import("@angular/core").OutputEmitterRef<CalendarItem>;
@@ -11518,6 +11636,8 @@ export declare class CalendarComponent {
11518
11636
  readonly slotClick: import("@angular/core").OutputEmitterRef<CalendarSlotClick>;
11519
11637
  /** "+N more" clicked in a month cell. */
11520
11638
  readonly moreClick: import("@angular/core").OutputEmitterRef<CalendarMoreClick>;
11639
+ /** A quick action of an item (`itemActionsFn`) was activated. Never accompanied by `itemClick`. */
11640
+ readonly itemAction: import("@angular/core").OutputEmitterRef<CalendarItemActionEvent>;
11521
11641
  private readonly host;
11522
11642
  protected readonly weekDayLabels: string[];
11523
11643
  protected readonly weekDayNames: string[];
@@ -11566,6 +11686,8 @@ export declare class CalendarComponent {
11566
11686
  overflow: number;
11567
11687
  clickable: boolean;
11568
11688
  label: string;
11689
+ level: CalendarDayLevel | null;
11690
+ tooltip: string;
11569
11691
  }[];
11570
11692
  }[]>;
11571
11693
  /** The 7 week columns with all-day items and the timed items laid out side by side when they overlap. */
@@ -11573,6 +11695,8 @@ export declare class CalendarComponent {
11573
11695
  day: import("@forgeroute/ui").CalendarDay;
11574
11696
  label: string;
11575
11697
  clickable: boolean;
11698
+ level: CalendarDayLevel | null;
11699
+ tooltip: string;
11576
11700
  allDay: CalendarItem[];
11577
11701
  timed: {
11578
11702
  lane: CalendarLane;
@@ -11605,6 +11729,29 @@ export declare class CalendarComponent {
11605
11729
  protected itemLabel(e: CalendarItem): string;
11606
11730
  protected agendaMeta(e: CalendarItem): string[];
11607
11731
  private dayAriaLabel;
11732
+ /** The decoration of one day: an unknown `level` (loosely typed host) is dropped, a missing tooltip is `''`. */
11733
+ private decoration;
11734
+ protected levelText(level: CalendarDayLevel): string;
11735
+ /** Quick actions per item id, computed once per input change (nothing is computed while `itemActionsFn` is null). */
11736
+ private readonly actionsById;
11737
+ private static readonly NO_ACTIONS;
11738
+ protected actionsFor(item: CalendarItem): CalendarItemAction[];
11739
+ protected actionIconD(a: CalendarItemAction): string | null;
11740
+ protected onActionClick(item: CalendarItem, action: CalendarItemAction, event: Event): void;
11741
+ /** Escape inside an item's actions: focus goes back to the item's own button. */
11742
+ protected onActionsEscape(event: Event): void;
11743
+ /** Agenda days grouped under `agendaGroupFn` headings (consecutive days with the same key), or null when no function is set. */
11744
+ private static nextUid;
11745
+ private readonly uid;
11746
+ protected readonly agendaSections: import("@angular/core").Signal<{
11747
+ key: string;
11748
+ label: string;
11749
+ id: string;
11750
+ groups: {
11751
+ dateStr: string;
11752
+ items: CalendarItem[];
11753
+ }[];
11754
+ }[] | null>;
11608
11755
  protected onDateClick(dateStr: string): void;
11609
11756
  /** Grid keys on a day cell: arrows / Home / End move the tab stop, Enter / Space create. Keys on the chips inside never reach here. */
11610
11757
  protected onCellKey(event: KeyboardEvent, dateStr: string): void;
@@ -11724,6 +11871,21 @@ export declare class CalendarComponent {
11724
11871
  "required": false;
11725
11872
  "isSignal": true;
11726
11873
  };
11874
+ "dayDecorationFn": {
11875
+ "alias": "dayDecorationFn";
11876
+ "required": false;
11877
+ "isSignal": true;
11878
+ };
11879
+ "itemActionsFn": {
11880
+ "alias": "itemActionsFn";
11881
+ "required": false;
11882
+ "isSignal": true;
11883
+ };
11884
+ "agendaGroupFn": {
11885
+ "alias": "agendaGroupFn";
11886
+ "required": false;
11887
+ "isSignal": true;
11888
+ };
11727
11889
  }, {
11728
11890
  "view": "viewChange";
11729
11891
  "anchorDate": "anchorDateChange";
@@ -11733,6 +11895,7 @@ export declare class CalendarComponent {
11733
11895
  "dateClick": "dateClick";
11734
11896
  "slotClick": "slotClick";
11735
11897
  "moreClick": "moreClick";
11898
+ "itemAction": "itemAction";
11736
11899
  }, never, ["[calendar-summary]", "[calendar-actions]", "[calendar-summary-mobile]"], true, never>;
11737
11900
  }
11738
11901
  /**
@@ -11927,7 +12090,7 @@ export declare class ShowComponent {
11927
12090
  }, {}, never, ["*"], true, never>;
11928
12091
  }
11929
12092
  /**
11930
- * Small formatting helpers shared by apps (money and postal addresses).
12093
+ * Small formatting helpers shared by apps (money, postal addresses, names, phone numbers, durations and dates).
11931
12094
  */
11932
12095
  export interface FormatCurrencyOptions {
11933
12096
  /** ISO 4217 code. Default `'USD'`. */
@@ -11969,6 +12132,37 @@ export interface FormatAddressOptions {
11969
12132
  * with `{ style: 'usa' }` -> `1 Main, Austin, TX 78701`.
11970
12133
  */
11971
12134
  export declare function formatAddress(parts: AddressParts, options?: FormatAddressOptions): string;
12135
+ /**
12136
+ * The first letter of the first and last name: `getInitials('Sarah', 'Chen')` -> `SC`. A missing name contributes nothing (`getInitials('Sarah', '')` -> `S`).
12137
+ * Letters are returned as written (not upper-cased).
12138
+ */
12139
+ export declare function getInitials(firstName: string | null | undefined, lastName: string | null | undefined): string;
12140
+ /**
12141
+ * A length of time in seconds as text: `formatDuration(90)` -> `1m 30s`, `formatDuration(45)` -> `45s`. `null`, `undefined` and 0 give `''`.
12142
+ * Hours are not split out (`3700` -> `61m 40s`).
12143
+ */
12144
+ export declare function formatDuration(seconds: number | null | undefined): string;
12145
+ /**
12146
+ * A phone number as `(555) 555-5555` while it is typed or stored: `formatPhone('5125550001')` -> `(512) 555-0001`. A US `+1` / leading `1` is dropped,
12147
+ * other international numbers (a `+` that is not `+1` plus 10 digits) are returned as given, fewer digits give the partial form
12148
+ * (`'512555'` -> `(512) 555`, `'512'` -> `512`) and more than 10 digits are cut to 10. `null`, `undefined` and `''` give `''`.
12149
+ */
12150
+ export declare function formatPhone(raw: string | null | undefined): string;
12151
+ /**
12152
+ * A US / Canada E.164 number as `+1 512 555-0100` (for showing a stored number). Any other value is returned as given (trimmed values are
12153
+ * still formatted: `' +15125550100 '` -> `+1 512 555-0100`); `null` and `undefined` give `''`. Use `formatPhone` for the domestic `(512) 555-0100` form.
12154
+ */
12155
+ export declare function formatPhoneDisplay(e164: string | null | undefined): string;
12156
+ /**
12157
+ * A date as short text: `formatShortDate('2026-01-05')` -> `Jan 5, 2026`; `''` / `null` / `undefined` give `—`. A plain `YYYY-MM-DD` is read as a LOCAL
12158
+ * date (so it never shifts a day with the time zone); any other string goes through `new Date(...)` and uses the same en-US format.
12159
+ */
12160
+ export declare function formatShortDate(value: string | null | undefined): string;
12161
+ /**
12162
+ * Today's date as `YYYY-MM-DD` in the given IANA time zone (e.g. the user's profile time zone): `todayInTimezone('America/Phoenix')` -> `2026-10-13`.
12163
+ * No or an invalid time zone falls back to the browser's local date.
12164
+ */
12165
+ export declare function todayInTimezone(timezone?: string | null): string;
11972
12166
  /**
11973
12167
  * Starts the browser download of a blob under `fileName`. The anchor is attached to the page while it is clicked (Firefox ignores a click on
11974
12168
  * a detached anchor) and the object URL is revoked 1000 ms later (Safari reads it asynchronously, so an immediate revoke can cancel the
@@ -14097,4 +14291,4 @@ export declare class ConversationsComponent {
14097
14291
  "messagesRetry": "messagesRetry";
14098
14292
  }, never, ["[uiConversationsContext]"], true, never>;
14099
14293
  }
14100
- export type { CalendarDay, CalendarRange, CalendarViewMode };
14294
+ export type { CalendarAgendaGroup, CalendarDay, CalendarDayLevel, CalendarRange, CalendarViewMode };