@compsych-ui-components/angular 6.1.1 → 6.1.2

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.
@@ -1,52 +1,81 @@
1
+ import { OnChanges } from '@angular/core';
2
+ import { SafeHtml } from '@angular/platform-browser';
1
3
  import * as i0 from "@angular/core";
2
4
  /** Visual style of a `compsych-button`. Controls color, border, and elevation. */
3
5
  export type ButtonVariant = 'filled' | 'tonal' | 'outlined' | 'elevated' | 'text' | 'danger' | 'danger-outlined';
4
- /** Button dimensions — controls height, padding, and font size. */
6
+ /** Button dimensions — controls height, padding, font size, and icon size. */
5
7
  export type ButtonSize = 'small' | 'medium' | 'large' | 'xlarge';
6
- /** Placement of `icon` relative to the label. */
7
- export type ButtonIconPosition = 'leading' | 'trailing';
8
8
  /** Native button behaviour. `'submit'`/`'reset'` make the component a real form control. */
9
9
  export type ButtonType = 'button' | 'submit' | 'reset';
10
10
  /**
11
11
  * A themeable button that renders a native `<button>` element, so it is fully
12
- * form-submittable and keyboard/screen-reader accessible out of the box.
12
+ * form-submittable and keyboard/screen-reader accessible out of the box. Icons
13
+ * are Lucide glyphs (matching the rest of the library); a button may carry a
14
+ * leading icon, a trailing icon, or both.
13
15
  */
