@memberjunction/ng-ui-components 6.2.0-edge.0 → 6.2.0-edge.1
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/README.md +35 -9
- package/dist/lib/a11y/named-control.base.d.ts +91 -0
- package/dist/lib/a11y/named-control.base.d.ts.map +1 -0
- package/dist/lib/a11y/named-control.base.js +121 -0
- package/dist/lib/a11y/named-control.base.js.map +1 -0
- package/dist/lib/a11y/unnamed-control-guard.d.ts +52 -0
- package/dist/lib/a11y/unnamed-control-guard.d.ts.map +1 -0
- package/dist/lib/a11y/unnamed-control-guard.js +94 -0
- package/dist/lib/a11y/unnamed-control-guard.js.map +1 -0
- package/dist/lib/accordion/accordion.component.d.ts +16 -4
- package/dist/lib/accordion/accordion.component.d.ts.map +1 -1
- package/dist/lib/accordion/accordion.component.js +36 -12
- package/dist/lib/accordion/accordion.component.js.map +1 -1
- package/dist/lib/applied-filters/applied-filters.component.js.map +1 -1
- package/dist/lib/button/button.directive.d.ts +34 -6
- package/dist/lib/button/button.directive.d.ts.map +1 -1
- package/dist/lib/button/button.directive.js +85 -25
- package/dist/lib/button/button.directive.js.map +1 -1
- package/dist/lib/card-grid/card-grid.component.d.ts +3 -1
- package/dist/lib/card-grid/card-grid.component.d.ts.map +1 -1
- package/dist/lib/card-grid/card-grid.component.js +13 -9
- package/dist/lib/card-grid/card-grid.component.js.map +1 -1
- package/dist/lib/clickable/clickable.directive.d.ts +11 -3
- package/dist/lib/clickable/clickable.directive.d.ts.map +1 -1
- package/dist/lib/clickable/clickable.directive.js +25 -5
- package/dist/lib/clickable/clickable.directive.js.map +1 -1
- package/dist/lib/combobox/combobox.component.d.ts +44 -3
- package/dist/lib/combobox/combobox.component.d.ts.map +1 -1
- package/dist/lib/combobox/combobox.component.js +135 -51
- package/dist/lib/combobox/combobox.component.js.map +1 -1
- package/dist/lib/confirm-dialog/confirm-dialog.component.d.ts +6 -0
- package/dist/lib/confirm-dialog/confirm-dialog.component.d.ts.map +1 -1
- package/dist/lib/confirm-dialog/confirm-dialog.component.js +16 -4
- package/dist/lib/confirm-dialog/confirm-dialog.component.js.map +1 -1
- package/dist/lib/datepicker/datepicker.component.d.ts +25 -2
- package/dist/lib/datepicker/datepicker.component.d.ts.map +1 -1
- package/dist/lib/datepicker/datepicker.component.js +98 -42
- package/dist/lib/datepicker/datepicker.component.js.map +1 -1
- package/dist/lib/dialog/dialog.component.d.ts +4 -0
- package/dist/lib/dialog/dialog.component.d.ts.map +1 -1
- package/dist/lib/dialog/dialog.component.js +12 -4
- package/dist/lib/dialog/dialog.component.js.map +1 -1
- package/dist/lib/dialog/dialog.service.js.map +1 -1
- package/dist/lib/dropdown/dropdown.component.d.ts +19 -44
- package/dist/lib/dropdown/dropdown.component.d.ts.map +1 -1
- package/dist/lib/dropdown/dropdown.component.js +37 -76
- package/dist/lib/dropdown/dropdown.component.js.map +1 -1
- package/dist/lib/dropdown/dropdown.scss +0 -16
- package/dist/lib/filter-panel/filter-panel.component.d.ts +8 -0
- package/dist/lib/filter-panel/filter-panel.component.d.ts.map +1 -1
- package/dist/lib/filter-panel/filter-panel.component.js +25 -9
- package/dist/lib/filter-panel/filter-panel.component.js.map +1 -1
- package/dist/lib/numeric-input/numeric-input.component.d.ts +15 -1
- package/dist/lib/numeric-input/numeric-input.component.d.ts.map +1 -1
- package/dist/lib/numeric-input/numeric-input.component.js +36 -9
- package/dist/lib/numeric-input/numeric-input.component.js.map +1 -1
- package/dist/lib/page-search/page-search.component.d.ts +32 -3
- package/dist/lib/page-search/page-search.component.d.ts.map +1 -1
- package/dist/lib/page-search/page-search.component.js +68 -12
- package/dist/lib/page-search/page-search.component.js.map +1 -1
- package/dist/lib/switch/switch.component.d.ts +22 -1
- package/dist/lib/switch/switch.component.d.ts.map +1 -1
- package/dist/lib/switch/switch.component.js +50 -16
- package/dist/lib/switch/switch.component.js.map +1 -1
- package/dist/lib/tabs/tab-chrome-guard.d.ts +2 -0
- package/dist/lib/tabs/tab-chrome-guard.d.ts.map +1 -1
- package/dist/lib/tabs/tab-chrome-guard.js +5 -1
- package/dist/lib/tabs/tab-chrome-guard.js.map +1 -1
- package/dist/lib/window/window.component.d.ts +10 -0
- package/dist/lib/window/window.component.d.ts.map +1 -1
- package/dist/lib/window/window.component.js +27 -7
- package/dist/lib/window/window.component.js.map +1 -1
- package/dist/lib/workspace-tabs/workspace-tab-strip.component.d.ts +10 -0
- package/dist/lib/workspace-tabs/workspace-tab-strip.component.d.ts.map +1 -1
- package/dist/lib/workspace-tabs/workspace-tab-strip.component.js +27 -7
- package/dist/lib/workspace-tabs/workspace-tab-strip.component.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirm-dialog.component.js","sourceRoot":"","sources":["../../../src/lib/confirm-dialog/confirm-dialog.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, Output, booleanAttribute } from '@angular/core';\nimport { MJDialogComponent, MJDialogActionsComponent } from '../dialog/dialog.component';\nimport { MJButtonDirective } from '../button/button.directive';\n\n/**\n * Visual intent of an `<mj-confirm-dialog>`. Drives the header icon and the\n * confirm button's color, so callers rarely restate either.\n *\n * - `default` — a neutral question (e.g. \"Discard unsaved changes?\"). Blue confirm button.\n * - `danger` — a destructive / irreversible action (delete). Red confirm button.\n * - `warning` — a non-destructive but consequential action. Blue confirm button, caution icon.\n * - `info` — an informational confirmation. Blue confirm button, info icon.\n */\nexport type MJConfirmDialogType = 'default' | 'danger' | 'warning' | 'info';\n\nconst DEFAULT_ICONS: Record<MJConfirmDialogType, string> = {\n default: 'fa-solid fa-circle-question',\n danger: 'fa-solid fa-triangle-exclamation',\n warning: 'fa-solid fa-triangle-exclamation',\n info: 'fa-solid fa-circle-info',\n};\n\n/**\n * mj-confirm-dialog — Canonical confirmation prompt. The shared replacement for\n * native `window.confirm()` and the many hand-rolled \"Are you sure?\" modals\n * (`@if (showDeleteConfirm) { … backdrop + centered dialog }`) scattered across\n * the app, plus the duplicate local `mj-confirm-dialog` / `mj-ev-confirm-dialog`\n * components.\n *\n * Built on `<mj-dialog>` (so it inherits the backdrop, animations, mobile\n * full-screen behavior, and Esc/backdrop handling) and uses `role=\"alertdialog\"`\n * for screen readers. Buttons follow the MJ convention: the affirmative action\n * is **leftmost**, Cancel on the right.\n *\n * Visibility is two-way bindable. Cancelling (Cancel button, backdrop, Esc, or\n * the ✕) auto-closes and emits `Cancelled`. Confirming emits `Confirmed` and\n * **leaves the dialog open** so the handler can run async work — set `Visible`\n * to `false` (or update your bound property) when done. Bind `[Processing]` to a\n * loading flag during that async work to show a spinner, disable both buttons,\n * and block dismissal until it completes.\n *\n * Usage:\n * ```html\n * <!-- Simple destructive confirm -->\n * <mj-confirm-dialog\n * [(Visible)]=\"showDeleteConfirm\"\n * Type=\"danger\"\n * Title=\"Delete view\"\n * Message=\"Are you sure you want to delete this view?\"\n * DetailMessage=\"This action cannot be undone.\"\n * ConfirmText=\"Delete\"\n * (Confirmed)=\"onDeleteConfirmed()\">\n * </mj-confirm-dialog>\n *\n * <!-- Async confirm with a spinner while the work runs -->\n * <mj-confirm-dialog\n * [(Visible)]=\"confirmOpen\"\n * [Processing]=\"isDeleting\"\n * Type=\"danger\" Title=\"Delete user\" Message=\"Remove this user permanently?\"\n * ConfirmText=\"Delete\" (Confirmed)=\"deleteUser()\">\n * </mj-confirm-dialog>\n * ```\n */\n@Component({\n selector: 'mj-confirm-dialog',\n standalone: true,\n imports: [MJDialogComponent, MJDialogActionsComponent, MJButtonDirective],\n template: `\n <mj-dialog\n [Visible]=\"Visible\"\n [Title]=\"Title\"\n Size=\"sm\"\n Role=\"alertdialog\"\n [Closeable]=\"!Processing\"\n (Close)=\"onDismiss()\">\n\n <div class=\"mj-confirm\">\n @if (ResolvedIcon) {\n <i class=\"mj-confirm__icon mj-confirm__icon--{{ Type }} {{ ResolvedIcon }}\" aria-hidden=\"true\"></i>\n }\n <div class=\"mj-confirm__body\">\n @if (Message) {\n <p class=\"mj-confirm__message\">{{ Message }}</p>\n }\n @if (DetailMessage) {\n <p class=\"mj-confirm__detail\">{{ DetailMessage }}</p>\n }\n <ng-content></ng-content>\n </div>\n </div>\n\n <mj-dialog-actions>\n <button\n mjButton\n [variant]=\"ConfirmVariant\"\n [disabled]=\"Processing\"\n (click)=\"onConfirm()\">\n @if (Processing) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n }\n {{ ConfirmText }}\n </button>\n <button\n mjButton\n variant=\"secondary\"\n [disabled]=\"Processing\"\n (click)=\"onCancel()\">\n {{ CancelText }}\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n `,\n styles: [`\n .mj-confirm {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n }\n .mj-confirm__icon {\n flex-shrink: 0;\n font-size: 1.5rem;\n margin-top: 0.05em;\n color: var(--mj-text-muted);\n }\n .mj-confirm__icon--danger { color: var(--mj-status-error); }\n .mj-confirm__icon--warning { color: var(--mj-status-warning); }\n .mj-confirm__icon--info { color: var(--mj-status-info); }\n\n .mj-confirm__body { flex: 1; min-width: 0; }\n .mj-confirm__message {\n margin: 0;\n color: var(--mj-text-primary);\n line-height: 1.5;\n }\n .mj-confirm__detail {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n line-height: 1.45;\n }\n `]\n})\nexport class MJConfirmDialogComponent {\n /** Whether the dialog is shown. Two-way bindable: `[(Visible)]`. */\n @Input() Visible = false;\n /** Two-way `Visible` change channel — fires when the dialog auto-closes on cancel. */\n @Output() VisibleChange = new EventEmitter<boolean>();\n\n /** Heading shown in the dialog title bar. */\n @Input() Title = 'Confirm';\n\n /** Primary prompt text. For rich content, project default `<ng-content>` instead. */\n @Input() Message = 'Are you sure?';\n\n /** Optional secondary line, rendered smaller/muted beneath the message. */\n @Input() DetailMessage = '';\n\n /** Visual intent — drives the header icon + confirm button color. Defaults to 'default'. */\n @Input() Type: MJConfirmDialogType = 'default';\n\n /** Affirmative button label. */\n @Input() ConfirmText = 'Confirm';\n\n /** Dismiss button label. */\n @Input() CancelText = 'Cancel';\n\n /**\n * Font Awesome icon class (e.g. \"fa-solid fa-trash\") for the header. When\n * omitted, a sensible default is chosen from `Type`. Set to `''` for no icon.\n */\n @Input() Icon: string | null = null;\n\n /**\n * When true, shows a spinner on the confirm button, disables both buttons, and\n * blocks dismissal (Esc / backdrop / ✕) — bind this to your loading flag while\n * the `Confirmed` handler runs async work.\n */\n @Input({ transform: booleanAttribute }) Processing = false;\n\n /** Fired when the user confirms. The dialog stays open; close it when ready. */\n @Output() Confirmed = new EventEmitter<void>();\n\n /** Fired when the user cancels (button, backdrop, Esc, or ✕). The dialog auto-closes. */\n @Output() Cancelled = new EventEmitter<void>();\n\n /** mjButton variant for the confirm button — red for `danger`, blue otherwise. */\n get ConfirmVariant(): 'primary' | 'danger' {\n return this.Type === 'danger' ? 'danger' : 'primary';\n }\n\n /**\n * Icon actually rendered: the explicit `Icon` when provided (including `\"\"`\n * to suppress it), otherwise the per-type default.\n */\n get ResolvedIcon(): string {\n if (this.Icon != null) {\n return this.Icon;\n }\n return DEFAULT_ICONS[this.Type] ?? DEFAULT_ICONS.default;\n }\n\n onConfirm(): void {\n this.Confirmed.emit();\n }\n\n onCancel(): void {\n this.close();\n this.Cancelled.emit();\n }\n\n /** Backdrop / Esc / ✕ from the underlying dialog — ignored while Processing. */\n onDismiss(): void {\n if (this.Processing) {\n return;\n }\n this.onCancel();\n }\n\n private close(): void {\n this.Visible = false;\n this.VisibleChange.emit(false);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"confirm-dialog.component.js","sourceRoot":"","sources":["../../../src/lib/confirm-dialog/confirm-dialog.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, Output, booleanAttribute } from '@angular/core';\nimport { MJDialogComponent, MJDialogActionsComponent } from '../dialog/dialog.component';\nimport { MJButtonDirective } from '../button/button.directive';\n\n/**\n * Visual intent of an `<mj-confirm-dialog>`. Drives the header icon and the\n * confirm button's color, so callers rarely restate either.\n *\n * - `default` — a neutral question (e.g. \"Discard unsaved changes?\"). Blue confirm button.\n * - `danger` — a destructive / irreversible action (delete). Red confirm button.\n * - `warning` — a non-destructive but consequential action. Blue confirm button, caution icon.\n * - `info` — an informational confirmation. Blue confirm button, info icon.\n */\nexport type MJConfirmDialogType = 'default' | 'danger' | 'warning' | 'info';\n\nconst DEFAULT_ICONS: Record<MJConfirmDialogType, string> = {\n default: 'fa-solid fa-circle-question',\n danger: 'fa-solid fa-triangle-exclamation',\n warning: 'fa-solid fa-triangle-exclamation',\n info: 'fa-solid fa-circle-info',\n};\n\n/**\n * mj-confirm-dialog — Canonical confirmation prompt. The shared replacement for\n * native `window.confirm()` and the many hand-rolled \"Are you sure?\" modals\n * (`@if (showDeleteConfirm) { … backdrop + centered dialog }`) scattered across\n * the app, plus the duplicate local `mj-confirm-dialog` / `mj-ev-confirm-dialog`\n * components.\n *\n * Built on `<mj-dialog>` (so it inherits the backdrop, animations, mobile\n * full-screen behavior, and Esc/backdrop handling) and uses `role=\"alertdialog\"`\n * for screen readers. Buttons follow the MJ convention: the affirmative action\n * is **leftmost**, Cancel on the right.\n *\n * Visibility is two-way bindable. Cancelling (Cancel button, backdrop, Esc, or\n * the ✕) auto-closes and emits `Cancelled`. Confirming emits `Confirmed` and\n * **leaves the dialog open** so the handler can run async work — set `Visible`\n * to `false` (or update your bound property) when done. Bind `[Processing]` to a\n * loading flag during that async work to show a spinner, disable both buttons,\n * and block dismissal until it completes.\n *\n * Usage:\n * ```html\n * <!-- Simple destructive confirm -->\n * <mj-confirm-dialog\n * [(Visible)]=\"showDeleteConfirm\"\n * Type=\"danger\"\n * Title=\"Delete view\"\n * Message=\"Are you sure you want to delete this view?\"\n * DetailMessage=\"This action cannot be undone.\"\n * ConfirmText=\"Delete\"\n * (Confirmed)=\"onDeleteConfirmed()\">\n * </mj-confirm-dialog>\n *\n * <!-- Async confirm with a spinner while the work runs -->\n * <mj-confirm-dialog\n * [(Visible)]=\"confirmOpen\"\n * [Processing]=\"isDeleting\"\n * Type=\"danger\" Title=\"Delete user\" Message=\"Remove this user permanently?\"\n * ConfirmText=\"Delete\" (Confirmed)=\"deleteUser()\">\n * </mj-confirm-dialog>\n * ```\n */\n@Component({\n selector: 'mj-confirm-dialog',\n standalone: true,\n imports: [MJDialogComponent, MJDialogActionsComponent, MJButtonDirective],\n template: `\n <mj-dialog\n [Visible]=\"Visible\"\n [Title]=\"Title\"\n Size=\"sm\"\n Role=\"alertdialog\"\n [Closeable]=\"!Processing\"\n (Close)=\"onDismiss()\">\n\n <div class=\"mj-confirm\">\n @if (ResolvedIcon) {\n <i class=\"mj-confirm__icon mj-confirm__icon--{{ Type }} {{ ResolvedIcon }}\" aria-hidden=\"true\"></i>\n }\n <div class=\"mj-confirm__body\">\n @if (Message) {\n <p class=\"mj-confirm__message\">{{ Message }}</p>\n }\n @if (DetailMessage) {\n <p class=\"mj-confirm__detail\">{{ DetailMessage }}</p>\n }\n <ng-content></ng-content>\n </div>\n </div>\n\n <mj-dialog-actions>\n <button\n mjButton\n [variant]=\"ConfirmVariant\"\n [disabled]=\"Processing\"\n (click)=\"onConfirm()\">\n @if (Processing) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n }\n {{ ConfirmText }}\n </button>\n <button\n mjButton\n variant=\"secondary\"\n [disabled]=\"Processing\"\n (click)=\"onCancel()\">\n {{ CancelText }}\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n `,\n styles: [`\n .mj-confirm {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n }\n .mj-confirm__icon {\n flex-shrink: 0;\n font-size: 1.5rem;\n margin-top: 0.05em;\n color: var(--mj-text-muted);\n }\n .mj-confirm__icon--danger { color: var(--mj-status-error); }\n .mj-confirm__icon--warning { color: var(--mj-status-warning); }\n .mj-confirm__icon--info { color: var(--mj-status-info); }\n\n .mj-confirm__body { flex: 1; min-width: 0; }\n .mj-confirm__message {\n margin: 0;\n color: var(--mj-text-primary);\n line-height: 1.5;\n }\n .mj-confirm__detail {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n line-height: 1.45;\n }\n `]\n})\nexport class MJConfirmDialogComponent {\n /** Whether the dialog is shown. Two-way bindable: `[(Visible)]`. */\n @Input() Visible = false;\n /** Two-way `Visible` change channel — fires when the dialog auto-closes on cancel. */\n @Output() VisibleChange = new EventEmitter<boolean>();\n\n /** Heading shown in the dialog title bar. */\n @Input() Title = 'Confirm';\n\n /** Primary prompt text. For rich content, project default `<ng-content>` instead. */\n @Input() Message = 'Are you sure?';\n\n /** Optional secondary line, rendered smaller/muted beneath the message. */\n @Input() DetailMessage = '';\n\n /** Visual intent — drives the header icon + confirm button color. Defaults to 'default'. */\n @Input() Type: MJConfirmDialogType = 'default';\n\n /** Affirmative button label. */\n @Input() ConfirmText = 'Confirm';\n\n /** Dismiss button label. */\n @Input() CancelText = 'Cancel';\n\n /**\n * Font Awesome icon class (e.g. \"fa-solid fa-trash\") for the header. When\n * omitted, a sensible default is chosen from `Type`. Set to `''` for no icon.\n */\n @Input() Icon: string | null = null;\n\n /**\n * When true, shows a spinner on the confirm button, disables both buttons, and\n * blocks dismissal (Esc / backdrop / ✕) — bind this to your loading flag while\n * the `Confirmed` handler runs async work.\n */\n @Input({ transform: booleanAttribute }) Processing = false;\n\n /** Fired when the user confirms. The dialog stays open; close it when ready. */\n @Output() Confirmed = new EventEmitter<void>();\n\n /** Fired when the user cancels (button, backdrop, Esc, or ✕). The dialog auto-closes. */\n @Output() Cancelled = new EventEmitter<void>();\n\n /** mjButton variant for the confirm button — red for `danger`, blue otherwise. */\n get ConfirmVariant(): 'primary' | 'danger' {\n return this.Type === 'danger' ? 'danger' : 'primary';\n }\n\n /**\n * Icon actually rendered: the explicit `Icon` when provided (including `\"\"`\n * to suppress it), otherwise the per-type default.\n */\n get ResolvedIcon(): string {\n if (this.Icon != null) {\n return this.Icon;\n }\n return DEFAULT_ICONS[this.Type] ?? DEFAULT_ICONS.default;\n }\n\n OnConfirm(): void {\n this.Confirmed.emit();\n }\n\n /** @deprecated Use {@link OnConfirm}. */\n onConfirm(): void {\n return this.OnConfirm();\n }\n\n OnCancel(): void {\n this.close();\n this.Cancelled.emit();\n }\n\n /** @deprecated Use {@link OnCancel}. */\n onCancel(): void {\n return this.OnCancel();\n }\n\n /** Backdrop / Esc / ✕ from the underlying dialog — ignored while Processing. */\n OnDismiss(): void {\n if (this.Processing) {\n return;\n }\n this.OnCancel();\n }\n\n /** @deprecated Use {@link OnDismiss}. */\n onDismiss(): void {\n return this.OnDismiss();\n }\n\n private close(): void {\n this.Visible = false;\n this.VisibleChange.emit(false);\n }\n}\n"]}
|
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
import { EventEmitter, OnDestroy } from '@angular/core';
|
|
1
|
+
import { AfterViewInit, EventEmitter, OnDestroy } from '@angular/core';
|
|
2
2
|
import { ControlValueAccessor } from '@angular/forms';
|
|
3
3
|
import { ConnectedPosition } from '@angular/cdk/overlay';
|
|
4
4
|
import { CalendarDay } from '../calendar/calendar-utils';
|
|
5
|
+
import { MJNamedControlBase } from '../a11y/named-control.base';
|
|
5
6
|
import * as i0 from "@angular/core";
|
|
6
7
|
/**
|
|
7
8
|
* mj-datepicker — Date picker with calendar popup. Replaces `<kendo-datepicker>`.
|
|
9
|
+
*
|
|
10
|
+
* Without an accessible name the date field announces as "edit, blank" and its calendar popup as a
|
|
11
|
+
* generic "Calendar" — so a form with a start date and an end date presents two identical grids
|
|
12
|
+
* (WCAG 2.1 4.1.2). Use {@link MJNamedControlBase.AriaLabelledBy} when a visible label exists,
|
|
13
|
+
* {@link MJNamedControlBase.AriaLabel} when none does; the toggle button and the calendar take
|
|
14
|
+
* their names from the same source. The field is a real `<input>`, so
|
|
15
|
+
* {@link MJNamedControlBase.InputId} IS a valid `<label for>` target.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```html
|
|
19
|
+
* <mj-datepicker AriaLabel="Due date" [(ngModel)]="dueDate" [Min]="minDate" />
|
|
20
|
+
* ```
|
|
8
21
|
*/
|
|
9
|
-
export declare class MJDatepickerComponent implements ControlValueAccessor, OnDestroy {
|
|
22
|
+
export declare class MJDatepickerComponent extends MJNamedControlBase implements ControlValueAccessor, AfterViewInit, OnDestroy {
|
|
10
23
|
Min: Date | null;
|
|
11
24
|
Max: Date | null;
|
|
12
25
|
Format: string;
|
|
@@ -21,6 +34,7 @@ export declare class MJDatepickerComponent implements ControlValueAccessor, OnDe
|
|
|
21
34
|
get Disabled(): boolean;
|
|
22
35
|
ValueChange: EventEmitter<Date | null>;
|
|
23
36
|
private triggerEl;
|
|
37
|
+
private dateInputEl;
|
|
24
38
|
readonly hostClass = true;
|
|
25
39
|
private cdr;
|
|
26
40
|
IsOpen: boolean;
|
|
@@ -34,6 +48,15 @@ export declare class MJDatepickerComponent implements ControlValueAccessor, OnDe
|
|
|
34
48
|
private onChange;
|
|
35
49
|
private onTouched;
|
|
36
50
|
get MonthYearLabel(): string;
|
|
51
|
+
/** `aria-labelledby` id list for the toggle button when a VISIBLE label names the field. */
|
|
52
|
+
get ToggleLabelledBy(): string;
|
|
53
|
+
/** `aria-label` for the toggle button in the no-visible-label case. */
|
|
54
|
+
get ToggleLabel(): string;
|
|
55
|
+
/** `aria-labelledby` id list for the calendar grid when a VISIBLE label names the field. */
|
|
56
|
+
get CalendarLabelledBy(): string;
|
|
57
|
+
/** `aria-label` for the calendar grid in the no-visible-label case. */
|
|
58
|
+
get CalendarLabel(): string;
|
|
59
|
+
ngAfterViewInit(): void;
|
|
37
60
|
Toggle(): void;
|
|
38
61
|
Open(): void;
|
|
39
62
|
Close(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datepicker.component.d.ts","sourceRoot":"","sources":["../../../src/lib/datepicker/datepicker.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAkD,SAAS,EAA6B,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"datepicker.component.d.ts","sourceRoot":"","sources":["../../../src/lib/datepicker/datepicker.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,YAAY,EAAkD,SAAS,EAA6B,MAAM,eAAe,CAAC;AAC5K,OAAO,EAAqB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAiB,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAgE,MAAM,4BAA4B,CAAC;AACvH,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;;AAGhE;;;;;;;;;;;;;;GAcG;AACH,qBA4Fa,qBAAsB,SAAQ,kBAAmB,YAAW,oBAAoB,EAAE,aAAa,EAAE,SAAS;IAC5G,GAAG,EAAE,IAAI,GAAG,IAAI,CAAQ;IACxB,GAAG,EAAE,IAAI,GAAG,IAAI,CAAQ;IACxB,MAAM,SAAgB;IACtB,WAAW,SAAM;IAC1B;;;;;OAKG;IACH,IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAsD;IACjF,IAAI,QAAQ,IAAI,OAAO,CAA+B;IAC5C,WAAW,4BAAmC;IAClC,OAAO,CAAC,SAAS,CAA2B;IAC1C,OAAO,CAAC,WAAW,CAA2C;IAC7C,QAAQ,CAAC,SAAS,QAAQ;IACnE,OAAO,CAAC,GAAG,CAA6B;IAExC,MAAM,UAAS;IAAC,UAAU,UAAS;IAAC,YAAY,SAAM;IACtD,KAAK,EAAE,WAAW,EAAE,EAAE,CAAM;IAAC,QAAQ,WAAa;IAClD,SAAS,EAAE,iBAAiB,EAAE,CAG5B;IACF,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,SAAS,CAAwB;IAEzC,IAAI,cAAc,IAAI,MAAM,CAA6C;IAEzE,4FAA4F;IAC5F,IAAI,gBAAgB,IAAI,MAAM,CAAoD;IAElF,uEAAuE;IACvE,IAAI,WAAW,IAAI,MAAM,CAAsE;IAE/F,4FAA4F;IAC5F,IAAI,kBAAkB,IAAI,MAAM,CAAsD;IAEtF,uEAAuE;IACvE,IAAI,aAAa,IAAI,MAAM,CAA4D;IAEvF,eAAe,IAAI,IAAI;IAEvB,MAAM,IAAI,IAAI;IACd,IAAI,IAAI,IAAI;IAKZ,KAAK,IAAI,IAAI;IAEb,8CAA8C;IAC9C,OAAO,CAAC,aAAa,CAAS;IAC9B,4FAA4F;IAC5F,OAAO,CAAC,YAAY,CAAS;IAE7B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,YAAY;IAOpB,aAAa,IAAI,IAAI;IACrB,SAAS,IAAI,IAAI;IAEjB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAKlC,WAAW,IAAI,IAAI;IAKnB,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO;IAIxC,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO;IAKvC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAKjC,MAAM,IAAI,IAAI;IACd,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAIrC,UAAU,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI;IAI7C,gBAAgB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IACxD,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IACvC,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;IAC3C,WAAW,IAAI,IAAI;yCAtHR,qBAAqB;2CAArB,qBAAqB;CAuHjC"}
|
|
@@ -2,12 +2,15 @@ import { Component, Input, Output, EventEmitter, forwardRef, HostBinding, ViewCh
|
|
|
2
2
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
3
|
import { OverlayModule } from '@angular/cdk/overlay';
|
|
4
4
|
import { WEEK_DAYS, BuildCalendarWeeks, FormatDate, GetMonthYearLabel } from '../calendar/calendar-utils';
|
|
5
|
+
import { MJNamedControlBase } from '../a11y/named-control.base';
|
|
6
|
+
import { WarnIfUnnamed } from '../a11y/unnamed-control-guard';
|
|
5
7
|
import * as i0 from "@angular/core";
|
|
6
8
|
import * as i1 from "@angular/cdk/overlay";
|
|
7
9
|
const _c0 = ["trigger"];
|
|
10
|
+
const _c1 = ["dateInput"];
|
|
8
11
|
const _forTrack0 = ($index, $item) => $item.date.getTime();
|
|
9
|
-
function
|
|
10
|
-
i0.ɵɵelementStart(0, "span",
|
|
12
|
+
function MJDatepickerComponent_ng_template_11_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
13
|
+
i0.ɵɵelementStart(0, "span", 16);
|
|
11
14
|
i0.ɵɵtext(1);
|
|
12
15
|
i0.ɵɵelementEnd();
|
|
13
16
|
} if (rf & 2) {
|
|
@@ -15,10 +18,10 @@ function MJDatepickerComponent_ng_template_7_For_10_Template(rf, ctx) { if (rf &
|
|
|
15
18
|
i0.ɵɵadvance();
|
|
16
19
|
i0.ɵɵtextInterpolate(day_r3);
|
|
17
20
|
} }
|
|
18
|
-
function
|
|
21
|
+
function MJDatepickerComponent_ng_template_11_For_12_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
19
22
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
20
|
-
i0.ɵɵelementStart(0, "button",
|
|
21
|
-
i0.ɵɵlistener("click", function
|
|
23
|
+
i0.ɵɵelementStart(0, "button", 21);
|
|
24
|
+
i0.ɵɵlistener("click", function MJDatepickerComponent_ng_template_11_For_12_For_2_Template_button_click_0_listener() { const day_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectDate(day_r5)); });
|
|
22
25
|
i0.ɵɵtext(1);
|
|
23
26
|
i0.ɵɵelementEnd();
|
|
24
27
|
} if (rf & 2) {
|
|
@@ -30,38 +33,39 @@ function MJDatepickerComponent_ng_template_7_For_12_For_2_Template(rf, ctx) { if
|
|
|
30
33
|
i0.ɵɵadvance();
|
|
31
34
|
i0.ɵɵtextInterpolate(day_r5.dayNumber);
|
|
32
35
|
} }
|
|
33
|
-
function
|
|
34
|
-
i0.ɵɵelementStart(0, "div",
|
|
35
|
-
i0.ɵɵrepeaterCreate(1,
|
|
36
|
+
function MJDatepickerComponent_ng_template_11_For_12_Template(rf, ctx) { if (rf & 1) {
|
|
37
|
+
i0.ɵɵelementStart(0, "div", 17);
|
|
38
|
+
i0.ɵɵrepeaterCreate(1, MJDatepickerComponent_ng_template_11_For_12_For_2_Template, 2, 9, "button", 20, _forTrack0);
|
|
36
39
|
i0.ɵɵelementEnd();
|
|
37
40
|
} if (rf & 2) {
|
|
38
41
|
const week_r6 = ctx.$implicit;
|
|
39
42
|
i0.ɵɵadvance();
|
|
40
43
|
i0.ɵɵrepeater(week_r6);
|
|
41
44
|
} }
|
|
42
|
-
function
|
|
45
|
+
function MJDatepickerComponent_ng_template_11_Template(rf, ctx) { if (rf & 1) {
|
|
43
46
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
44
|
-
i0.ɵɵelementStart(0, "div",
|
|
45
|
-
i0.ɵɵlistener("click", function
|
|
46
|
-
i0.ɵɵelement(3, "i",
|
|
47
|
+
i0.ɵɵelementStart(0, "div", 8)(1, "div", 9)(2, "button", 10);
|
|
48
|
+
i0.ɵɵlistener("click", function MJDatepickerComponent_ng_template_11_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.PreviousMonth()); });
|
|
49
|
+
i0.ɵɵelement(3, "i", 11);
|
|
47
50
|
i0.ɵɵelementEnd();
|
|
48
|
-
i0.ɵɵelementStart(4, "span",
|
|
51
|
+
i0.ɵɵelementStart(4, "span", 12);
|
|
49
52
|
i0.ɵɵtext(5);
|
|
50
53
|
i0.ɵɵelementEnd();
|
|
51
|
-
i0.ɵɵelementStart(6, "button",
|
|
52
|
-
i0.ɵɵlistener("click", function
|
|
53
|
-
i0.ɵɵelement(7, "i",
|
|
54
|
+
i0.ɵɵelementStart(6, "button", 13);
|
|
55
|
+
i0.ɵɵlistener("click", function MJDatepickerComponent_ng_template_11_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.NextMonth()); });
|
|
56
|
+
i0.ɵɵelement(7, "i", 14);
|
|
54
57
|
i0.ɵɵelementEnd()();
|
|
55
|
-
i0.ɵɵelementStart(8, "div",
|
|
56
|
-
i0.ɵɵrepeaterCreate(9,
|
|
58
|
+
i0.ɵɵelementStart(8, "div", 15);
|
|
59
|
+
i0.ɵɵrepeaterCreate(9, MJDatepickerComponent_ng_template_11_For_10_Template, 2, 1, "span", 16, i0.ɵɵrepeaterTrackByIdentity);
|
|
57
60
|
i0.ɵɵelementEnd();
|
|
58
|
-
i0.ɵɵrepeaterCreate(11,
|
|
59
|
-
i0.ɵɵelementStart(13, "div",
|
|
60
|
-
i0.ɵɵlistener("click", function
|
|
61
|
+
i0.ɵɵrepeaterCreate(11, MJDatepickerComponent_ng_template_11_For_12_Template, 3, 0, "div", 17, i0.ɵɵrepeaterTrackByIndex);
|
|
62
|
+
i0.ɵɵelementStart(13, "div", 18)(14, "button", 19);
|
|
63
|
+
i0.ɵɵlistener("click", function MJDatepickerComponent_ng_template_11_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SelectToday()); });
|
|
61
64
|
i0.ɵɵtext(15, "Today");
|
|
62
65
|
i0.ɵɵelementEnd()()();
|
|
63
66
|
} if (rf & 2) {
|
|
64
67
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
68
|
+
i0.ɵɵattribute("aria-labelledby", ctx_r1.CalendarLabelledBy || null)("aria-label", ctx_r1.CalendarLabelledBy ? null : ctx_r1.CalendarLabel);
|
|
65
69
|
i0.ɵɵadvance(5);
|
|
66
70
|
i0.ɵɵtextInterpolate(ctx_r1.MonthYearLabel);
|
|
67
71
|
i0.ɵɵadvance(4);
|
|
@@ -71,8 +75,20 @@ function MJDatepickerComponent_ng_template_7_Template(rf, ctx) { if (rf & 1) {
|
|
|
71
75
|
} }
|
|
72
76
|
/**
|
|
73
77
|
* mj-datepicker — Date picker with calendar popup. Replaces `<kendo-datepicker>`.
|
|
78
|
+
*
|
|
79
|
+
* Without an accessible name the date field announces as "edit, blank" and its calendar popup as a
|
|
80
|
+
* generic "Calendar" — so a form with a start date and an end date presents two identical grids
|
|
81
|
+
* (WCAG 2.1 4.1.2). Use {@link MJNamedControlBase.AriaLabelledBy} when a visible label exists,
|
|
82
|
+
* {@link MJNamedControlBase.AriaLabel} when none does; the toggle button and the calendar take
|
|
83
|
+
* their names from the same source. The field is a real `<input>`, so
|
|
84
|
+
* {@link MJNamedControlBase.InputId} IS a valid `<label for>` target.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```html
|
|
88
|
+
* <mj-datepicker AriaLabel="Due date" [(ngModel)]="dueDate" [Min]="minDate" />
|
|
89
|
+
* ```
|
|
74
90
|
*/
|
|
75
|
-
export class MJDatepickerComponent {
|
|
91
|
+
export class MJDatepickerComponent extends MJNamedControlBase {
|
|
76
92
|
Min = null;
|
|
77
93
|
Max = null;
|
|
78
94
|
Format = 'MM/dd/yyyy';
|
|
@@ -87,6 +103,7 @@ export class MJDatepickerComponent {
|
|
|
87
103
|
get Disabled() { return this.disabledInput; }
|
|
88
104
|
ValueChange = new EventEmitter();
|
|
89
105
|
triggerEl;
|
|
106
|
+
dateInputEl;
|
|
90
107
|
hostClass = true;
|
|
91
108
|
cdr = inject(ChangeDetectorRef);
|
|
92
109
|
IsOpen = false;
|
|
@@ -103,6 +120,15 @@ export class MJDatepickerComponent {
|
|
|
103
120
|
onChange = () => { };
|
|
104
121
|
onTouched = () => { };
|
|
105
122
|
get MonthYearLabel() { return GetMonthYearLabel(this.viewDate); }
|
|
123
|
+
/** `aria-labelledby` id list for the toggle button when a VISIBLE label names the field. */
|
|
124
|
+
get ToggleLabelledBy() { return this.SecondaryLabelledBy('toggle-word'); }
|
|
125
|
+
/** `aria-label` for the toggle button in the no-visible-label case. */
|
|
126
|
+
get ToggleLabel() { return this.SecondaryLabel('Open calendar for', 'Open calendar'); }
|
|
127
|
+
/** `aria-labelledby` id list for the calendar grid when a VISIBLE label names the field. */
|
|
128
|
+
get CalendarLabelledBy() { return this.SecondaryLabelledBy('calendar-word'); }
|
|
129
|
+
/** `aria-label` for the calendar grid in the no-visible-label case. */
|
|
130
|
+
get CalendarLabel() { return this.SecondaryLabel('Calendar for', 'Calendar'); }
|
|
131
|
+
ngAfterViewInit() { WarnIfUnnamed(this.dateInputEl?.nativeElement, 'mj-datepicker'); }
|
|
106
132
|
Toggle() { if (this.IsDisabled)
|
|
107
133
|
return; this.IsOpen ? this.Close() : this.Open(); }
|
|
108
134
|
Open() {
|
|
@@ -206,49 +232,76 @@ export class MJDatepickerComponent {
|
|
|
206
232
|
registerOnTouched(fn) { this.onTouched = fn; }
|
|
207
233
|
setDisabledState(isDisabled) { this.formDisabled = isDisabled; this.syncDisabled(); }
|
|
208
234
|
ngOnDestroy() { this.Close(); }
|
|
209
|
-
static ɵfac = function MJDatepickerComponent_Factory(__ngFactoryType__) { return
|
|
235
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵMJDatepickerComponent_BaseFactory; return function MJDatepickerComponent_Factory(__ngFactoryType__) { return (ɵMJDatepickerComponent_BaseFactory || (ɵMJDatepickerComponent_BaseFactory = i0.ɵɵgetInheritedFactory(MJDatepickerComponent)))(__ngFactoryType__ || MJDatepickerComponent); }; })();
|
|
210
236
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJDatepickerComponent, selectors: [["mj-datepicker"]], viewQuery: function MJDatepickerComponent_Query(rf, ctx) { if (rf & 1) {
|
|
211
|
-
i0.ɵɵviewQuery(_c0, 5);
|
|
237
|
+
i0.ɵɵviewQuery(_c0, 5)(_c1, 5);
|
|
212
238
|
} if (rf & 2) {
|
|
213
239
|
let _t;
|
|
214
240
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.triggerEl = _t.first);
|
|
241
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.dateInputEl = _t.first);
|
|
215
242
|
} }, hostVars: 2, hostBindings: function MJDatepickerComponent_HostBindings(rf, ctx) { if (rf & 2) {
|
|
216
243
|
i0.ɵɵclassProp("mj-datepicker-host", ctx.hostClass);
|
|
217
|
-
} }, inputs: { Min: "Min", Max: "Max", Format: "Format", Placeholder: "Placeholder", Disabled: "Disabled" }, outputs: { ValueChange: "ValueChange" }, features: [i0.ɵɵProvidersFeature([{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJDatepickerComponent), multi: true }])], decls:
|
|
244
|
+
} }, inputs: { Min: "Min", Max: "Max", Format: "Format", Placeholder: "Placeholder", Disabled: "Disabled" }, outputs: { ValueChange: "ValueChange" }, features: [i0.ɵɵProvidersFeature([{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJDatepickerComponent), multi: true }]), i0.ɵɵInheritDefinitionFeature], decls: 12, vars: 18, consts: [["trigger", "", "overlayOrigin", "cdkOverlayOrigin"], ["dateInput", ""], ["cdkOverlayOrigin", "", 1, "mj-datepicker"], ["type", "text", 1, "mj-input", "mj-datepicker-input", 3, "input", "blur", "keydown", "placeholder", "disabled", "value"], ["aria-hidden", "true", 1, "mj-datepicker-sr-only"], ["type", "button", "tabindex", "-1", 1, "mj-datepicker-toggle", 3, "click", "disabled"], [1, "fa-solid", "fa-calendar"], ["cdkConnectedOverlay", "", "cdkConnectedOverlayBackdropClass", "mj-dropdown-backdrop", 3, "backdropClick", "detach", "cdkConnectedOverlayOrigin", "cdkConnectedOverlayOpen", "cdkConnectedOverlayPositions", "cdkConnectedOverlayHasBackdrop"], ["role", "grid", 1, "mj-calendar"], [1, "mj-calendar-header"], ["type", "button", "aria-label", "Previous month", 1, "mj-calendar-nav", 3, "click"], [1, "fa-solid", "fa-chevron-left"], [1, "mj-calendar-title"], ["type", "button", "aria-label", "Next month", 1, "mj-calendar-nav", 3, "click"], [1, "fa-solid", "fa-chevron-right"], ["role", "row", 1, "mj-calendar-weekdays"], ["role", "columnheader", 1, "mj-calendar-weekday"], ["role", "row", 1, "mj-calendar-row"], [1, "mj-calendar-footer"], ["type", "button", 1, "mj-calendar-today", 3, "click"], ["type", "button", "role", "gridcell", 1, "mj-calendar-day", 3, "mj-calendar-day--selected", "mj-calendar-day--today", "mj-calendar-day--other-month", "disabled"], ["type", "button", "role", "gridcell", 1, "mj-calendar-day", 3, "click", "disabled"]], template: function MJDatepickerComponent_Template(rf, ctx) { if (rf & 1) {
|
|
218
245
|
i0.ɵɵelementStart(0, "div", 2, 0)(3, "input", 3, 1);
|
|
219
246
|
i0.ɵɵlistener("input", function MJDatepickerComponent_Template_input_input_3_listener($event) { return ctx.OnInputChange($event); })("blur", function MJDatepickerComponent_Template_input_blur_3_listener() { return ctx.OnBlur(); })("keydown", function MJDatepickerComponent_Template_input_keydown_3_listener($event) { return ctx.OnKeyDown($event); });
|
|
220
247
|
i0.ɵɵelementEnd();
|
|
221
|
-
i0.ɵɵelementStart(5, "
|
|
222
|
-
i0.ɵɵ
|
|
223
|
-
i0.ɵɵ
|
|
248
|
+
i0.ɵɵelementStart(5, "span", 4);
|
|
249
|
+
i0.ɵɵtext(6, "Open calendar for");
|
|
250
|
+
i0.ɵɵelementEnd();
|
|
251
|
+
i0.ɵɵelementStart(7, "span", 4);
|
|
252
|
+
i0.ɵɵtext(8, "Calendar for");
|
|
253
|
+
i0.ɵɵelementEnd();
|
|
254
|
+
i0.ɵɵelementStart(9, "button", 5);
|
|
255
|
+
i0.ɵɵlistener("click", function MJDatepickerComponent_Template_button_click_9_listener() { return ctx.Toggle(); });
|
|
256
|
+
i0.ɵɵelement(10, "i", 6);
|
|
224
257
|
i0.ɵɵelementEnd()();
|
|
225
|
-
i0.ɵɵtemplate(
|
|
226
|
-
i0.ɵɵlistener("backdropClick", function
|
|
258
|
+
i0.ɵɵtemplate(11, MJDatepickerComponent_ng_template_11_Template, 16, 3, "ng-template", 7);
|
|
259
|
+
i0.ɵɵlistener("backdropClick", function MJDatepickerComponent_Template_ng_template_backdropClick_11_listener() { return ctx.Close(); })("detach", function MJDatepickerComponent_Template_ng_template_detach_11_listener() { return ctx.Close(); });
|
|
227
260
|
} if (rf & 2) {
|
|
228
261
|
const overlayOrigin_r7 = i0.ɵɵreference(2);
|
|
229
262
|
i0.ɵɵclassProp("mj-datepicker--disabled", ctx.IsDisabled);
|
|
230
263
|
i0.ɵɵadvance(3);
|
|
231
264
|
i0.ɵɵproperty("placeholder", ctx.Placeholder)("disabled", ctx.IsDisabled)("value", ctx.DisplayValue);
|
|
265
|
+
i0.ɵɵattribute("id", ctx.InputId || null)("aria-label", ctx.AriaLabel || null)("aria-labelledby", ctx.AriaLabelledBy || null)("aria-describedby", ctx.AriaDescribedBy || null);
|
|
266
|
+
i0.ɵɵadvance(2);
|
|
267
|
+
i0.ɵɵattribute("id", ctx.SecondaryWordId("toggle-word"));
|
|
268
|
+
i0.ɵɵadvance(2);
|
|
269
|
+
i0.ɵɵattribute("id", ctx.SecondaryWordId("calendar-word"));
|
|
232
270
|
i0.ɵɵadvance(2);
|
|
233
271
|
i0.ɵɵproperty("disabled", ctx.IsDisabled);
|
|
272
|
+
i0.ɵɵattribute("aria-labelledby", ctx.ToggleLabelledBy || null)("aria-label", ctx.ToggleLabelledBy ? null : ctx.ToggleLabel);
|
|
234
273
|
i0.ɵɵadvance(2);
|
|
235
274
|
i0.ɵɵproperty("cdkConnectedOverlayOrigin", overlayOrigin_r7)("cdkConnectedOverlayOpen", ctx.IsOpen)("cdkConnectedOverlayPositions", ctx.Positions)("cdkConnectedOverlayHasBackdrop", true);
|
|
236
|
-
} }, dependencies: [OverlayModule, i1.CdkConnectedOverlay, i1.CdkOverlayOrigin],
|
|
275
|
+
} }, dependencies: [OverlayModule, i1.CdkConnectedOverlay, i1.CdkOverlayOrigin], styles: ["\n\n\n\n\n\n\n\n\n .mj-datepicker-sr-only[_ngcontent-%COMP%] {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }"] });
|
|
237
276
|
}
|
|
238
277
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJDatepickerComponent, [{
|
|
239
278
|
type: Component,
|
|
240
|
-
args: [{
|
|
241
|
-
selector: 'mj-datepicker',
|
|
242
|
-
standalone: true,
|
|
243
|
-
imports: [OverlayModule],
|
|
244
|
-
template: `
|
|
279
|
+
args: [{ selector: 'mj-datepicker', standalone: true, imports: [OverlayModule], template: `
|
|
245
280
|
<div class="mj-datepicker" #trigger cdkOverlayOrigin #overlayOrigin="cdkOverlayOrigin"
|
|
246
281
|
[class.mj-datepicker--disabled]="IsDisabled">
|
|
247
282
|
<input #dateInput class="mj-input mj-datepicker-input" type="text"
|
|
283
|
+
[attr.id]="InputId || null"
|
|
284
|
+
[attr.aria-label]="AriaLabel || null"
|
|
285
|
+
[attr.aria-labelledby]="AriaLabelledBy || null"
|
|
286
|
+
[attr.aria-describedby]="AriaDescribedBy || null"
|
|
248
287
|
[placeholder]="Placeholder" [disabled]="IsDisabled" [value]="DisplayValue"
|
|
249
288
|
(input)="OnInputChange($event)" (blur)="OnBlur()" (keydown)="OnKeyDown($event)" />
|
|
289
|
+
<!--
|
|
290
|
+
The fixed words live in hidden spans rather than in concatenated strings so the
|
|
291
|
+
AriaLabelledBy path can name the toggle and the calendar from the same visible label that
|
|
292
|
+
names the field: aria-labelledby takes an ID LIST, so the word plus the label's own text is
|
|
293
|
+
composed by the accessibility tree without this component ever seeing that text. The
|
|
294
|
+
calendar's word sits here, outside the overlay, because ids resolve document-wide.
|
|
295
|
+
A hidden node that is DIRECTLY referenced by aria-labelledby is still included in the name
|
|
296
|
+
(accname §4.1), so aria-hidden keeps the word out of the reading order without costing the
|
|
297
|
+
composed name.
|
|
298
|
+
-->
|
|
299
|
+
<span class="mj-datepicker-sr-only" aria-hidden="true" [attr.id]="SecondaryWordId('toggle-word')">Open calendar for</span>
|
|
300
|
+
<span class="mj-datepicker-sr-only" aria-hidden="true" [attr.id]="SecondaryWordId('calendar-word')">Calendar for</span>
|
|
250
301
|
<button type="button" class="mj-datepicker-toggle" tabindex="-1" [disabled]="IsDisabled"
|
|
251
|
-
(click)="Toggle()"
|
|
302
|
+
(click)="Toggle()"
|
|
303
|
+
[attr.aria-labelledby]="ToggleLabelledBy || null"
|
|
304
|
+
[attr.aria-label]="ToggleLabelledBy ? null : ToggleLabel">
|
|
252
305
|
<i class="fa-solid fa-calendar"></i>
|
|
253
306
|
</button>
|
|
254
307
|
</div>
|
|
@@ -256,7 +309,9 @@ export class MJDatepickerComponent {
|
|
|
256
309
|
[cdkConnectedOverlayOpen]="IsOpen" [cdkConnectedOverlayPositions]="Positions"
|
|
257
310
|
[cdkConnectedOverlayHasBackdrop]="true" cdkConnectedOverlayBackdropClass="mj-dropdown-backdrop"
|
|
258
311
|
(backdropClick)="Close()" (detach)="Close()">
|
|
259
|
-
<div class="mj-calendar" role="grid"
|
|
312
|
+
<div class="mj-calendar" role="grid"
|
|
313
|
+
[attr.aria-labelledby]="CalendarLabelledBy || null"
|
|
314
|
+
[attr.aria-label]="CalendarLabelledBy ? null : CalendarLabel">
|
|
260
315
|
<div class="mj-calendar-header">
|
|
261
316
|
<button type="button" (click)="PreviousMonth()" aria-label="Previous month" class="mj-calendar-nav">
|
|
262
317
|
<i class="fa-solid fa-chevron-left"></i></button>
|
|
@@ -284,9 +339,7 @@ export class MJDatepickerComponent {
|
|
|
284
339
|
</div>
|
|
285
340
|
</div>
|
|
286
341
|
</ng-template>
|
|
287
|
-
`,
|
|
288
|
-
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJDatepickerComponent), multi: true }]
|
|
289
|
-
}]
|
|
342
|
+
`, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJDatepickerComponent), multi: true }], styles: ["\n /*\n * Component-scoped ON PURPOSE, unlike the rest of this control's styling, which ships as a global\n * stylesheet the host application imports. A host that skips that import gets unstyled chrome \u2014\n * survivable \u2014 but a hidden-word span that is not hidden renders its word as literal text in the\n * middle of the field. The rule that hides it therefore has to travel with the component.\n *\n * Not display:none or visibility:hidden \u2014 both remove the element from the accessibility tree,\n * which is the one thing this element exists to be in.\n */\n .mj-datepicker-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n "] }]
|
|
290
343
|
}], null, { Min: [{
|
|
291
344
|
type: Input
|
|
292
345
|
}], Max: [{
|
|
@@ -302,9 +355,12 @@ export class MJDatepickerComponent {
|
|
|
302
355
|
}], triggerEl: [{
|
|
303
356
|
type: ViewChild,
|
|
304
357
|
args: ['trigger']
|
|
358
|
+
}], dateInputEl: [{
|
|
359
|
+
type: ViewChild,
|
|
360
|
+
args: ['dateInput']
|
|
305
361
|
}], hostClass: [{
|
|
306
362
|
type: HostBinding,
|
|
307
363
|
args: ['class.mj-datepicker-host']
|
|
308
364
|
}] }); })();
|
|
309
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDatepickerComponent, { className: "MJDatepickerComponent", filePath: "lib/datepicker/datepicker.component.ts", lineNumber:
|
|
365
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDatepickerComponent, { className: "MJDatepickerComponent", filePath: "lib/datepicker/datepicker.component.ts", lineNumber: 115 }); })();
|
|
310
366
|
//# sourceMappingURL=datepicker.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datepicker.component.js","sourceRoot":"","sources":["../../../src/lib/datepicker/datepicker.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, forwardRef, HostBinding, ElementRef, ViewChild, OnDestroy, inject, ChangeDetectorRef } from '@angular/core';\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';\nimport { OverlayModule, ConnectedPosition } from '@angular/cdk/overlay';\nimport { CalendarDay, WEEK_DAYS, BuildCalendarWeeks, FormatDate, GetMonthYearLabel } from '../calendar/calendar-utils';\n\n/**\n * mj-datepicker — Date picker with calendar popup. Replaces `<kendo-datepicker>`.\n */\n@Component({\n selector: 'mj-datepicker',\n standalone: true,\n imports: [OverlayModule],\n template: `\n <div class=\"mj-datepicker\" #trigger cdkOverlayOrigin #overlayOrigin=\"cdkOverlayOrigin\"\n [class.mj-datepicker--disabled]=\"IsDisabled\">\n <input #dateInput class=\"mj-input mj-datepicker-input\" type=\"text\"\n [placeholder]=\"Placeholder\" [disabled]=\"IsDisabled\" [value]=\"DisplayValue\"\n (input)=\"OnInputChange($event)\" (blur)=\"OnBlur()\" (keydown)=\"OnKeyDown($event)\" />\n <button type=\"button\" class=\"mj-datepicker-toggle\" tabindex=\"-1\" [disabled]=\"IsDisabled\"\n (click)=\"Toggle()\" aria-label=\"Open calendar\">\n <i class=\"fa-solid fa-calendar\"></i>\n </button>\n </div>\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"IsOpen\" [cdkConnectedOverlayPositions]=\"Positions\"\n [cdkConnectedOverlayHasBackdrop]=\"true\" cdkConnectedOverlayBackdropClass=\"mj-dropdown-backdrop\"\n (backdropClick)=\"Close()\" (detach)=\"Close()\">\n <div class=\"mj-calendar\" role=\"grid\" aria-label=\"Calendar\">\n <div class=\"mj-calendar-header\">\n <button type=\"button\" (click)=\"PreviousMonth()\" aria-label=\"Previous month\" class=\"mj-calendar-nav\">\n <i class=\"fa-solid fa-chevron-left\"></i></button>\n <span class=\"mj-calendar-title\">{{ MonthYearLabel }}</span>\n <button type=\"button\" (click)=\"NextMonth()\" aria-label=\"Next month\" class=\"mj-calendar-nav\">\n <i class=\"fa-solid fa-chevron-right\"></i></button>\n </div>\n <div class=\"mj-calendar-weekdays\" role=\"row\">\n @for (day of WeekDays; track day) { <span class=\"mj-calendar-weekday\" role=\"columnheader\">{{ day }}</span> }\n </div>\n @for (week of Weeks; track $index) {\n <div class=\"mj-calendar-row\" role=\"row\">\n @for (day of week; track day.date.getTime()) {\n <button type=\"button\" class=\"mj-calendar-day\" role=\"gridcell\"\n [class.mj-calendar-day--selected]=\"IsSelectedDay(day)\"\n [class.mj-calendar-day--today]=\"day.isToday\"\n [class.mj-calendar-day--other-month]=\"!day.isCurrentMonth\"\n [disabled]=\"IsOutOfRange(day)\" [attr.aria-selected]=\"IsSelectedDay(day)\"\n (click)=\"SelectDate(day)\">{{ day.dayNumber }}</button>\n }\n </div>\n }\n <div class=\"mj-calendar-footer\">\n <button type=\"button\" class=\"mj-calendar-today\" (click)=\"SelectToday()\">Today</button>\n </div>\n </div>\n </ng-template>\n `,\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJDatepickerComponent), multi: true }]\n})\nexport class MJDatepickerComponent implements ControlValueAccessor, OnDestroy {\n @Input() Min: Date | null = null;\n @Input() Max: Date | null = null;\n @Input() Format = 'MM/dd/yyyy';\n @Input() Placeholder = '';\n /**\n * Host-driven disable. Composed with Angular Forms' `setDisabledState()` into `IsDisabled`\n * (the actual gate) — see `syncDisabled`. A setter, not a bare field, because this input is\n * routinely bound to an expression that changes over the control's lifetime, and the gate has\n * to follow it every time.\n */\n @Input()\n set Disabled(value: boolean) { this.disabledInput = value; this.syncDisabled(); }\n get Disabled(): boolean { return this.disabledInput; }\n @Output() ValueChange = new EventEmitter<Date | null>();\n @ViewChild('trigger') private triggerEl!: ElementRef<HTMLElement>;\n @HostBinding('class.mj-datepicker-host') readonly hostClass = true;\n private cdr = inject(ChangeDetectorRef);\n\n IsOpen = false; IsDisabled = false; DisplayValue = '';\n Weeks: CalendarDay[][] = []; WeekDays = WEEK_DAYS;\n Positions: ConnectedPosition[] = [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' }\n ];\n private viewDate = new Date();\n private selectedDate: Date | null = null;\n private onChange: (value: Date | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n get MonthYearLabel(): string { return GetMonthYearLabel(this.viewDate); }\n\n Toggle(): void { if (this.IsDisabled) return; this.IsOpen ? this.Close() : this.Open(); }\n Open(): void {\n if (this.IsDisabled || this.IsOpen) return;\n this.viewDate = this.selectedDate ? new Date(this.selectedDate) : new Date();\n this.Weeks = BuildCalendarWeeks(this.viewDate); this.IsOpen = true; this.cdr.detectChanges();\n }\n Close(): void { if (!this.IsOpen) return; this.IsOpen = false; this.cdr.detectChanges(); }\n\n /** Backing field for the `Disabled` input. */\n private disabledInput = false;\n /** The forms-driven disabled state, kept SEPARATE so neither source can stomp the other. */\n private formDisabled = false;\n\n /**\n * Recompute the gate from both of its sources. Called whenever either changes.\n *\n * `IsDisabled` is derived state, and the only thing that assigned it was `setDisabledState()`.\n * The forms-driven half was in fact fine — `setUpControl` also wires `registerOnDisabledChange`,\n * so that hook fires on every `control.disable()`/`enable()`, not just at registration. What had\n * no recompute path at all was the `Disabled` @Input: a plain field, so the gate froze at\n * whatever the first compose produced and every later change to the input was dropped.\n *\n * Closes the calendar directly rather than via `Close()`: this can run from an @Input setter,\n * i.e. DURING the parent's CD pass, where a nested `detectChanges()` trips NG0100.\n */\n private syncDisabled(): void {\n const disabled = this.disabledInput || this.formDisabled;\n if (disabled === this.IsDisabled) return;\n this.IsDisabled = disabled;\n if (disabled) this.IsOpen = false;\n this.cdr.markForCheck();\n }\n PreviousMonth(): void { this.viewDate = new Date(this.viewDate.getFullYear(), this.viewDate.getMonth() - 1, 1); this.Weeks = BuildCalendarWeeks(this.viewDate); }\n NextMonth(): void { this.viewDate = new Date(this.viewDate.getFullYear(), this.viewDate.getMonth() + 1, 1); this.Weeks = BuildCalendarWeeks(this.viewDate); }\n\n SelectDate(day: CalendarDay): void {\n if (this.IsOutOfRange(day)) return;\n this.selectedDate = day.date; this.DisplayValue = FormatDate(day.date);\n this.onChange(day.date); this.ValueChange.emit(day.date); this.Close();\n }\n SelectToday(): void {\n const today = new Date(); today.setHours(0, 0, 0, 0);\n this.selectedDate = today; this.DisplayValue = FormatDate(today);\n this.onChange(today); this.ValueChange.emit(today); this.Close();\n }\n IsSelectedDay(day: CalendarDay): boolean {\n if (!this.selectedDate) return false;\n return day.date.getFullYear() === this.selectedDate.getFullYear() && day.date.getMonth() === this.selectedDate.getMonth() && day.date.getDate() === this.selectedDate.getDate();\n }\n IsOutOfRange(day: CalendarDay): boolean {\n if (this.Min && day.date < this.Min) return true;\n if (this.Max && day.date > this.Max) return true;\n return false;\n }\n OnInputChange(event: Event): void {\n const value = (event.target as HTMLInputElement).value; this.DisplayValue = value;\n const parsed = new Date(value);\n if (!isNaN(parsed.getTime())) { this.selectedDate = parsed; this.onChange(parsed); this.ValueChange.emit(parsed); }\n }\n OnBlur(): void { this.onTouched(); }\n OnKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Escape') this.Close();\n else if (event.key === 'Enter' && !this.IsOpen) this.Open();\n }\n writeValue(value: Date | string | null): void {\n if (value == null) { this.selectedDate = null; this.DisplayValue = ''; }\n else { const d = typeof value === 'string' ? new Date(value) : value; if (!isNaN(d.getTime())) { this.selectedDate = d; this.DisplayValue = FormatDate(d); } }\n }\n registerOnChange(fn: (value: Date | null) => void): void { this.onChange = fn; }\n registerOnTouched(fn: () => void): void { this.onTouched = fn; }\n setDisabledState(isDisabled: boolean): void { this.formDisabled = isDisabled; this.syncDisabled(); }\n ngOnDestroy(): void { this.Close(); }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"datepicker.component.js","sourceRoot":"","sources":["../../../src/lib/datepicker/datepicker.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { AfterViewInit, Component, Input, Output, EventEmitter, forwardRef, HostBinding, ElementRef, ViewChild, OnDestroy, inject, ChangeDetectorRef } from '@angular/core';\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';\nimport { OverlayModule, ConnectedPosition } from '@angular/cdk/overlay';\nimport { CalendarDay, WEEK_DAYS, BuildCalendarWeeks, FormatDate, GetMonthYearLabel } from '../calendar/calendar-utils';\nimport { MJNamedControlBase } from '../a11y/named-control.base';\nimport { WarnIfUnnamed } from '../a11y/unnamed-control-guard';\n\n/**\n * mj-datepicker — Date picker with calendar popup. Replaces `<kendo-datepicker>`.\n *\n * Without an accessible name the date field announces as \"edit, blank\" and its calendar popup as a\n * generic \"Calendar\" — so a form with a start date and an end date presents two identical grids\n * (WCAG 2.1 4.1.2). Use {@link MJNamedControlBase.AriaLabelledBy} when a visible label exists,\n * {@link MJNamedControlBase.AriaLabel} when none does; the toggle button and the calendar take\n * their names from the same source. The field is a real `<input>`, so\n * {@link MJNamedControlBase.InputId} IS a valid `<label for>` target.\n *\n * @example\n * ```html\n * <mj-datepicker AriaLabel=\"Due date\" [(ngModel)]=\"dueDate\" [Min]=\"minDate\" />\n * ```\n */\n@Component({\n selector: 'mj-datepicker',\n standalone: true,\n imports: [OverlayModule],\n template: `\n <div class=\"mj-datepicker\" #trigger cdkOverlayOrigin #overlayOrigin=\"cdkOverlayOrigin\"\n [class.mj-datepicker--disabled]=\"IsDisabled\">\n <input #dateInput class=\"mj-input mj-datepicker-input\" type=\"text\"\n [attr.id]=\"InputId || null\"\n [attr.aria-label]=\"AriaLabel || null\"\n [attr.aria-labelledby]=\"AriaLabelledBy || null\"\n [attr.aria-describedby]=\"AriaDescribedBy || null\"\n [placeholder]=\"Placeholder\" [disabled]=\"IsDisabled\" [value]=\"DisplayValue\"\n (input)=\"OnInputChange($event)\" (blur)=\"OnBlur()\" (keydown)=\"OnKeyDown($event)\" />\n <!--\n The fixed words live in hidden spans rather than in concatenated strings so the\n AriaLabelledBy path can name the toggle and the calendar from the same visible label that\n names the field: aria-labelledby takes an ID LIST, so the word plus the label's own text is\n composed by the accessibility tree without this component ever seeing that text. The\n calendar's word sits here, outside the overlay, because ids resolve document-wide.\n A hidden node that is DIRECTLY referenced by aria-labelledby is still included in the name\n (accname §4.1), so aria-hidden keeps the word out of the reading order without costing the\n composed name.\n -->\n <span class=\"mj-datepicker-sr-only\" aria-hidden=\"true\" [attr.id]=\"SecondaryWordId('toggle-word')\">Open calendar for</span>\n <span class=\"mj-datepicker-sr-only\" aria-hidden=\"true\" [attr.id]=\"SecondaryWordId('calendar-word')\">Calendar for</span>\n <button type=\"button\" class=\"mj-datepicker-toggle\" tabindex=\"-1\" [disabled]=\"IsDisabled\"\n (click)=\"Toggle()\"\n [attr.aria-labelledby]=\"ToggleLabelledBy || null\"\n [attr.aria-label]=\"ToggleLabelledBy ? null : ToggleLabel\">\n <i class=\"fa-solid fa-calendar\"></i>\n </button>\n </div>\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"IsOpen\" [cdkConnectedOverlayPositions]=\"Positions\"\n [cdkConnectedOverlayHasBackdrop]=\"true\" cdkConnectedOverlayBackdropClass=\"mj-dropdown-backdrop\"\n (backdropClick)=\"Close()\" (detach)=\"Close()\">\n <div class=\"mj-calendar\" role=\"grid\"\n [attr.aria-labelledby]=\"CalendarLabelledBy || null\"\n [attr.aria-label]=\"CalendarLabelledBy ? null : CalendarLabel\">\n <div class=\"mj-calendar-header\">\n <button type=\"button\" (click)=\"PreviousMonth()\" aria-label=\"Previous month\" class=\"mj-calendar-nav\">\n <i class=\"fa-solid fa-chevron-left\"></i></button>\n <span class=\"mj-calendar-title\">{{ MonthYearLabel }}</span>\n <button type=\"button\" (click)=\"NextMonth()\" aria-label=\"Next month\" class=\"mj-calendar-nav\">\n <i class=\"fa-solid fa-chevron-right\"></i></button>\n </div>\n <div class=\"mj-calendar-weekdays\" role=\"row\">\n @for (day of WeekDays; track day) { <span class=\"mj-calendar-weekday\" role=\"columnheader\">{{ day }}</span> }\n </div>\n @for (week of Weeks; track $index) {\n <div class=\"mj-calendar-row\" role=\"row\">\n @for (day of week; track day.date.getTime()) {\n <button type=\"button\" class=\"mj-calendar-day\" role=\"gridcell\"\n [class.mj-calendar-day--selected]=\"IsSelectedDay(day)\"\n [class.mj-calendar-day--today]=\"day.isToday\"\n [class.mj-calendar-day--other-month]=\"!day.isCurrentMonth\"\n [disabled]=\"IsOutOfRange(day)\" [attr.aria-selected]=\"IsSelectedDay(day)\"\n (click)=\"SelectDate(day)\">{{ day.dayNumber }}</button>\n }\n </div>\n }\n <div class=\"mj-calendar-footer\">\n <button type=\"button\" class=\"mj-calendar-today\" (click)=\"SelectToday()\">Today</button>\n </div>\n </div>\n </ng-template>\n `,\n styles: [`\n /*\n * Component-scoped ON PURPOSE, unlike the rest of this control's styling, which ships as a global\n * stylesheet the host application imports. A host that skips that import gets unstyled chrome —\n * survivable — but a hidden-word span that is not hidden renders its word as literal text in the\n * middle of the field. The rule that hides it therefore has to travel with the component.\n *\n * Not display:none or visibility:hidden — both remove the element from the accessibility tree,\n * which is the one thing this element exists to be in.\n */\n .mj-datepicker-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n `],\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJDatepickerComponent), multi: true }]\n})\nexport class MJDatepickerComponent extends MJNamedControlBase implements ControlValueAccessor, AfterViewInit, OnDestroy {\n @Input() Min: Date | null = null;\n @Input() Max: Date | null = null;\n @Input() Format = 'MM/dd/yyyy';\n @Input() Placeholder = '';\n /**\n * Host-driven disable. Composed with Angular Forms' `setDisabledState()` into `IsDisabled`\n * (the actual gate) — see `syncDisabled`. A setter, not a bare field, because this input is\n * routinely bound to an expression that changes over the control's lifetime, and the gate has\n * to follow it every time.\n */\n @Input()\n set Disabled(value: boolean) { this.disabledInput = value; this.syncDisabled(); }\n get Disabled(): boolean { return this.disabledInput; }\n @Output() ValueChange = new EventEmitter<Date | null>();\n @ViewChild('trigger') private triggerEl!: ElementRef<HTMLElement>;\n @ViewChild('dateInput') private dateInputEl: ElementRef<HTMLInputElement> | undefined;\n @HostBinding('class.mj-datepicker-host') readonly hostClass = true;\n private cdr = inject(ChangeDetectorRef);\n\n IsOpen = false; IsDisabled = false; DisplayValue = '';\n Weeks: CalendarDay[][] = []; WeekDays = WEEK_DAYS;\n Positions: ConnectedPosition[] = [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' }\n ];\n private viewDate = new Date();\n private selectedDate: Date | null = null;\n private onChange: (value: Date | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n get MonthYearLabel(): string { return GetMonthYearLabel(this.viewDate); }\n\n /** `aria-labelledby` id list for the toggle button when a VISIBLE label names the field. */\n get ToggleLabelledBy(): string { return this.SecondaryLabelledBy('toggle-word'); }\n\n /** `aria-label` for the toggle button in the no-visible-label case. */\n get ToggleLabel(): string { return this.SecondaryLabel('Open calendar for', 'Open calendar'); }\n\n /** `aria-labelledby` id list for the calendar grid when a VISIBLE label names the field. */\n get CalendarLabelledBy(): string { return this.SecondaryLabelledBy('calendar-word'); }\n\n /** `aria-label` for the calendar grid in the no-visible-label case. */\n get CalendarLabel(): string { return this.SecondaryLabel('Calendar for', 'Calendar'); }\n\n ngAfterViewInit(): void { WarnIfUnnamed(this.dateInputEl?.nativeElement, 'mj-datepicker'); }\n\n Toggle(): void { if (this.IsDisabled) return; this.IsOpen ? this.Close() : this.Open(); }\n Open(): void {\n if (this.IsDisabled || this.IsOpen) return;\n this.viewDate = this.selectedDate ? new Date(this.selectedDate) : new Date();\n this.Weeks = BuildCalendarWeeks(this.viewDate); this.IsOpen = true; this.cdr.detectChanges();\n }\n Close(): void { if (!this.IsOpen) return; this.IsOpen = false; this.cdr.detectChanges(); }\n\n /** Backing field for the `Disabled` input. */\n private disabledInput = false;\n /** The forms-driven disabled state, kept SEPARATE so neither source can stomp the other. */\n private formDisabled = false;\n\n /**\n * Recompute the gate from both of its sources. Called whenever either changes.\n *\n * `IsDisabled` is derived state, and the only thing that assigned it was `setDisabledState()`.\n * The forms-driven half was in fact fine — `setUpControl` also wires `registerOnDisabledChange`,\n * so that hook fires on every `control.disable()`/`enable()`, not just at registration. What had\n * no recompute path at all was the `Disabled` @Input: a plain field, so the gate froze at\n * whatever the first compose produced and every later change to the input was dropped.\n *\n * Closes the calendar directly rather than via `Close()`: this can run from an @Input setter,\n * i.e. DURING the parent's CD pass, where a nested `detectChanges()` trips NG0100.\n */\n private syncDisabled(): void {\n const disabled = this.disabledInput || this.formDisabled;\n if (disabled === this.IsDisabled) return;\n this.IsDisabled = disabled;\n if (disabled) this.IsOpen = false;\n this.cdr.markForCheck();\n }\n PreviousMonth(): void { this.viewDate = new Date(this.viewDate.getFullYear(), this.viewDate.getMonth() - 1, 1); this.Weeks = BuildCalendarWeeks(this.viewDate); }\n NextMonth(): void { this.viewDate = new Date(this.viewDate.getFullYear(), this.viewDate.getMonth() + 1, 1); this.Weeks = BuildCalendarWeeks(this.viewDate); }\n\n SelectDate(day: CalendarDay): void {\n if (this.IsOutOfRange(day)) return;\n this.selectedDate = day.date; this.DisplayValue = FormatDate(day.date);\n this.onChange(day.date); this.ValueChange.emit(day.date); this.Close();\n }\n SelectToday(): void {\n const today = new Date(); today.setHours(0, 0, 0, 0);\n this.selectedDate = today; this.DisplayValue = FormatDate(today);\n this.onChange(today); this.ValueChange.emit(today); this.Close();\n }\n IsSelectedDay(day: CalendarDay): boolean {\n if (!this.selectedDate) return false;\n return day.date.getFullYear() === this.selectedDate.getFullYear() && day.date.getMonth() === this.selectedDate.getMonth() && day.date.getDate() === this.selectedDate.getDate();\n }\n IsOutOfRange(day: CalendarDay): boolean {\n if (this.Min && day.date < this.Min) return true;\n if (this.Max && day.date > this.Max) return true;\n return false;\n }\n OnInputChange(event: Event): void {\n const value = (event.target as HTMLInputElement).value; this.DisplayValue = value;\n const parsed = new Date(value);\n if (!isNaN(parsed.getTime())) { this.selectedDate = parsed; this.onChange(parsed); this.ValueChange.emit(parsed); }\n }\n OnBlur(): void { this.onTouched(); }\n OnKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Escape') this.Close();\n else if (event.key === 'Enter' && !this.IsOpen) this.Open();\n }\n writeValue(value: Date | string | null): void {\n if (value == null) { this.selectedDate = null; this.DisplayValue = ''; }\n else { const d = typeof value === 'string' ? new Date(value) : value; if (!isNaN(d.getTime())) { this.selectedDate = d; this.DisplayValue = FormatDate(d); } }\n }\n registerOnChange(fn: (value: Date | null) => void): void { this.onChange = fn; }\n registerOnTouched(fn: () => void): void { this.onTouched = fn; }\n setDisabledState(isDisabled: boolean): void { this.formDisabled = isDisabled; this.syncDisabled(); }\n ngOnDestroy(): void { this.Close(); }\n}\n"]}
|
|
@@ -41,7 +41,11 @@ export declare class MJDialogComponent implements OnDestroy {
|
|
|
41
41
|
Close: EventEmitter<void>;
|
|
42
42
|
DialogId: number;
|
|
43
43
|
get dialogId(): number;
|
|
44
|
+
get ResolvedWidth(): string;
|
|
45
|
+
/** @deprecated Use {@link ResolvedWidth}. */
|
|
44
46
|
get resolvedWidth(): string;
|
|
47
|
+
get ResolvedHeight(): string;
|
|
48
|
+
/** @deprecated Use {@link ResolvedHeight}. */
|
|
45
49
|
get resolvedHeight(): string;
|
|
46
50
|
OnEscapeKey(): void;
|
|
47
51
|
OnBackdropClick(event: Event): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.component.d.ts","sourceRoot":"","sources":["../../../src/lib/dialog/dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAKZ,SAAS,EAEV,MAAM,eAAe,CAAC;;AAEvB,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAU9D;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBA2Ca,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAK;IAE1B,IACI,OAAO,CAAC,KAAK,EAAE,OAAO,EASzB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IAEQ,KAAK,SAAM;IACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IACrC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IACtC,IAAI,EAAE,YAAY,CAAU;IAC5B,SAAS,UAAQ;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC;;;;;OAKG;IACM,IAAI,EAAE,QAAQ,GAAG,aAAa,CAAY;IAEzC,KAAK,qBAA4B;IAE3C,QAAQ,SAA8B;IAEtC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,aAAa,IAAI,MAAM,CAK1B;IAED,IAAI,cAAc,IAAI,MAAM,CAK3B;IAGD,WAAW,IAAI,IAAI;IAMnB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAMnC,YAAY,IAAI,IAAI;IAIpB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,eAAe;IAIvB,WAAW,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"dialog.component.d.ts","sourceRoot":"","sources":["../../../src/lib/dialog/dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAKZ,SAAS,EAEV,MAAM,eAAe,CAAC;;AAEvB,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAU9D;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBA2Ca,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAK;IAE1B,IACI,OAAO,CAAC,KAAK,EAAE,OAAO,EASzB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IAEQ,KAAK,SAAM;IACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IACrC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IACtC,IAAI,EAAE,YAAY,CAAU;IAC5B,SAAS,UAAQ;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC;;;;;OAKG;IACM,IAAI,EAAE,QAAQ,GAAG,aAAa,CAAY;IAEzC,KAAK,qBAA4B;IAE3C,QAAQ,SAA8B;IAEtC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,aAAa,IAAI,MAAM,CAK1B;IAED,6CAA6C;IAC7C,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,cAAc,IAAI,MAAM,CAK3B;IAED,8CAA8C;IAC9C,IAAI,cAAc,IAAI,MAAM,CAE3B;IAGD,WAAW,IAAI,IAAI;IAMnB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAMnC,YAAY,IAAI,IAAI;IAIpB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,eAAe;IAIvB,WAAW,IAAI,IAAI;yCA3FR,iBAAiB;2CAAjB,iBAAiB;CA8F7B;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAKa,yBAAyB;yCAAzB,yBAAyB;2CAAzB,yBAAyB;CAAG;AAEzC;;;;;;;;;;;;GAYG;AACH,qBASa,wBAAwB;yCAAxB,wBAAwB;2CAAxB,wBAAwB;CAAG"}
|
|
@@ -113,18 +113,26 @@ export class MJDialogComponent {
|
|
|
113
113
|
get dialogId() {
|
|
114
114
|
return this.DialogId;
|
|
115
115
|
}
|
|
116
|
-
get
|
|
116
|
+
get ResolvedWidth() {
|
|
117
117
|
if (this.Width) {
|
|
118
118
|
return typeof this.Width === 'number' ? `${this.Width}px` : this.Width;
|
|
119
119
|
}
|
|
120
120
|
return SIZE_MAP[this.Size] ?? 'auto';
|
|
121
121
|
}
|
|
122
|
-
|
|
122
|
+
/** @deprecated Use {@link ResolvedWidth}. */
|
|
123
|
+
get resolvedWidth() {
|
|
124
|
+
return this.ResolvedWidth;
|
|
125
|
+
}
|
|
126
|
+
get ResolvedHeight() {
|
|
123
127
|
if (this.Height) {
|
|
124
128
|
return typeof this.Height === 'number' ? `${this.Height}px` : this.Height;
|
|
125
129
|
}
|
|
126
130
|
return 'auto';
|
|
127
131
|
}
|
|
132
|
+
/** @deprecated Use {@link ResolvedHeight}. */
|
|
133
|
+
get resolvedHeight() {
|
|
134
|
+
return this.ResolvedHeight;
|
|
135
|
+
}
|
|
128
136
|
OnEscapeKey() {
|
|
129
137
|
if (this.Visible && this.Closeable) {
|
|
130
138
|
this.OnCloseClick();
|
|
@@ -255,7 +263,7 @@ export class MJDialogTitlebarComponent {
|
|
|
255
263
|
template: `<ng-content></ng-content>`
|
|
256
264
|
}]
|
|
257
265
|
}], null, null); })();
|
|
258
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDialogTitlebarComponent, { className: "MJDialogTitlebarComponent", filePath: "lib/dialog/dialog.component.ts", lineNumber:
|
|
266
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDialogTitlebarComponent, { className: "MJDialogTitlebarComponent", filePath: "lib/dialog/dialog.component.ts", lineNumber: 202 }); })();
|
|
259
267
|
/**
|
|
260
268
|
* mj-dialog-actions — Footer action bar for mj-dialog.
|
|
261
269
|
*
|
|
@@ -290,5 +298,5 @@ export class MJDialogActionsComponent {
|
|
|
290
298
|
`
|
|
291
299
|
}]
|
|
292
300
|
}], null, null); })();
|
|
293
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDialogActionsComponent, { className: "MJDialogActionsComponent", filePath: "lib/dialog/dialog.component.ts", lineNumber:
|
|
301
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDialogActionsComponent, { className: "MJDialogActionsComponent", filePath: "lib/dialog/dialog.component.ts", lineNumber: 226 }); })();
|
|
294
302
|
//# sourceMappingURL=dialog.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.component.js","sourceRoot":"","sources":["../../../src/lib/dialog/dialog.component.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"dialog.component.js","sourceRoot":"","sources":["../../../src/lib/dialog/dialog.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n HostListener,\n ElementRef,\n ViewChild,\n AfterViewInit,\n OnDestroy,\n inject\n} from '@angular/core';\n\nexport type MjDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'auto';\n\nconst SIZE_MAP: Record<MjDialogSize, string> = {\n sm: '400px',\n md: '600px',\n lg: '800px',\n xl: '1000px',\n auto: 'auto'\n};\n\n/**\n * mj-dialog — Modal dialog component using native `<dialog>` element.\n *\n * Replaces `<kendo-dialog>`.\n *\n * Supports both explicit width/height and size presets.\n * Content is projected, with an optional `<mj-dialog-actions>` for the footer.\n *\n * @example\n * ```html\n * <mj-dialog [Visible]=\"showDialog\" Title=\"Confirm\" (Close)=\"onClose()\">\n * <p>Are you sure?</p>\n * <mj-dialog-actions>\n * <button mjButton variant=\"primary\" (click)=\"onConfirm()\">Yes</button>\n * <button mjButton (click)=\"onClose()\">No</button>\n * </mj-dialog-actions>\n * </mj-dialog>\n * ```\n */\n@Component({\n selector: 'mj-dialog',\n standalone: true,\n template: `\n @if (Visible) {\n <div class=\"mj-dialog-backdrop\" (click)=\"OnBackdropClick($event)\">\n <div class=\"mj-dialog-container\"\n [attr.role]=\"Role\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"Title ? 'mj-dialog-title-' + dialogId : null\"\n [style.width]=\"resolvedWidth\"\n [style.height]=\"resolvedHeight\"\n [style.max-width]=\"'90vw'\"\n [style.max-height]=\"'90vh'\"\n (click)=\"$event.stopPropagation()\">\n\n <!-- Title bar -->\n @if (Title || Closeable) {\n <div class=\"mj-dialog-titlebar\">\n @if (Title) {\n <h2 class=\"mj-dialog-title\" [id]=\"'mj-dialog-title-' + dialogId\">{{ Title }}</h2>\n }\n <ng-content select=\"mj-dialog-titlebar\"></ng-content>\n @if (Closeable) {\n <button class=\"mj-dialog-close\" (click)=\"OnCloseClick()\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Body -->\n <div class=\"mj-dialog-body\">\n <ng-content></ng-content>\n </div>\n\n <!-- Actions (projected) -->\n <ng-content select=\"mj-dialog-actions\"></ng-content>\n </div>\n </div>\n }\n `\n})\nexport class MJDialogComponent implements OnDestroy {\n private _visible = false;\n private static nextId = 0;\n\n @Input()\n set Visible(value: boolean) {\n const wasVisible = this._visible;\n this._visible = value;\n if (value && !wasVisible) {\n this.onOpen();\n }\n if (!value && wasVisible) {\n this.onCloseInternal();\n }\n }\n get Visible(): boolean {\n return this._visible;\n }\n\n @Input() Title = '';\n @Input() Width: number | string | null = null;\n @Input() Height: number | string | null = null;\n @Input() Size: MjDialogSize = 'auto';\n @Input() Closeable = true;\n @Input() MinWidth: number | null = null;\n\n /**\n * ARIA role for the dialog container. Defaults to `'dialog'`; pass\n * `'alertdialog'` for confirmation / destructive prompts that interrupt the\n * user (per WAI-ARIA, an alertdialog conveys an urgent message requiring a\n * response). Backward compatible — existing callers keep `'dialog'`.\n */\n @Input() Role: 'dialog' | 'alertdialog' = 'dialog';\n\n @Output() Close = new EventEmitter<void>();\n\n DialogId = MJDialogComponent.nextId++;\n\n get dialogId(): number { // case-violation-ok-legacy-back-compat: the PascalCase name is already taken in this scope\n return this.DialogId;\n }\n\n get ResolvedWidth(): string {\n if (this.Width) {\n return typeof this.Width === 'number' ? `${this.Width}px` : this.Width;\n }\n return SIZE_MAP[this.Size] ?? 'auto';\n }\n\n /** @deprecated Use {@link ResolvedWidth}. */\n get resolvedWidth(): string {\n return this.ResolvedWidth;\n }\n\n get ResolvedHeight(): string {\n if (this.Height) {\n return typeof this.Height === 'number' ? `${this.Height}px` : this.Height;\n }\n return 'auto';\n }\n\n /** @deprecated Use {@link ResolvedHeight}. */\n get resolvedHeight(): string {\n return this.ResolvedHeight;\n }\n\n @HostListener('document:keydown.escape')\n OnEscapeKey(): void {\n if (this.Visible && this.Closeable) {\n this.OnCloseClick();\n }\n }\n\n OnBackdropClick(event: Event): void {\n if (this.Closeable) {\n this.OnCloseClick();\n }\n }\n\n OnCloseClick(): void {\n this.Close.emit();\n }\n\n private onOpen(): void {\n document.body.style.overflow = 'hidden';\n }\n\n private onCloseInternal(): void {\n document.body.style.overflow = '';\n }\n\n ngOnDestroy(): void {\n document.body.style.overflow = '';\n }\n}\n\n/**\n * mj-dialog-titlebar — Custom titlebar content for mj-dialog.\n *\n * Replaces `<kendo-dialog-titlebar>`.\n *\n * @example\n * ```html\n * <mj-dialog [Visible]=\"show\" (Close)=\"onClose()\">\n * <mj-dialog-titlebar>\n * <i class=\"fa-solid fa-save\"></i> Custom Title\n * </mj-dialog-titlebar>\n * <p>Dialog content</p>\n * </mj-dialog>\n * ```\n */\n@Component({\n selector: 'mj-dialog-titlebar',\n standalone: true,\n template: `<ng-content></ng-content>`\n})\nexport class MJDialogTitlebarComponent {}\n\n/**\n * mj-dialog-actions — Footer action bar for mj-dialog.\n *\n * Replaces `<kendo-dialog-actions>`.\n *\n * @example\n * ```html\n * <mj-dialog-actions>\n * <button mjButton variant=\"primary\">Save</button>\n * <button mjButton>Cancel</button>\n * </mj-dialog-actions>\n * ```\n */\n@Component({\n selector: 'mj-dialog-actions',\n standalone: true,\n template: `\n <div class=\"mj-dialog-actions\">\n <ng-content></ng-content>\n </div>\n `\n})\nexport class MJDialogActionsComponent {}\n"]}
|