@eagami/ui 5.65.0 → 5.66.0

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,7 +1,7 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ApplicationRef, CSP_NONCE, ChangeDetectionStrategy, Component, DOCUMENT, DestroyRef, Directive, ElementRef, EnvironmentInjector, HostAttributeToken, HostBinding, HostListener, Injectable, InjectionToken, Injector, PLATFORM_ID, Renderer2, RendererStyleFlags2, TemplateRef, ViewContainerRef, ViewEncapsulation, afterNextRender, afterRenderEffect, computed, contentChild, createComponent, effect, forwardRef, inject, input, linkedSignal, makeEnvironmentProviders, model, output, provideEnvironmentInitializer, signal, untracked, viewChild, viewChildren } from "@angular/core";
3
3
  import { NgClass, NgComponentOutlet, NgTemplateOutlet, isPlatformBrowser } from "@angular/common";
4
- import { NG_VALUE_ACCESSOR, NgControl, TouchedChangeEvent } from "@angular/forms";
4
+ import { FormSubmittedEvent, NG_VALUE_ACCESSOR, NgControl, TouchedChangeEvent } from "@angular/forms";
5
5
  const EAGAMI_I18N_CONFIG = new InjectionToken("EAGAMI_I18N_CONFIG");
6
6
  const STYLE_TAG_ID = "eagami-palette";