14
- export declare class ButtonComponent {
16
+ export declare class ButtonComponent implements OnChanges {
17
+ private readonly sanitizer;
15
18
  /** Text label rendered on the button. */
16
19
  label: string;
17
20
  /** Visual style of the button. Defaults to `'filled'`. */
18
21
  variant: ButtonVariant;
19
- /** Button dimensions — controls height, padding, and font size. Defaults to `'small'`. */
22
+ /** Button dimensions — controls height, padding, font size, and icon size. Defaults to `'small'`. */
20
23
  size: ButtonSize;
21
- /** Material Symbols icon name (e.g. `'search'`, `'arrow_forward'`). Omit to show label only. */
22
- icon?: string;
23
- /** Placement of `icon` relative to the label. Defaults to `'leading'`. */
24
- iconPosition: ButtonIconPosition;
24
+ /** Lucide icon name shown before the label (e.g. `'house'`). Swapped for a spinner when loading. */
25
+ leadingIcon?: string;
26
+ /** Lucide icon name shown after the label (e.g. `'chevron-right'`). Can be combined with `leadingIcon`. */
27
+ trailingIcon?: string;
25
28
  /** Native button type. Use `'submit'` inside a `<form>` to submit it. Defaults to `'button'`. */
26
29
  type: ButtonType;
27
30
  /**
28
- * Accessible name. Required for icon-only buttons since the icon is decorative
29
- * (`aria-hidden`). When `iconOnly` is set and this is omitted, `label` is used.
31
+ * Accessible name. Required for icon-only buttons since the icon is decorative.
32
+ * When `iconOnly` or `loading` is set and this is omitted, `label` is used.
30
33
  */
31
34
  ariaLabel?: string;
32
- /** Hides the label and renders a square icon-only button. Requires `icon`. Supports boolean coercion. */
35
+ /** Hides the label and renders a square icon-only button. Uses `leadingIcon`. Supports boolean coercion. */
33
36
  iconOnly: boolean;
34
- /** Disables the button — non-interactive and dimmed. Supports boolean coercion. */
37
+ /** Disables the button — non-interactive and rendered in a neutral grey. Supports boolean coercion. */
35
38
  disabled: boolean;
36
39
  /**
37
- * Loading state. Replaces the content with a centered spinner while preserving
38
- * the button's width, blocks re-clicks, and exposes `aria-busy="true"`. The
39
- * variant's colours are retained (unlike `disabled`, which dims the button).
40
- * Supports boolean coercion.
40
+ * Loading state. Swaps the leading icon for a spinner and suppresses activation
41
+ * (native `disabled` blocks click/keyboard), while keeping the label and exposing
42
+ * `aria-busy="true"`. Retains the variant's colours. Supports boolean coercion.
41
43
  */
42
44
  loading: boolean;
45
+ /** Stretches the button to the full width of its container. Supports boolean coercion. */
46
+ fullWidth: boolean;
47
+ /** Mirrors `fullWidth` onto the host so it can stretch. */
48
+ get hostFullWidth(): boolean;
49
+ /** Pre-sanitized icon markup, recomputed on input change (avoids re-sanitizing every CD cycle). */
50
+ protected leadingIconSvg: SafeHtml | null;
51
+ protected trailingIconSvg: SafeHtml | null;
52
+ ngOnChanges(): void;
43
53
  /** Space-separated class list applied to the inner native button. */
44
54
  get buttonClasses(): string;
45
- /** Resolves the accessible name, guaranteeing icon-only and loading buttons are labelled. */
55
+ /** Resolves the accessible name. Icon-only buttons have no visible text, so they fall back to `label`. */
46
56
  get computedAriaLabel(): string | null;
57
+ /**
58
+ * Looks up a Lucide icon by name and injects an explicit width/height so the SVG
59
+ * renders at the correct size when injected via `[innerHTML]` (Angular's CSS
60
+ * encapsulation does not reach dynamically injected content).
61
+ */
62
+ private buildIconSvg;
63
+ /** M3 pressed ripple: pointer-down spawns a ripple at the pointer position. */
64
+ onPointerDown(event: PointerEvent): void;
65
+ /** M3 pressed ripple: keyboard activation (Enter/Space) spawns a centered ripple. */
66
+ onKeyDown(event: KeyboardEvent): void;
67
+ /** Diameter that reaches the farthest corner from (x, y), so the ripple always covers the button. */
68
+ private farthestCornerDiameter;
69
+ /**
70
+ * Spawns an expanding ripple circle. Created imperatively with inline styles and
71
+ * animated via the Web Animations API — Angular's emulated encapsulation does not
72
+ * reach dynamically created nodes, so it cannot rely on the component stylesheet.
73
+ */
74
+ private spawnRipple;
47
75
  static ɵfac: i0.ɵɵFactoryDeclaration<ButtonComponent, never>;
48
- static ɵcmp: i0.ɵɵComponentDeclaration<ButtonComponent, "compsych-button", never, { "label": { "alias": "label"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "size": { "alias": "size"; "required": false; }; "icon": { "alias": "icon"; "required": false; }; "iconPosition": { "alias": "iconPosition"; "required": false; }; "type": { "alias": "type"; "required": false; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "iconOnly": { "alias": "iconOnly"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; }, {}, never, never, true, never>;
76
+ static ɵcmp: i0.ɵɵComponentDeclaration<ButtonComponent, "compsych-button", never, { "label": { "alias": "label"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "size": { "alias": "size"; "required": false; }; "leadingIcon": { "alias": "leadingIcon"; "required": false; }; "trailingIcon": { "alias": "trailingIcon"; "required": false; }; "type": { "alias": "type"; "required": false; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "iconOnly": { "alias": "iconOnly"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "fullWidth": { "alias": "fullWidth"; "required": false; }; }, {}, never, ["*"], true, never>;
49
77
  static ngAcceptInputType_iconOnly: unknown;
50
78
  static ngAcceptInputType_disabled: unknown;
51
79
  static ngAcceptInputType_loading: unknown;
80
+ static ngAcceptInputType_fullWidth: unknown;
52
81
  }
@@ -0,0 +1,50 @@
1
+ import { ElementRef, OnChanges } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /** A single navigation link in the footer. */
4
+ export interface FooterLink {
5
+ /** Text displayed in the link. */
6
+ label: string;
7
+ /** URL the link navigates to. */
8
+ href: string;
9
+ }
10
+ /**
11
+ * Footer — bottom bar from the ComPsych Design System.
12
+ *
13
+ * Displays a copyright notice and an optional list of navigation links.
14
+ * On initialisation the component measures the natural widths of the copyright
15
+ * and links to establish a breakpoint. On every window resize it compares the
16
+ * host width against that breakpoint and switches between a row layout
17
+ * (copyright left, links right) and a stacked, centered column layout.
18
+ */
19
+ export declare class FooterComponent implements OnChanges {
20
+ private readonly el;
21
+ /**
22
+ * Navigation links rendered alongside the copyright notice.
23
+ * The layout switches automatically based on their combined natural width.
24
+ */
25
+ links: FooterLink[];
26
+ /**
27
+ * Copyright notice generated from the current calendar year.
28
+ * Left-aligned in the row layout and centered when stacked.
29
+ */
30
+ readonly copyright: string;
31
+ /**
32
+ * Reflects whether the row layout is active.
33
+ * Signal so OnPush picks up DOM-driven updates from async callbacks.
34
+ */
35
+ protected readonly isRow: import("@angular/core").WritableSignal<boolean>;
36
+ /** Combined natural width of copyright + links + gap + padding. */
37
+ private breakpoint;
38
+ constructor(el: ElementRef<HTMLElement>);
39
+ ngOnChanges(): void;
40
+ protected onResize(): void;
41
+ /**
42
+ * Measures the natural widths of the copyright and links elements once and
43
+ * stores their sum (plus padding and gap) as the layout breakpoint.
44
+ */
45
+ private measureBreakpoint;
46
+ /** Switches to the row layout when the host is wide enough for both children. */
47
+ private checkLayout;
48
+ static ɵfac: i0.ɵɵFactoryDeclaration<FooterComponent, never>;
49
+ static ɵcmp: i0.ɵɵComponentDeclaration<FooterComponent, "compsych-footer", never, { "links": { "alias": "links"; "required": false; }; }, {}, never, never, true, never>;
50
+ }
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from '@angular/core';
2
2
  import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
3
- import { ButtonVariant, ButtonIconPosition } from '../button/button';
3
+ import { ButtonVariant } from '../button/button';
4
4
  import * as i0 from "@angular/core";
5
5
  export type HeaderNavLevel = 'main' | 'sub-page' | 'not-logged';
6
6
  /**
@@ -15,10 +15,10 @@ export interface NavAction {
15
15
  label: string;
16
16
  /** Button style for action buttons. Defaults to `'filled'` when omitted. Not used for breadcrumbs. */
17
17
  variant?: ButtonVariant;
18
- /** Material Symbols icon shown on the action button (e.g. `'chevron_right'`). Not used for breadcrumbs. */
19
- icon?: string;
20
- /** Placement of `icon` relative to the label. Defaults to `'leading'`. */
21
- iconPosition?: ButtonIconPosition;
18
+ /** Lucide icon shown before the label (e.g. `'house'`). Not used for breadcrumbs. */
19
+ leadingIcon?: string;
20
+ /** Lucide icon shown after the label (e.g. `'chevron-right'`). Not used for breadcrumbs. */
21
+ trailingIcon?: string;
22
22
  /** Renders the action button disabled. */
23
23
  disabled?: boolean;
24
24
  /** Renders the action button in a loading state (spinner, interaction blocked). */
@@ -127,10 +127,10 @@ export declare class HeaderNavComponent {
127
127
  get notificationAriaLabel(): string;
128
128
  /**
129
129
  * Looks up a Lucide icon by name and injects explicit width/height attributes
130
- * (20 × 20) so the SVG renders at the correct size when injected via [innerHTML].
131
- * Angular's CSS encapsulation does not add _ngcontent attributes to dynamically
132
- * injected content, so CSS descendant selectors targeting `svg` would not apply —
133
- * explicit SVG attributes are the reliable solution.
130
+ * (default 20 × 20) so the SVG renders at the correct size when injected via
131
+ * [innerHTML]. Angular's CSS encapsulation does not add _ngcontent attributes to
132
+ * dynamically injected content, so CSS descendant selectors targeting `svg` would
133
+ * not apply — explicit SVG attributes are the reliable solution.
134
134
  */
135
135
  private trustedIcon;
136
136
  static ɵfac: i0.ɵɵFactoryDeclaration<HeaderNavComponent, never>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compsych-ui-components/angular",
3
- "version": "6.1.1",
3
+ "version": "6.1.2",
4
4
  "description": "Angular UI components for compsych",
5
5
  "publishConfig": {
6
6
  "access": "public",