7
7
  function applyPalette(palette, nonce) {
@@ -5426,32 +5426,73 @@ i0.ɵɵngDeclareClassMetadata({
5426
5426
  function controlErrorStateFrom(control, config) {
5427
5427
  const i18n = inject(EagamiI18nService);
5428
5428
  const press = inject(PointerPressTracker);
5429
+ const injector = inject(Injector);
5430
+ const destroyRef = inject(DestroyRef);
5431
+ const host = inject(ElementRef, { optional: true });
5429
5432
  const revision = signal(0, ...ngDevMode ? [{ debugName: "revision" }] : /* istanbul ignore next */ []);
5433
+ const editing = signal(false, ...ngDevMode ? [{ debugName: "editing" }] : /* istanbul ignore next */ []);
5434
+ const revealedBySubmit = signal(false, ...ngDevMode ? [{ debugName: "revealedBySubmit" }] : /* istanbul ignore next */ []);
5430
5435
  const revealPending = signal(false, ...ngDevMode ? [{ debugName: "revealPending" }] : /* istanbul ignore next */ []);
5436
+ let dropPendingReveal = null;
5437
+ const holdRevealForPress = () => {
5438
+ dropPendingReveal?.();
5439
+ revealPending.set(true);
5440
+ dropPendingReveal = press.whenPressEnds(() => revealPending.set(false));
5441
+ };
5442
+ destroyRef.onDestroy(() => dropPendingReveal?.());
5431
5443
  effect((onCleanup) => {
5432
5444
  const ctrl = control();
5433
5445
  if (!ctrl) return;
5434
- let dropPendingReveal = null;
5446
+ const onSubmit = () => revealedBySubmit.set(true);
5435
5447
  const sub = ctrl.events.subscribe((event) => {
5436
- if (event instanceof TouchedChangeEvent && event.touched) {
5437
- dropPendingReveal?.();
5438
- revealPending.set(true);
5439
- dropPendingReveal = press.whenPressEnds(() => revealPending.set(false));
5440
- }
5448
+ if (event instanceof TouchedChangeEvent && event.touched) holdRevealForPress();
5449
+ if (event instanceof FormSubmittedEvent) onSubmit();
5441
5450
  revision.update((r) => r + 1);
5442
5451
  });
5452
+ const rootSub = ctrl.root === ctrl ? null : ctrl.root.events.subscribe((event) => {
5453
+ if (event instanceof FormSubmittedEvent) onSubmit();
5454
+ });
5443
5455
  onCleanup(() => {
5444
5456
  sub.unsubscribe();
5457
+ rootSub?.unsubscribe();
5445
5458
  dropPendingReveal?.();
5446
5459
  revealPending.set(false);
5447
5460
  });
5448
5461
  });
5449
- const autoError = computed(() => {
5462
+ if (host) afterNextRender(() => {
5463
+ const element = host.nativeElement;
5464
+ const onFocusIn = () => {
5465
+ editing.set(true);
5466
+ revealedBySubmit.set(false);
5467
+ };
5468
+ const onFocusOut = (event) => {
5469
+ if (event.relatedTarget instanceof Node && element.contains(event.relatedTarget)) return;
5470
+ editing.set(false);
5471
+ revealedBySubmit.set(false);
5472
+ holdRevealForPress();
5473
+ };
5474
+ editing.set(element.contains(document.activeElement));
5475
+ element.addEventListener("focusin", onFocusIn);
5476
+ element.addEventListener("focusout", onFocusOut);
5477
+ destroyRef.onDestroy(() => {
5478
+ element.removeEventListener("focusin", onFocusIn);
5479
+ element.removeEventListener("focusout", onFocusOut);
5480
+ });
5481
+ }, { injector });
5482
+ const validationError = computed(() => {
5450
5483
  revision();
5451
5484
  const ctrl = control();
5452
- if (revealPending() || !ctrl || !ctrl.invalid || !ctrl.touched || !ctrl.errors) return null;
5485
+ if (!ctrl || !ctrl.invalid || !ctrl.touched || !ctrl.errors) return null;
5453
5486
  return resolveValidationMessage(ctrl.errors, config.errorMessages(), i18n.messages());
5454
- }, ...ngDevMode ? [{ debugName: "autoError" }] : /* istanbul ignore next */ []);
5487
+ }, ...ngDevMode ? [{ debugName: "validationError" }] : /* istanbul ignore next */ []);
5488
+ const autoError = linkedSignal({
5489
+ ...ngDevMode ? { debugName: "autoError" } : /* istanbul ignore next */ {},
5490
+ source: () => ({
5491
+ message: validationError(),
5492
+ holding: revealPending() || editing() && !revealedBySubmit()
5493
+ }),
5494
+ computation: ({ message, holding }, previous) => previous?.value || !holding ? message : null
5495
+ });
5455
5496
  const error = computed(() => config.errorMsg() || autoError(), ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
5456
5497
  return {
5457
5498
  error,
@@ -5471,7 +5512,7 @@ function injectControlErrorState(config) {
5471
5512
  return controlErrorStateFrom(control, config);
5472
5513
  }
5473
5514
  function resolveValidationMessage(errors, overrides, messages) {
5474
- const key = Object.keys(errors)[0];
5515
+ const key = Object.keys(errors).find((name) => overrides?.[name] !== null);
5475
5516
  if (!key) return null;
5476
5517
  const override = overrides?.[key];
5477
5518
  if (override) return override;
@@ -32122,6 +32163,7 @@ i0.ɵɵngDeclareClassMetadata({
32122
32163
  var ToggleChipComponent = class ToggleChipComponent {
32123
32164
  selected = model(false, ...ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []);
32124
32165
  size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
32166
+ icon = input(void 0, ...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
32125
32167
  disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
32126
32168
  ariaLabel = input(void 0, {
32127
32169
  ...ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {},
@@ -32151,7 +32193,7 @@ var ToggleChipComponent = class ToggleChipComponent {
32151
32193
  target: i0.ɵɵFactoryTarget.Component
32152
32194
  });
32153
32195
  static ɵcmp = i0.ɵɵngDeclareComponent({
32154
- minVersion: "17.1.0",
32196
+ minVersion: "17.0.0",
32155
32197
  version: "22.2.1",
32156
32198
  type: ToggleChipComponent,
32157
32199
  isStandalone: true,
@@ -32171,6 +32213,13 @@ var ToggleChipComponent = class ToggleChipComponent {
32171
32213
  isRequired: false,
32172
32214
  transformFunction: null
32173
32215
  },
32216
+ icon: {
32217
+ classPropertyName: "icon",
32218
+ publicName: "icon",
32219
+ isSignal: true,
32220
+ isRequired: false,
32221
+ transformFunction: null
32222
+ },
32174
32223
  disabled: {
32175
32224
  classPropertyName: "disabled",
32176
32225
  publicName: "disabled",
@@ -32198,12 +32247,25 @@ var ToggleChipComponent = class ToggleChipComponent {
32198
32247
  changed: "changed"
32199
32248
  },
32200
32249
  ngImport: i0,
32201
- template: "<button\n type=\"button\"\n class=\"ea-toggle-chip\"\n [class]=\"classes()\"\n [attr.aria-pressed]=\"selected()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-describedby]=\"ariaDescribedby() ?? null\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\">\n <span class=\"ea-toggle-chip__content\">\n <ng-content />\n </span>\n <ea-icon-check\n class=\"ea-toggle-chip__check\"\n aria-hidden=\"true\" />\n</button>\n",
32202
- styles: [":host{display:inline-flex;min-width:0}.ea-toggle-chip{display:inline-flex;align-items:center;gap:.375em;min-height:2.25em;padding:.25em .625em .25em .875em;font:inherit;font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-full);background-color:var(--color-bg-base);color:var(--color-text-primary);cursor:pointer;-webkit-user-select:none;user-select:none;appearance:none;transition:var(--transition-colors)}.ea-toggle-chip:hover:not(:disabled){background-color:var(--color-state-hover)}.ea-toggle-chip:active:not(:disabled){background-color:var(--color-state-active)}.ea-toggle-chip:focus-visible{outline:var(--border-width-medium) solid var(--color-border-focus);outline-offset:2px}@media(forced-colors:active){.ea-toggle-chip:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-toggle-chip:disabled{opacity:.5;cursor:default}.ea-toggle-chip--2xs{font-size:var(--font-size-2xs)}.ea-toggle-chip--xs{font-size:var(--font-size-xs)}.ea-toggle-chip--sm{font-size:var(--font-size-sm)}.ea-toggle-chip--md{font-size:var(--font-size-md)}.ea-toggle-chip--lg{font-size:var(--font-size-lg)}.ea-toggle-chip--xl{font-size:var(--font-size-xl)}.ea-toggle-chip--selected{border-color:var(--color-brand-default);background-color:var(--color-brand-subtle);color:var(--color-brand-text)}.ea-toggle-chip--selected:hover:not(:disabled){background-color:var(--color-brand-muted)}.ea-toggle-chip__content{display:inline-flex;align-items:center;gap:.375em;min-width:0}.ea-toggle-chip__check{opacity:0;flex-shrink:0;transition:var(--transition-opacity),var(--transition-transform);transform:scale(.6)}.ea-toggle-chip--selected .ea-toggle-chip__check{opacity:1;transform:none}\n"],
32250
+ template: "<button\n type=\"button\"\n class=\"ea-toggle-chip\"\n [class]=\"classes()\"\n [attr.aria-pressed]=\"selected()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-describedby]=\"ariaDescribedby() ?? null\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\">\n <span class=\"ea-toggle-chip__content\">\n @if (icon(); as iconComponent) {\n <span\n class=\"ea-toggle-chip__icon\"\n aria-hidden=\"true\">\n <ng-container *ngComponentOutlet=\"iconComponent\" />\n </span>\n }\n <ng-content />\n </span>\n <ea-icon-check\n class=\"ea-toggle-chip__check\"\n aria-hidden=\"true\" />\n</button>\n",
32251
+ styles: [":host{display:inline-flex;min-width:0}.ea-toggle-chip{display:inline-flex;align-items:center;gap:.375em;min-height:2.25em;padding:.25em .625em .25em .875em;font:inherit;font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-full);background-color:var(--color-bg-base);color:var(--color-text-primary);cursor:pointer;-webkit-user-select:none;user-select:none;appearance:none;transition:var(--transition-colors)}.ea-toggle-chip:hover:not(:disabled){background-color:var(--color-state-hover)}.ea-toggle-chip:active:not(:disabled){background-color:var(--color-state-active)}.ea-toggle-chip:focus-visible{outline:var(--border-width-medium) solid var(--color-border-focus);outline-offset:2px}@media(forced-colors:active){.ea-toggle-chip:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-toggle-chip:disabled{opacity:.5;cursor:default}.ea-toggle-chip--2xs{font-size:var(--font-size-2xs)}.ea-toggle-chip--xs{font-size:var(--font-size-xs)}.ea-toggle-chip--sm{font-size:var(--font-size-sm)}.ea-toggle-chip--md{font-size:var(--font-size-md)}.ea-toggle-chip--lg{font-size:var(--font-size-lg)}.ea-toggle-chip--xl{font-size:var(--font-size-xl)}.ea-toggle-chip--selected{border-color:var(--color-brand-default);background-color:var(--color-brand-subtle);color:var(--color-brand-text)}.ea-toggle-chip--selected:hover:not(:disabled){background-color:var(--color-brand-muted)}.ea-toggle-chip__icon{display:inline-flex;flex-shrink:0;font-size:var(--icon-inline-size)}.ea-toggle-chip__content{display:inline-flex;align-items:center;gap:.375em;min-width:0}.ea-toggle-chip__check{opacity:0;flex-shrink:0;transition:var(--transition-opacity),var(--transition-transform);transform:scale(.6)}.ea-toggle-chip--selected .ea-toggle-chip__check{opacity:1;transform:none}\n"],
32203
32252
  dependencies: [{
32204
32253
  kind: "component",
32205
32254
  type: CheckIconComponent,
32206
32255
  selector: "ea-icon-check"
32256
+ }, {
32257
+ kind: "directive",
32258
+ type: NgComponentOutlet,
32259
+ selector: "[ngComponentOutlet]",
32260
+ inputs: [
32261
+ "ngComponentOutlet",
32262
+ "ngComponentOutletInputs",
32263
+ "ngComponentOutletInjector",
32264
+ "ngComponentOutletEnvironmentInjector",
32265
+ "ngComponentOutletContent",
32266
+ "ngComponentOutletNgModule"
32267
+ ],
32268
+ exportAs: ["ngComponentOutlet"]
32207
32269
  }],
32208
32270
  changeDetection: i0.ChangeDetectionStrategy.OnPush
32209
32271
  });
@@ -32217,10 +32279,10 @@ i0.ɵɵngDeclareClassMetadata({
32217
32279
  type: Component,
32218
32280
  args: [{
32219
32281
  selector: "ea-toggle-chip",
32220
- imports: [CheckIconComponent],
32282
+ imports: [CheckIconComponent, NgComponentOutlet],
32221
32283
  changeDetection: ChangeDetectionStrategy.OnPush,
32222
- template: "<button\n type=\"button\"\n class=\"ea-toggle-chip\"\n [class]=\"classes()\"\n [attr.aria-pressed]=\"selected()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-describedby]=\"ariaDescribedby() ?? null\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\">\n <span class=\"ea-toggle-chip__content\">\n <ng-content />\n </span>\n <ea-icon-check\n class=\"ea-toggle-chip__check\"\n aria-hidden=\"true\" />\n</button>\n",
32223
- styles: [":host{display:inline-flex;min-width:0}.ea-toggle-chip{display:inline-flex;align-items:center;gap:.375em;min-height:2.25em;padding:.25em .625em .25em .875em;font:inherit;font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-full);background-color:var(--color-bg-base);color:var(--color-text-primary);cursor:pointer;-webkit-user-select:none;user-select:none;appearance:none;transition:var(--transition-colors)}.ea-toggle-chip:hover:not(:disabled){background-color:var(--color-state-hover)}.ea-toggle-chip:active:not(:disabled){background-color:var(--color-state-active)}.ea-toggle-chip:focus-visible{outline:var(--border-width-medium) solid var(--color-border-focus);outline-offset:2px}@media(forced-colors:active){.ea-toggle-chip:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-toggle-chip:disabled{opacity:.5;cursor:default}.ea-toggle-chip--2xs{font-size:var(--font-size-2xs)}.ea-toggle-chip--xs{font-size:var(--font-size-xs)}.ea-toggle-chip--sm{font-size:var(--font-size-sm)}.ea-toggle-chip--md{font-size:var(--font-size-md)}.ea-toggle-chip--lg{font-size:var(--font-size-lg)}.ea-toggle-chip--xl{font-size:var(--font-size-xl)}.ea-toggle-chip--selected{border-color:var(--color-brand-default);background-color:var(--color-brand-subtle);color:var(--color-brand-text)}.ea-toggle-chip--selected:hover:not(:disabled){background-color:var(--color-brand-muted)}.ea-toggle-chip__content{display:inline-flex;align-items:center;gap:.375em;min-width:0}.ea-toggle-chip__check{opacity:0;flex-shrink:0;transition:var(--transition-opacity),var(--transition-transform);transform:scale(.6)}.ea-toggle-chip--selected .ea-toggle-chip__check{opacity:1;transform:none}\n"]
32284
+ template: "<button\n type=\"button\"\n class=\"ea-toggle-chip\"\n [class]=\"classes()\"\n [attr.aria-pressed]=\"selected()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-describedby]=\"ariaDescribedby() ?? null\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\">\n <span class=\"ea-toggle-chip__content\">\n @if (icon(); as iconComponent) {\n <span\n class=\"ea-toggle-chip__icon\"\n aria-hidden=\"true\">\n <ng-container *ngComponentOutlet=\"iconComponent\" />\n </span>\n }\n <ng-content />\n </span>\n <ea-icon-check\n class=\"ea-toggle-chip__check\"\n aria-hidden=\"true\" />\n</button>\n",
32285
+ styles: [":host{display:inline-flex;min-width:0}.ea-toggle-chip{display:inline-flex;align-items:center;gap:.375em;min-height:2.25em;padding:.25em .625em .25em .875em;font:inherit;font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-full);background-color:var(--color-bg-base);color:var(--color-text-primary);cursor:pointer;-webkit-user-select:none;user-select:none;appearance:none;transition:var(--transition-colors)}.ea-toggle-chip:hover:not(:disabled){background-color:var(--color-state-hover)}.ea-toggle-chip:active:not(:disabled){background-color:var(--color-state-active)}.ea-toggle-chip:focus-visible{outline:var(--border-width-medium) solid var(--color-border-focus);outline-offset:2px}@media(forced-colors:active){.ea-toggle-chip:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-toggle-chip:disabled{opacity:.5;cursor:default}.ea-toggle-chip--2xs{font-size:var(--font-size-2xs)}.ea-toggle-chip--xs{font-size:var(--font-size-xs)}.ea-toggle-chip--sm{font-size:var(--font-size-sm)}.ea-toggle-chip--md{font-size:var(--font-size-md)}.ea-toggle-chip--lg{font-size:var(--font-size-lg)}.ea-toggle-chip--xl{font-size:var(--font-size-xl)}.ea-toggle-chip--selected{border-color:var(--color-brand-default);background-color:var(--color-brand-subtle);color:var(--color-brand-text)}.ea-toggle-chip--selected:hover:not(:disabled){background-color:var(--color-brand-muted)}.ea-toggle-chip__icon{display:inline-flex;flex-shrink:0;font-size:var(--icon-inline-size)}.ea-toggle-chip__content{display:inline-flex;align-items:center;gap:.375em;min-width:0}.ea-toggle-chip__check{opacity:0;flex-shrink:0;transition:var(--transition-opacity),var(--transition-transform);transform:scale(.6)}.ea-toggle-chip--selected .ea-toggle-chip__check{opacity:1;transform:none}\n"]
32224
32286
  }]
32225
32287
  }],
32226
32288
  propDecorators: {
@@ -32243,6 +32305,14 @@ i0.ɵɵngDeclareClassMetadata({
32243
32305
  required: false
32244
32306
  }]
32245
32307
  }],
32308
+ icon: [{
32309
+ type: i0.Input,
32310
+ args: [{
32311
+ isSignal: true,
32312
+ alias: "icon",
32313
+ required: false
32314
+ }]
32315
+ }],
32246
32316
  disabled: [{
32247
32317
  type: i0.Input,
32248
32318
  args: [{