forty-cdk 0.6.0 → 0.7.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.
Files changed (136) hide show
  1. package/accordion/README.md +9 -7
  2. package/calendar/README.md +1 -1
  3. package/combobox/README.md +1 -1
  4. package/context-menu/README.md +9 -0
  5. package/date-picker/README.md +12 -13
  6. package/date-range-field/README.md +7 -7
  7. package/dialog/README.md +7 -7
  8. package/drag-drop/README.md +9 -8
  9. package/drawer/README.md +9 -7
  10. package/fesm2022/forty-cdk-accordion.mjs +30 -11
  11. package/fesm2022/forty-cdk-accordion.mjs.map +1 -1
  12. package/fesm2022/forty-cdk-avatar.mjs +4 -3
  13. package/fesm2022/forty-cdk-avatar.mjs.map +1 -1
  14. package/fesm2022/forty-cdk-breakpoints.mjs.map +1 -1
  15. package/fesm2022/forty-cdk-calendar.mjs +1 -1
  16. package/fesm2022/forty-cdk-calendar.mjs.map +1 -1
  17. package/fesm2022/forty-cdk-carousel.mjs +13 -2
  18. package/fesm2022/forty-cdk-carousel.mjs.map +1 -1
  19. package/fesm2022/forty-cdk-combobox.mjs +88 -56
  20. package/fesm2022/forty-cdk-combobox.mjs.map +1 -1
  21. package/fesm2022/forty-cdk-context-menu.mjs +62 -5
  22. package/fesm2022/forty-cdk-context-menu.mjs.map +1 -1
  23. package/fesm2022/forty-cdk-core.mjs +531 -120
  24. package/fesm2022/forty-cdk-core.mjs.map +1 -1
  25. package/fesm2022/forty-cdk-date-field.mjs +12 -0
  26. package/fesm2022/forty-cdk-date-field.mjs.map +1 -1
  27. package/fesm2022/forty-cdk-date-picker.mjs +17 -10
  28. package/fesm2022/forty-cdk-date-picker.mjs.map +1 -1
  29. package/fesm2022/forty-cdk-date-range-field.mjs +26 -5
  30. package/fesm2022/forty-cdk-date-range-field.mjs.map +1 -1
  31. package/fesm2022/forty-cdk-dialog.mjs +47 -11
  32. package/fesm2022/forty-cdk-dialog.mjs.map +1 -1
  33. package/fesm2022/forty-cdk-drag-drop.mjs +50 -7
  34. package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -1
  35. package/fesm2022/forty-cdk-drawer.mjs +38 -18
  36. package/fesm2022/forty-cdk-drawer.mjs.map +1 -1
  37. package/fesm2022/forty-cdk-field.mjs +51 -30
  38. package/fesm2022/forty-cdk-field.mjs.map +1 -1
  39. package/fesm2022/forty-cdk-file-upload.mjs +53 -10
  40. package/fesm2022/forty-cdk-file-upload.mjs.map +1 -1
  41. package/fesm2022/forty-cdk-hover-card.mjs +32 -14
  42. package/fesm2022/forty-cdk-hover-card.mjs.map +1 -1
  43. package/fesm2022/forty-cdk-listbox.mjs +37 -1
  44. package/fesm2022/forty-cdk-listbox.mjs.map +1 -1
  45. package/fesm2022/forty-cdk-menu.mjs +191 -218
  46. package/fesm2022/forty-cdk-menu.mjs.map +1 -1
  47. package/fesm2022/forty-cdk-menubar.mjs +36 -28
  48. package/fesm2022/forty-cdk-menubar.mjs.map +1 -1
  49. package/fesm2022/forty-cdk-navigation-menu.mjs +10 -2
  50. package/fesm2022/forty-cdk-navigation-menu.mjs.map +1 -1
  51. package/fesm2022/forty-cdk-number-input.mjs +32 -10
  52. package/fesm2022/forty-cdk-number-input.mjs.map +1 -1
  53. package/fesm2022/forty-cdk-otp-input.mjs +3 -0
  54. package/fesm2022/forty-cdk-otp-input.mjs.map +1 -1
  55. package/fesm2022/forty-cdk-pagination.mjs +20 -8
  56. package/fesm2022/forty-cdk-pagination.mjs.map +1 -1
  57. package/fesm2022/forty-cdk-pane-resizer.mjs +18 -2
  58. package/fesm2022/forty-cdk-pane-resizer.mjs.map +1 -1
  59. package/fesm2022/forty-cdk-radio-group.mjs +28 -14
  60. package/fesm2022/forty-cdk-radio-group.mjs.map +1 -1
  61. package/fesm2022/forty-cdk-scroll-area.mjs +18 -3
  62. package/fesm2022/forty-cdk-scroll-area.mjs.map +1 -1
  63. package/fesm2022/forty-cdk-select.mjs +58 -12
  64. package/fesm2022/forty-cdk-select.mjs.map +1 -1
  65. package/fesm2022/forty-cdk-slider.mjs +20 -4
  66. package/fesm2022/forty-cdk-slider.mjs.map +1 -1
  67. package/fesm2022/forty-cdk-stepper.mjs +8 -1
  68. package/fesm2022/forty-cdk-stepper.mjs.map +1 -1
  69. package/fesm2022/forty-cdk-table.mjs +272 -25
  70. package/fesm2022/forty-cdk-table.mjs.map +1 -1
  71. package/fesm2022/forty-cdk-time-field.mjs +12 -0
  72. package/fesm2022/forty-cdk-time-field.mjs.map +1 -1
  73. package/fesm2022/forty-cdk-time-range-field.mjs +26 -5
  74. package/fesm2022/forty-cdk-time-range-field.mjs.map +1 -1
  75. package/fesm2022/forty-cdk-toast.mjs +24 -22
  76. package/fesm2022/forty-cdk-toast.mjs.map +1 -1
  77. package/fesm2022/forty-cdk-toggle.mjs +15 -0
  78. package/fesm2022/forty-cdk-toggle.mjs.map +1 -1
  79. package/fesm2022/forty-cdk-tooltip.mjs +53 -25
  80. package/fesm2022/forty-cdk-tooltip.mjs.map +1 -1
  81. package/fesm2022/forty-cdk-tree.mjs +109 -16
  82. package/fesm2022/forty-cdk-tree.mjs.map +1 -1
  83. package/fesm2022/forty-cdk-virtualization.mjs +20 -9
  84. package/fesm2022/forty-cdk-virtualization.mjs.map +1 -1
  85. package/field/README.md +13 -10
  86. package/file-upload/README.md +5 -0
  87. package/menu/README.md +3 -1
  88. package/package.json +1 -1
  89. package/radio-group/README.md +13 -11
  90. package/scroll-area/README.md +18 -2
  91. package/stepper/README.md +2 -2
  92. package/table/README.md +11 -8
  93. package/time-range-field/README.md +7 -7
  94. package/toast/README.md +10 -10
  95. package/tree/README.md +1 -1
  96. package/types/forty-cdk-accordion.d.ts +28 -8
  97. package/types/forty-cdk-calendar.d.ts +5 -17
  98. package/types/forty-cdk-carousel.d.ts +1 -0
  99. package/types/forty-cdk-combobox.d.ts +54 -26
  100. package/types/forty-cdk-context-menu.d.ts +22 -1
  101. package/types/forty-cdk-core.d.ts +270 -44
  102. package/types/forty-cdk-date-field.d.ts +8 -1
  103. package/types/forty-cdk-date-picker.d.ts +14 -12
  104. package/types/forty-cdk-date-range-field.d.ts +23 -10
  105. package/types/forty-cdk-dialog.d.ts +57 -8
  106. package/types/forty-cdk-drag-drop.d.ts +1 -0
  107. package/types/forty-cdk-drawer.d.ts +44 -14
  108. package/types/forty-cdk-dropdown-menu.d.ts +1 -0
  109. package/types/forty-cdk-field.d.ts +20 -13
  110. package/types/forty-cdk-file-upload.d.ts +13 -1
  111. package/types/forty-cdk-hover-card.d.ts +11 -1
  112. package/types/forty-cdk-internationalized-date.d.ts +1 -0
  113. package/types/forty-cdk-listbox.d.ts +17 -0
  114. package/types/forty-cdk-menu.d.ts +87 -49
  115. package/types/forty-cdk-menubar.d.ts +16 -9
  116. package/types/forty-cdk-navigation-menu.d.ts +2 -1
  117. package/types/forty-cdk-number-input.d.ts +15 -3
  118. package/types/forty-cdk-pagination.d.ts +24 -2
  119. package/types/forty-cdk-pane-resizer.d.ts +10 -0
  120. package/types/forty-cdk-popover.d.ts +1 -0
  121. package/types/forty-cdk-radio-group.d.ts +24 -12
  122. package/types/forty-cdk-scroll-area.d.ts +16 -1
  123. package/types/forty-cdk-select.d.ts +38 -0
  124. package/types/forty-cdk-slider.d.ts +10 -0
  125. package/types/forty-cdk-stepper.d.ts +7 -0
  126. package/types/forty-cdk-table.d.ts +80 -8
  127. package/types/forty-cdk-tabs.d.ts +1 -0
  128. package/types/forty-cdk-time-field.d.ts +8 -1
  129. package/types/forty-cdk-time-picker.d.ts +1 -0
  130. package/types/forty-cdk-time-range-field.d.ts +23 -10
  131. package/types/forty-cdk-toast.d.ts +3 -3
  132. package/types/forty-cdk-toggle.d.ts +10 -0
  133. package/types/forty-cdk-toolbar.d.ts +1 -0
  134. package/types/forty-cdk-tooltip.d.ts +41 -6
  135. package/types/forty-cdk-tree.d.ts +17 -1
  136. package/types/forty-cdk-virtualization.d.ts +16 -0
@@ -1 +1 @@
1
- {"version":3,"file":"forty-cdk-avatar.mjs","sources":["../../../projects/forty-cdk/avatar/src/avatar-context.ts","../../../projects/forty-cdk/avatar/src/avatar-defaults.ts","../../../projects/forty-cdk/avatar/src/avatar.ts","../../../projects/forty-cdk/avatar/src/avatar-image.ts","../../../projects/forty-cdk/avatar/src/avatar-fallback.ts","../../../projects/forty-cdk/avatar/src/forty-cdk-avatar.ts"],"sourcesContent":["import { inject, InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Lifecycle stages of the avatar's image:\n * - `idle`: no `src` set yet.\n * - `loading`: `src` set, waiting for the network.\n * - `loaded`: image rendered successfully.\n * - `error`: image failed to load.\n */\nexport type ForAvatarStatus = 'idle' | 'loading' | 'loaded' | 'error';\n\nexport interface ForAvatarContext {\n /** Current status of the avatar's image. */\n readonly status: Signal<ForAvatarStatus>;\n /**\n * `true` when the consumer should render the fallback. Drives `@if` in\n * the consumer's template. Honors `fallbackDelayMs` for `idle` / `loading`\n * states; `error` flips it to `true` immediately.\n */\n readonly shouldShowFallback: Signal<boolean>;\n /**\n * Internal — reported by `[forAvatarImage]` so the root can transition\n * its state machine. Consumers should not call this.\n */\n reportStatus(status: ForAvatarStatus): void;\n}\n\nexport const FOR_AVATAR_CONTEXT = new InjectionToken<ForAvatarContext>('FOR_AVATAR_CONTEXT');\n\n/**\n * Injects the nearest {@link ForAvatarContext}, throwing a descriptive error\n * when used outside a `[forAvatar]` element.\n *\n * @param piece Name of the calling directive, used in the error message.\n */\nexport function injectAvatarContext(piece: string): ForAvatarContext {\n const ctx = inject(FOR_AVATAR_CONTEXT, { optional: true });\n if (!ctx) {\n throw new Error(`[forty-cdk/avatar] ${piece} must be used inside a [forAvatar] element.`);\n }\n return ctx;\n}\n","import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * Defaults inherited by descendant avatars in the surrounding injector\n * scope. Configure with `provideForAvatarDefaults` either at the\n * application root or in any component's `providers` array; partial\n * overrides merge with the parent scope.\n */\nexport interface ForAvatarDefaults {\n /**\n * Milliseconds to defer the fallback for fast loads, avoiding a brief\n * \"initials → image\" flicker. Set to `0` to show immediately during\n * `idle` / `loading`, or to e.g. `500` to skip rendering during quick\n * cached loads. `error` always shows the fallback immediately.\n */\n fallbackDelayMs: number;\n}\n\n/**\n * Library fallback for avatar defaults, read at the root injector when no\n * consumer has called `provideForAvatarDefaults`. Exported for the shared defaults\n * contract spec; not re-exported from the primitive's public entry.\n */\nexport const FOR_AVATAR_FALLBACK_DEFAULTS: ForAvatarDefaults = {\n fallbackDelayMs: 0,\n};\n\nconst { token, provideDefaults } = createDefaults<ForAvatarDefaults>(\n 'FOR_AVATAR_DEFAULTS',\n FOR_AVATAR_FALLBACK_DEFAULTS,\n);\n\n/** Token holding the resolved avatar defaults for the current scope. */\nexport const FOR_AVATAR_DEFAULTS = token;\n\n/**\n * Configures forty-cdk avatar defaults for this injector scope. Partial\n * overrides inherit unspecified keys from the parent scope (or library\n * defaults at the root).\n */\nexport function provideForAvatarDefaults(defaults: Partial<ForAvatarDefaults> = {}): Provider[] {\n return provideDefaults(defaults);\n}\n","import {\n computed,\n DestroyRef,\n Directive,\n effect,\n inject,\n input,\n linkedSignal,\n numberAttribute,\n signal,\n} from '@angular/core';\n\nimport { FOR_AVATAR_CONTEXT, type ForAvatarContext, type ForAvatarStatus } from './avatar-context';\nimport { FOR_AVATAR_DEFAULTS } from './avatar-defaults';\n\n/**\n * Headless avatar root. Tracks the load lifecycle of an inner\n * `[forAvatarImage]` and exposes `status` + `shouldShowFallback` so the\n * consumer can swap the image for fallback content (initials, generic icon)\n * via `@if`.\n *\n * No ARIA role is imposed — avatars are typically presentational. If the\n * surrounding component conveys identity (a person's name in the header,\n * a chat bubble), the consumer should provide an `aria-label` on the\n * relevant ancestor or pair the avatar with visible text.\n *\n * @example\n * ```html\n * <span forAvatar #a=\"forAvatar\" fallbackDelayMs=\"500\">\n * <img forAvatarImage [src]=\"user.avatarUrl\" [alt]=\"user.name\" />\n * @if (a.shouldShowFallback()) {\n * <span forAvatarFallback>{{ user.initials }}</span>\n * }\n * </span>\n * ```\n */\n@Directive({\n selector: '[forAvatar]',\n exportAs: 'forAvatar',\n host: {\n '[attr.data-status]': 'status()',\n },\n providers: [{ provide: FOR_AVATAR_CONTEXT, useExisting: ForAvatar }],\n})\nexport class ForAvatar implements ForAvatarContext {\n readonly #defaults = inject(FOR_AVATAR_DEFAULTS);\n\n /**\n * Milliseconds to defer the fallback for fast loads, avoiding a brief\n * \"initials → image\" flicker. Set to `0` (default) to show immediately\n * during `idle` / `loading`, or to e.g. `500` to skip rendering during\n * quick cached loads. `error` always shows the fallback immediately.\n * The default is read from `provideForAvatarDefaults` for the\n * surrounding scope.\n */\n readonly fallbackDelayMs = input(this.#defaults.fallbackDelayMs, {\n transform: numberAttribute,\n });\n\n readonly #status = signal<ForAvatarStatus>('idle');\n readonly status = this.#status.asReadonly();\n\n // Whether the deferred-fallback timer has fired for the current status/delay.\n // `linkedSignal` resets it to `false` whenever the source changes (the\n // canonical replacement for resetting state inside an effect); the timer\n // callback in the constructor flips it to `true`.\n readonly #timerElapsed = linkedSignal<{ status: ForAvatarStatus; delay: number }, boolean>({\n source: () => ({ status: this.#status(), delay: this.fallbackDelayMs() }),\n computation: () => false,\n });\n #timer: ReturnType<typeof setTimeout> | null = null;\n\n readonly shouldShowFallback = computed(() => {\n const status = this.#status();\n if (status === 'loaded') return false;\n if (status === 'error') return true;\n // idle | loading: an immediate (delay <= 0) gate shows the fallback right\n // away; a deferred gate waits for the timer armed in the effect below.\n if (this.fallbackDelayMs() <= 0) return true;\n return this.#timerElapsed();\n });\n\n /** @internal */\n reportStatus(status: ForAvatarStatus): void {\n this.#status.set(status);\n }\n\n constructor() {\n // Imperative timer integration: the effect's only job is to (re)arm a\n // setTimeout for the deferred-fallback case (idle | loading with a positive\n // delay). The synchronous branches (loaded / error / delay <= 0) are pure\n // derivations and live in `shouldShowFallback`. The signal write happens\n // inside the timer callback, which runs outside the effect's reactive\n // scope, so this does NOT create a self-cycle in the reactive graph.\n effect(() => {\n const status = this.#status();\n const delay = this.fallbackDelayMs();\n this.#cancelTimer();\n if ((status === 'idle' || status === 'loading') && delay > 0) {\n this.#timer = setTimeout(() => {\n this.#timer = null;\n this.#timerElapsed.set(true);\n }, delay);\n }\n });\n\n inject(DestroyRef).onDestroy(() => this.#cancelTimer());\n }\n\n #cancelTimer(): void {\n if (this.#timer !== null) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n afterNextRender,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n output,\n PLATFORM_ID,\n} from '@angular/core';\n\nimport { FOR_AVATAR_CONTEXT, type ForAvatarStatus } from './avatar-context';\n\n/**\n * Wraps an `<img>` and reports its load lifecycle to the surrounding\n * `[forAvatar]`. The native `src` / `alt` bindings are owned by the\n * consumer — this directive only observes.\n *\n * Reflects `data-status` on the image element so the consumer can hide it\n * via CSS while loading or after an error (e.g. `img[data-status=\"error\"]\n * { display: none }`).\n */\n@Directive({\n selector: 'img[forAvatarImage]',\n exportAs: 'forAvatarImage',\n host: {\n '[attr.data-status]': 'status()',\n '(load)': 'onLoad()',\n '(error)': 'onError()',\n },\n})\nexport class ForAvatarImage {\n readonly #host = inject<ElementRef<HTMLImageElement>>(ElementRef).nativeElement;\n readonly #parent = inject(FOR_AVATAR_CONTEXT, { optional: true });\n\n /**\n * Emits whenever the image lifecycle transitions to a new state. Useful\n * if the consumer wants to log analytics, swap to a different src on\n * error, etc.\n */\n readonly loadStatusChanged = output<ForAvatarStatus>();\n\n constructor() {\n if (!this.#parent) {\n throw new Error(\n '[forty-cdk/avatar] ForAvatarImage must be used inside a [forAvatar] element.',\n );\n }\n const parent = this.#parent;\n const host = this.#host;\n\n afterNextRender(() => {\n this.#syncFromAttr();\n });\n\n if (isPlatformBrowser(inject(PLATFORM_ID)) && typeof MutationObserver !== 'undefined') {\n const observer = new MutationObserver(() => {\n this.#syncFromAttr();\n });\n observer.observe(host, { attributes: true, attributeFilter: ['src'] });\n inject(DestroyRef).onDestroy(() => observer.disconnect());\n }\n\n // Re-emit upstream whenever the parent's status changes due to our writes.\n // De-dupe on the (request, status) pair rather than status alone: a new\n // `src` opens a fresh request token, so an identical status (e.g. a second\n // image that also `loaded`) still re-reports for the new request, while a\n // repeated status within the same request is suppressed.\n let last: ForAvatarStatus | null = null;\n let lastReportedToken = -1;\n const emit = (status: ForAvatarStatus): void => {\n if (last === status && lastReportedToken === this.#requestToken) return;\n last = status;\n lastReportedToken = this.#requestToken;\n parent.reportStatus(status);\n this.loadStatusChanged.emit(status);\n };\n this.#emit = emit;\n }\n\n protected status(): ForAvatarStatus {\n return this.#parent!.status();\n }\n\n protected onLoad(): void {\n // Ignore a `load` that fires for a request the host has already moved past\n // (the native event can arrive after `src` was reassigned).\n if (!this.#isCurrentRequest()) return;\n this.#emit('loaded');\n }\n\n protected onError(): void {\n if (!this.#isCurrentRequest()) return;\n this.#emit('error');\n }\n\n /**\n * True when the `src` the host currently carries is the one the latest\n * `#syncFromAttr` observed, so a native load/error event belongs to the\n * in-flight request rather than a superseded one.\n */\n #isCurrentRequest(): boolean {\n return this.#host.getAttribute('src') === this.#requestSrc;\n }\n\n #syncFromAttr(): void {\n const src = this.#host.getAttribute('src');\n this.#requestToken++;\n this.#requestSrc = src;\n if (!src) {\n this.#emit('idle');\n return;\n }\n if (this.#host.complete) {\n // Cached image: load/error events may not fire — derive from naturalWidth.\n if (this.#host.naturalWidth > 0) {\n this.#emit('loaded');\n return;\n }\n // A complete image with zero intrinsic width is ambiguous: it may be a\n // broken image OR a valid SVG with no intrinsic dimensions. Don't\n // pessimistically flag `error` and hide a valid image — verify with\n // `decode()`, which resolves for a decodable (even zero-size) image and\n // rejects for a broken one. Stay `loading` until it settles.\n this.#emit('loading');\n this.#verifyCachedZeroSize(src);\n return;\n }\n this.#emit('loading');\n }\n\n #verifyCachedZeroSize(src: string): void {\n const decode = this.#host.decode?.bind(this.#host);\n if (!decode) {\n // No `decode()` (older engines / jsdom): keep the legacy heuristic.\n this.#emit('error');\n return;\n }\n decode().then(\n () => {\n if (this.#host.getAttribute('src') === src) {\n this.#emit('loaded');\n }\n },\n () => {\n if (this.#host.getAttribute('src') === src) {\n this.#emit('error');\n }\n },\n );\n }\n\n // Initialized in constructor.\n #emit!: (status: ForAvatarStatus) => void;\n\n /** Monotonic id bumped on every `src` change so stale events are ignored. */\n #requestToken = 0;\n /** The `src` the latest `#syncFromAttr` observed, used to match native events. */\n #requestSrc: string | null = null;\n}\n","import { Directive } from '@angular/core';\n\nimport { injectAvatarContext } from './avatar-context';\n\n/**\n * Marker for the avatar's fallback content (initials, generic icon, …).\n * Reflects `data-status` from the parent `[forAvatar]` so the consumer can\n * style for the `error` state separately from `idle` / `loading` if needed.\n *\n * The decision of *whether* to render the fallback lives on the root —\n * drive `@if` with `forAvatar.shouldShowFallback()`.\n */\n@Directive({\n selector: '[forAvatarFallback]',\n exportAs: 'forAvatarFallback',\n host: {\n '[attr.data-status]': 'parent.status()',\n },\n})\nexport class ForAvatarFallback {\n protected readonly parent = injectAvatarContext('ForAvatarFallback');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;MA2Ba,kBAAkB,GAAG,IAAI,cAAc,CAAmB,oBAAoB;AAE3F;;;;;AAKG;AACG,SAAU,mBAAmB,CAAC,KAAa,EAAA;AAC/C,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,GAAG,EAAE;AACR,QAAA,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,CAAA,2CAAA,CAA6C,CAAC;IAC3F;AACA,IAAA,OAAO,GAAG;AACZ;;ACrBA;;;;AAIG;AACI,MAAM,4BAA4B,GAAsB;AAC7D,IAAA,eAAe,EAAE,CAAC;CACnB;AAED,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,cAAc,CAC/C,qBAAqB,EACrB,4BAA4B,CAC7B;AAED;AACO,MAAM,mBAAmB,GAAG;AAEnC;;;;AAIG;AACG,SAAU,wBAAwB,CAAC,QAAA,GAAuC,EAAE,EAAA;AAChF,IAAA,OAAO,eAAe,CAAC,QAAQ,CAAC;AAClC;;AC7BA;;;;;;;;;;;;;;;;;;;;AAoBG;MASU,SAAS,CAAA;AACX,IAAA,SAAS,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAEhD;;;;;;;AAOG;AACM,IAAA,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,iBAAA,EAAA,8BAAA,EAAA,CAAA,EAC7D,SAAS,EAAE,eAAe,GAC1B;IAEO,OAAO,GAAG,MAAM,CAAkB,MAAM;gFAAC;AACzC,IAAA,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;;;;;IAMlC,aAAa,GAAG,YAAY,CAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,eAAA,EAAA,8BAAA,EAAA,CAAA,EACnC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;AACzE,QAAA,WAAW,EAAE,MAAM,KAAK,GACxB;IACF,MAAM,GAAyC,IAAI;AAE1C,IAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAK;AAC1C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;QAC7B,IAAI,MAAM,KAAK,QAAQ;AAAE,YAAA,OAAO,KAAK;QACrC,IAAI,MAAM,KAAK,OAAO;AAAE,YAAA,OAAO,IAAI;;;AAGnC,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC;AAAE,YAAA,OAAO,IAAI;AAC5C,QAAA,OAAO,IAAI,CAAC,aAAa,EAAE;IAC7B,CAAC;2FAAC;;AAGF,IAAA,YAAY,CAAC,MAAuB,EAAA;AAClC,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;IAC1B;AAEA,IAAA,WAAA,GAAA;;;;;;;QAOE,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;AAC7B,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE;YACpC,IAAI,CAAC,YAAY,EAAE;AACnB,YAAA,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,SAAS,KAAK,KAAK,GAAG,CAAC,EAAE;AAC5D,gBAAA,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAK;AAC5B,oBAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,oBAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;gBAC9B,CAAC,EAAE,KAAK,CAAC;YACX;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IACzD;IAEA,YAAY,GAAA;AACV,QAAA,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE;AACxB,YAAA,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;AACzB,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;QACpB;IACF;uGAtEW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAT,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,EAAA,EAAA,SAAA,EAFT,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAEzD,SAAS,EAAA,UAAA,EAAA,CAAA;kBARrB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,aAAa;AACvB,oBAAA,QAAQ,EAAE,WAAW;AACrB,oBAAA,IAAI,EAAE;AACJ,wBAAA,oBAAoB,EAAE,UAAU;AACjC,qBAAA;oBACD,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAA,SAAW,EAAE,CAAC;AACrE,iBAAA;;;AC9BD;;;;;;;;AAQG;MAUU,cAAc,CAAA;AAChB,IAAA,KAAK,GAAG,MAAM,CAA+B,UAAU,CAAC,CAAC,aAAa;IACtE,OAAO,GAAG,MAAM,CAAC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAEjE;;;;AAIG;IACM,iBAAiB,GAAG,MAAM,EAAmB;AAEtD,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,YAAA,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E;QACH;AACA,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO;AAC3B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK;QAEvB,eAAe,CAAC,MAAK;YACnB,IAAI,CAAC,aAAa,EAAE;AACtB,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,OAAO,gBAAgB,KAAK,WAAW,EAAE;AACrF,YAAA,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,MAAK;gBACzC,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,CAAC,CAAC;AACF,YAAA,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;AACtE,YAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC3D;;;;;;QAOA,IAAI,IAAI,GAA2B,IAAI;AACvC,QAAA,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAC1B,QAAA,MAAM,IAAI,GAAG,CAAC,MAAuB,KAAU;YAC7C,IAAI,IAAI,KAAK,MAAM,IAAI,iBAAiB,KAAK,IAAI,CAAC,aAAa;gBAAE;YACjE,IAAI,GAAG,MAAM;AACb,YAAA,iBAAiB,GAAG,IAAI,CAAC,aAAa;AACtC,YAAA,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;AAC3B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;AACrC,QAAA,CAAC;AACD,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI;IACnB;IAEU,MAAM,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,OAAQ,CAAC,MAAM,EAAE;IAC/B;IAEU,MAAM,GAAA;;;AAGd,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAAE;AAC/B,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IACtB;IAEU,OAAO,GAAA;AACf,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAAE;AAC/B,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;IACrB;AAEA;;;;AAIG;IACH,iBAAiB,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,WAAW;IAC5D;IAEA,aAAa,GAAA;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC;QAC1C,IAAI,CAAC,aAAa,EAAE;AACpB,QAAA,IAAI,CAAC,WAAW,GAAG,GAAG;QACtB,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;YAClB;QACF;AACA,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;;YAEvB,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,EAAE;AAC/B,gBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;gBACpB;YACF;;;;;;AAMA,YAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;AACrB,YAAA,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC;YAC/B;QACF;AACA,QAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;IACvB;AAEA,IAAA,qBAAqB,CAAC,GAAW,EAAA;AAC/B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAClD,IAAI,CAAC,MAAM,EAAE;;AAEX,YAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YACnB;QACF;AACA,QAAA,MAAM,EAAE,CAAC,IAAI,CACX,MAAK;YACH,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE;AAC1C,gBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YACtB;QACF,CAAC,EACD,MAAK;YACH,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE;AAC1C,gBAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YACrB;AACF,QAAA,CAAC,CACF;IACH;;AAGA,IAAA,KAAK;;IAGL,aAAa,GAAG,CAAC;;IAEjB,WAAW,GAAkB,IAAI;uGA/HtB,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,MAAA,EAAA,UAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,UAAA,EAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,EAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBAT1B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;AAC/B,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,IAAI,EAAE;AACJ,wBAAA,oBAAoB,EAAE,UAAU;AAChC,wBAAA,QAAQ,EAAE,UAAU;AACpB,wBAAA,SAAS,EAAE,WAAW;AACvB,qBAAA;AACF,iBAAA;;;AC1BD;;;;;;;AAOG;MAQU,iBAAiB,CAAA;AACT,IAAA,MAAM,GAAG,mBAAmB,CAAC,mBAAmB,CAAC;uGADzD,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,kBAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAP7B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;AAC/B,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,IAAI,EAAE;AACJ,wBAAA,oBAAoB,EAAE,iBAAiB;AACxC,qBAAA;AACF,iBAAA;;;AClBD;;AAEG;;;;"}
1
+ {"version":3,"file":"forty-cdk-avatar.mjs","sources":["../../../projects/forty-cdk/avatar/src/avatar-context.ts","../../../projects/forty-cdk/avatar/src/avatar-defaults.ts","../../../projects/forty-cdk/avatar/src/avatar.ts","../../../projects/forty-cdk/avatar/src/avatar-image.ts","../../../projects/forty-cdk/avatar/src/avatar-fallback.ts","../../../projects/forty-cdk/avatar/src/forty-cdk-avatar.ts"],"sourcesContent":["import { inject, InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Lifecycle stages of the avatar's image:\n * - `idle`: no `src` set yet.\n * - `loading`: `src` set, waiting for the network.\n * - `loaded`: image rendered successfully.\n * - `error`: image failed to load.\n */\nexport type ForAvatarStatus = 'idle' | 'loading' | 'loaded' | 'error';\n\nexport interface ForAvatarContext {\n /** Current status of the avatar's image. */\n readonly status: Signal<ForAvatarStatus>;\n /**\n * `true` when the consumer should render the fallback. Drives `@if` in\n * the consumer's template. Honors `fallbackDelayMs` for `idle` / `loading`\n * states; `error` flips it to `true` immediately.\n */\n readonly shouldShowFallback: Signal<boolean>;\n /**\n * Internal — reported by `[forAvatarImage]` so the root can transition\n * its state machine. Consumers should not call this.\n */\n reportStatus(status: ForAvatarStatus): void;\n}\n\nexport const FOR_AVATAR_CONTEXT = new InjectionToken<ForAvatarContext>('FOR_AVATAR_CONTEXT');\n\n/**\n * Injects the nearest {@link ForAvatarContext}, throwing a descriptive error\n * when used outside a `[forAvatar]` element.\n *\n * @param piece Name of the calling directive, used in the error message.\n */\nexport function injectAvatarContext(piece: string): ForAvatarContext {\n const ctx = inject(FOR_AVATAR_CONTEXT, { optional: true });\n if (!ctx) {\n throw new Error(`[forty-cdk/avatar] ${piece} must be used inside a [forAvatar] element.`);\n }\n return ctx;\n}\n","import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * Defaults inherited by descendant avatars in the surrounding injector\n * scope. Configure with `provideForAvatarDefaults` either at the\n * application root or in any component's `providers` array; partial\n * overrides merge with the parent scope.\n */\nexport interface ForAvatarDefaults {\n /**\n * Milliseconds to defer the fallback for fast loads, avoiding a brief\n * \"initials → image\" flicker. Set to `0` to show immediately during\n * `idle` / `loading`, or to e.g. `500` to skip rendering during quick\n * cached loads. `error` always shows the fallback immediately.\n */\n fallbackDelayMs: number;\n}\n\n/**\n * Library fallback for avatar defaults, read at the root injector when no\n * consumer has called `provideForAvatarDefaults`. Exported for the shared defaults\n * contract spec; not re-exported from the primitive's public entry.\n */\nexport const FOR_AVATAR_FALLBACK_DEFAULTS: ForAvatarDefaults = {\n fallbackDelayMs: 0,\n};\n\nconst { token, provideDefaults } = createDefaults<ForAvatarDefaults>(\n 'FOR_AVATAR_DEFAULTS',\n FOR_AVATAR_FALLBACK_DEFAULTS,\n);\n\n/** Token holding the resolved avatar defaults for the current scope. */\nexport const FOR_AVATAR_DEFAULTS = token;\n\n/**\n * Configures forty-cdk avatar defaults for this injector scope. Partial\n * overrides inherit unspecified keys from the parent scope (or library\n * defaults at the root).\n */\nexport function provideForAvatarDefaults(defaults: Partial<ForAvatarDefaults> = {}): Provider[] {\n return provideDefaults(defaults);\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n computed,\n DestroyRef,\n Directive,\n effect,\n inject,\n input,\n linkedSignal,\n numberAttribute,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\n\nimport { FOR_AVATAR_CONTEXT, type ForAvatarContext, type ForAvatarStatus } from './avatar-context';\nimport { FOR_AVATAR_DEFAULTS } from './avatar-defaults';\n\n/**\n * Headless avatar root. Tracks the load lifecycle of an inner\n * `[forAvatarImage]` and exposes `status` + `shouldShowFallback` so the\n * consumer can swap the image for fallback content (initials, generic icon)\n * via `@if`.\n *\n * No ARIA role is imposed — avatars are typically presentational. If the\n * surrounding component conveys identity (a person's name in the header,\n * a chat bubble), the consumer should provide an `aria-label` on the\n * relevant ancestor or pair the avatar with visible text.\n *\n * @example\n * ```html\n * <span forAvatar #a=\"forAvatar\" fallbackDelayMs=\"500\">\n * <img forAvatarImage [src]=\"user.avatarUrl\" [alt]=\"user.name\" />\n * @if (a.shouldShowFallback()) {\n * <span forAvatarFallback>{{ user.initials }}</span>\n * }\n * </span>\n * ```\n */\n@Directive({\n selector: '[forAvatar]',\n exportAs: 'forAvatar',\n host: {\n '[attr.data-status]': 'status()',\n },\n providers: [{ provide: FOR_AVATAR_CONTEXT, useExisting: ForAvatar }],\n})\nexport class ForAvatar implements ForAvatarContext {\n readonly #defaults = inject(FOR_AVATAR_DEFAULTS);\n\n /**\n * Milliseconds to defer the fallback for fast loads, avoiding a brief\n * \"initials → image\" flicker. Set to `0` (default) to show immediately\n * during `idle` / `loading`, or to e.g. `500` to skip rendering during\n * quick cached loads. `error` always shows the fallback immediately.\n * The default is read from `provideForAvatarDefaults` for the\n * surrounding scope.\n */\n readonly fallbackDelayMs = input(this.#defaults.fallbackDelayMs, {\n transform: numberAttribute,\n });\n\n readonly #status = signal<ForAvatarStatus>('idle');\n readonly status = this.#status.asReadonly();\n\n // Whether the deferred-fallback timer has fired for the current status/delay.\n // `linkedSignal` resets it to `false` whenever the source changes (the\n // canonical replacement for resetting state inside an effect); the timer\n // callback in the constructor flips it to `true`.\n readonly #timerElapsed = linkedSignal<{ status: ForAvatarStatus; delay: number }, boolean>({\n source: () => ({ status: this.#status(), delay: this.fallbackDelayMs() }),\n computation: () => false,\n });\n #timer: ReturnType<typeof setTimeout> | null = null;\n readonly #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n readonly shouldShowFallback = computed(() => {\n const status = this.#status();\n if (status === 'loaded') return false;\n if (status === 'error') return true;\n // idle | loading: an immediate (delay <= 0) gate shows the fallback right\n // away; a deferred gate waits for the timer armed in the effect below.\n if (this.fallbackDelayMs() <= 0) return true;\n return this.#timerElapsed();\n });\n\n /** @internal */\n reportStatus(status: ForAvatarStatus): void {\n this.#status.set(status);\n }\n\n constructor() {\n // Imperative timer integration: the effect's only job is to (re)arm a\n // setTimeout for the deferred-fallback case (idle | loading with a positive\n // delay). The synchronous branches (loaded / error / delay <= 0) are pure\n // derivations and live in `shouldShowFallback`. The signal write happens\n // inside the timer callback, which runs outside the effect's reactive\n // scope, so this does NOT create a self-cycle in the reactive graph.\n effect(() => {\n const status = this.#status();\n const delay = this.fallbackDelayMs();\n this.#cancelTimer();\n if (this.#isBrowser && (status === 'idle' || status === 'loading') && delay > 0) {\n this.#timer = setTimeout(() => {\n this.#timer = null;\n this.#timerElapsed.set(true);\n }, delay);\n }\n });\n\n inject(DestroyRef).onDestroy(() => this.#cancelTimer());\n }\n\n #cancelTimer(): void {\n if (this.#timer !== null) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n afterNextRender,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n output,\n PLATFORM_ID,\n} from '@angular/core';\n\nimport { FOR_AVATAR_CONTEXT, type ForAvatarStatus } from './avatar-context';\n\n/**\n * Wraps an `<img>` and reports its load lifecycle to the surrounding\n * `[forAvatar]`. The native `src` / `alt` bindings are owned by the\n * consumer — this directive only observes.\n *\n * Reflects `data-status` on the image element so the consumer can hide it\n * via CSS while loading or after an error (e.g. `img[data-status=\"error\"]\n * { display: none }`).\n */\n@Directive({\n selector: 'img[forAvatarImage]',\n exportAs: 'forAvatarImage',\n host: {\n '[attr.data-status]': 'status()',\n '(load)': 'onLoad()',\n '(error)': 'onError()',\n },\n})\nexport class ForAvatarImage {\n readonly #host = inject<ElementRef<HTMLImageElement>>(ElementRef).nativeElement;\n readonly #parent = inject(FOR_AVATAR_CONTEXT, { optional: true });\n\n /**\n * Emits whenever the image lifecycle transitions to a new state. Useful\n * if the consumer wants to log analytics, swap to a different src on\n * error, etc.\n */\n readonly loadStatusChanged = output<ForAvatarStatus>();\n\n constructor() {\n if (!this.#parent) {\n throw new Error(\n '[forty-cdk/avatar] ForAvatarImage must be used inside a [forAvatar] element.',\n );\n }\n const parent = this.#parent;\n const host = this.#host;\n\n afterNextRender(() => {\n this.#syncFromAttr();\n });\n\n if (isPlatformBrowser(inject(PLATFORM_ID)) && typeof MutationObserver !== 'undefined') {\n const observer = new MutationObserver(() => {\n this.#syncFromAttr();\n });\n observer.observe(host, { attributes: true, attributeFilter: ['src'] });\n inject(DestroyRef).onDestroy(() => observer.disconnect());\n }\n\n // Re-emit upstream whenever the parent's status changes due to our writes.\n // De-dupe on the (request, status) pair rather than status alone: a new\n // `src` opens a fresh request token, so an identical status (e.g. a second\n // image that also `loaded`) still re-reports for the new request, while a\n // repeated status within the same request is suppressed.\n let last: ForAvatarStatus | null = null;\n let lastReportedToken = -1;\n const emit = (status: ForAvatarStatus): void => {\n if (last === status && lastReportedToken === this.#requestToken) return;\n last = status;\n lastReportedToken = this.#requestToken;\n parent.reportStatus(status);\n this.loadStatusChanged.emit(status);\n };\n this.#emit = emit;\n }\n\n protected status(): ForAvatarStatus {\n return this.#parent!.status();\n }\n\n protected onLoad(): void {\n // Ignore a `load` that fires for a request the host has already moved past\n // (the native event can arrive after `src` was reassigned).\n if (!this.#isCurrentRequest()) return;\n this.#emit('loaded');\n }\n\n protected onError(): void {\n if (!this.#isCurrentRequest()) return;\n this.#emit('error');\n }\n\n /**\n * True when the `src` the host currently carries is the one the latest\n * `#syncFromAttr` observed, so a native load/error event belongs to the\n * in-flight request rather than a superseded one.\n */\n #isCurrentRequest(): boolean {\n return this.#host.getAttribute('src') === this.#requestSrc;\n }\n\n #syncFromAttr(): void {\n const src = this.#host.getAttribute('src');\n this.#requestToken++;\n this.#requestSrc = src;\n if (!src) {\n this.#emit('idle');\n return;\n }\n if (this.#host.complete) {\n // Cached image: load/error events may not fire — derive from naturalWidth.\n if (this.#host.naturalWidth > 0) {\n this.#emit('loaded');\n return;\n }\n // A complete image with zero intrinsic width is ambiguous: it may be a\n // broken image OR a valid SVG with no intrinsic dimensions. Don't\n // pessimistically flag `error` and hide a valid image — verify with\n // `decode()`, which resolves for a decodable (even zero-size) image and\n // rejects for a broken one. Stay `loading` until it settles.\n this.#emit('loading');\n this.#verifyCachedZeroSize(src);\n return;\n }\n this.#emit('loading');\n }\n\n #verifyCachedZeroSize(src: string): void {\n const decode = this.#host.decode?.bind(this.#host);\n if (!decode) {\n // No `decode()` (older engines / jsdom): keep the legacy heuristic.\n this.#emit('error');\n return;\n }\n decode().then(\n () => {\n if (this.#host.getAttribute('src') === src) {\n this.#emit('loaded');\n }\n },\n () => {\n if (this.#host.getAttribute('src') === src) {\n this.#emit('error');\n }\n },\n );\n }\n\n // Initialized in constructor.\n #emit!: (status: ForAvatarStatus) => void;\n\n /** Monotonic id bumped on every `src` change so stale events are ignored. */\n #requestToken = 0;\n /** The `src` the latest `#syncFromAttr` observed, used to match native events. */\n #requestSrc: string | null = null;\n}\n","import { Directive } from '@angular/core';\n\nimport { injectAvatarContext } from './avatar-context';\n\n/**\n * Marker for the avatar's fallback content (initials, generic icon, …).\n * Reflects `data-status` from the parent `[forAvatar]` so the consumer can\n * style for the `error` state separately from `idle` / `loading` if needed.\n *\n * The decision of *whether* to render the fallback lives on the root —\n * drive `@if` with `forAvatar.shouldShowFallback()`.\n */\n@Directive({\n selector: '[forAvatarFallback]',\n exportAs: 'forAvatarFallback',\n host: {\n '[attr.data-status]': 'parent.status()',\n },\n})\nexport class ForAvatarFallback {\n protected readonly parent = injectAvatarContext('ForAvatarFallback');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"forty-cdk-breakpoints.mjs","sources":["../../../projects/forty-cdk/breakpoints/src/breakpoints-defaults.ts","../../../projects/forty-cdk/breakpoints/src/breakpoints.ts","../../../projects/forty-cdk/breakpoints/src/forty-cdk-breakpoints.ts"],"sourcesContent":["import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * A breakpoint map: each named breakpoint paired with its `min-width`\n * threshold in CSS pixels. Names are arbitrary — `injectBreakpoints` derives\n * its query methods (`up`, `down`, `between`, `only`) from whatever keys this\n * map declares, sorted ascending by threshold.\n */\nexport type BreakpointMap = Record<string, number>;\n\n/**\n * The default breakpoint map, mirroring Tailwind CSS's `sm`–`2xl` scale. Used\n * as the library fallback when no `provideForBreakpoints` is in scope, and the\n * source of the typed breakpoint names when the consumer has not augmented\n * {@link BreakpointRegistry}.\n */\nexport const breakpointsTailwind = {\n sm: 640,\n md: 768,\n lg: 1024,\n xl: 1280,\n '2xl': 1536,\n} as const satisfies BreakpointMap;\n\n/** The breakpoint names from the default Tailwind scale. */\nexport type TailwindBreakpointName = keyof typeof breakpointsTailwind;\n\n/** Resolved shape stored against {@link FOR_BREAKPOINTS}. */\nexport interface ForBreakpointsDefaults {\n /** The active breakpoint map for the current injector scope. */\n breakpoints: BreakpointMap;\n}\n\nconst FALLBACK: ForBreakpointsDefaults = {\n breakpoints: breakpointsTailwind,\n};\n\nconst { token, provideDefaults } = createDefaults<ForBreakpointsDefaults>(\n 'FOR_BREAKPOINTS',\n FALLBACK,\n);\n\n/**\n * Token holding the resolved breakpoint map for the current injector scope.\n * The library always provides a fully-populated value (the Tailwind fallback\n * at the root, or the map from the nearest `provideForBreakpoints`).\n */\nexport const FOR_BREAKPOINTS = token;\n\n/**\n * Configures the breakpoint map for this injector scope so `injectBreakpoints`\n * can be called with no arguments. Provide it once in your application config:\n *\n * ```ts\n * providers: [\n * provideForBreakpoints({ mobile: 0, tablet: 640, laptop: 1024, desktop: 1280 }),\n * ]\n * ```\n *\n * Providing it again on a component injector replaces the map for that subtree\n * only (the nearest scope wins; the map is replaced wholesale, never merged\n * key-by-key). Omit it entirely to use {@link breakpointsTailwind}.\n */\nexport function provideForBreakpoints(breakpoints: BreakpointMap): Provider[] {\n return provideDefaults({ breakpoints });\n}\n","import { Injector, computed, inject, runInInjectionContext, type Signal } from '@angular/core';\n\nimport { injectMediaQuery } from 'forty-cdk/core';\nimport { FOR_BREAKPOINTS, type TailwindBreakpointName } from './breakpoints-defaults';\n\n/**\n * Extension point for typing custom breakpoint names. Augment it via module\n * declaration merging so `injectBreakpoints` autocompletes your own names\n * instead of the default Tailwind scale:\n *\n * ```ts\n * import type { appBreakpoints } from './breakpoints';\n *\n * declare module 'forty-cdk' {\n * interface BreakpointRegistry extends Record<keyof typeof appBreakpoints, true> {}\n * }\n * ```\n *\n * When left empty (no augmentation), {@link BreakpointName} falls back to the\n * keys of {@link breakpointsTailwind}.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface BreakpointRegistry {}\n\n/**\n * The set of valid breakpoint names. Resolves to the augmented\n * {@link BreakpointRegistry} keys when present, otherwise the Tailwind scale\n * (`'sm' | 'md' | 'lg' | 'xl' | '2xl'`).\n */\nexport type BreakpointName = [keyof BreakpointRegistry] extends [never]\n ? TailwindBreakpointName\n : keyof BreakpointRegistry & string;\n\n/** Reactive handle returned by {@link injectBreakpoints}. */\nexport interface ForBreakpoints<K extends string = BreakpointName> {\n /**\n * Matches the named breakpoint and wider — `(min-width: <threshold>px)`.\n * @param name A breakpoint declared in the active map.\n */\n up(name: K): Signal<boolean>;\n /**\n * Matches narrower than the named breakpoint —\n * `(max-width: <threshold - 0.02>px)`. The 0.02px back-off keeps `up(name)`\n * and `down(name)` from both matching at the exact threshold.\n * @param name A breakpoint declared in the active map.\n */\n down(name: K): Signal<boolean>;\n /**\n * Matches from `min` (inclusive) up to but not including `max`.\n * @param min Lower breakpoint, inclusive.\n * @param max Upper breakpoint, exclusive.\n */\n between(min: K, max: K): Signal<boolean>;\n /**\n * Matches only the named breakpoint's own band — from its threshold up to\n * but not including the next-larger breakpoint (open-ended for the largest).\n * @param name A breakpoint declared in the active map.\n */\n only(name: K): Signal<boolean>;\n /**\n * The largest breakpoint whose `min-width` currently matches, or `null` when\n * the viewport is narrower than the smallest breakpoint (and on the server).\n */\n readonly active: Signal<K | null>;\n /**\n * Escape hatch for an arbitrary media query string (orientation, pointer,\n * `prefers-color-scheme`, …) that the named helpers don't cover.\n * @param query Any valid media query.\n */\n matches(query: string): Signal<boolean>;\n}\n\n/**\n * A signal-first, zoneless, SSR-safe viewport breakpoint observer. Reads the\n * breakpoint map from the ambient {@link FOR_BREAKPOINTS} token (configured\n * with `provideForBreakpoints`, or the Tailwind fallback), so call sites never\n * repeat the breakpoint set:\n *\n * ```ts\n * private bp = injectBreakpoints();\n * protected isDesktop = this.bp.up('desktop');\n * protected active = this.bp.active;\n * ```\n *\n * Each query method returns a `Signal<boolean>` backed by a cached\n * `MediaQueryList`. The returned handle captures the calling injection\n * context, so its methods can be invoked lazily from `computed()` or a\n * template — not only during construction. Listeners are torn down with the\n * injector. On the server (or where `matchMedia` is unavailable) every signal\n * reads `false` and `active` reads `null`.\n *\n * Must be called from an injection context.\n *\n * @returns A {@link ForBreakpoints} handle of reactive query methods.\n */\nexport function injectBreakpoints(): ForBreakpoints {\n const injector = inject(Injector);\n const map = inject(FOR_BREAKPOINTS).breakpoints;\n const names = Object.keys(map).sort((a, b) => map[a] - map[b]);\n const cache = new Map<string, Signal<boolean>>();\n\n const observe = (query: string): Signal<boolean> => {\n let result = cache.get(query);\n if (result === undefined) {\n result = runInInjectionContext(injector, () => injectMediaQuery(query));\n cache.set(query, result);\n }\n return result;\n };\n\n const thresholdOf = (name: string): number => {\n const value = map[name];\n if (value === undefined) {\n throw new Error(\n `[forty-cdk/breakpoints] Unknown breakpoint \"${name}\". Defined breakpoints: ${\n names.join(', ') || '(none)'\n }.`,\n );\n }\n return value;\n };\n\n const up = (name: string): Signal<boolean> => observe(`(min-width: ${thresholdOf(name)}px)`);\n\n const down = (name: string): Signal<boolean> =>\n observe(`(max-width: ${thresholdOf(name) - 0.02}px)`);\n\n const between = (min: string, max: string): Signal<boolean> =>\n observe(`(min-width: ${thresholdOf(min)}px) and (max-width: ${thresholdOf(max) - 0.02}px)`);\n\n const only = (name: string): Signal<boolean> => {\n const lower = thresholdOf(name);\n const index = names.indexOf(name);\n const next = index < names.length - 1 ? thresholdOf(names[index + 1]) : null;\n return next === null\n ? observe(`(min-width: ${lower}px)`)\n : observe(`(min-width: ${lower}px) and (max-width: ${next - 0.02}px)`);\n };\n\n const active = computed<BreakpointName | null>(() => {\n let current: string | null = null;\n for (const name of names) {\n if (observe(`(min-width: ${map[name]}px)`)()) {\n current = name;\n }\n }\n return current as BreakpointName | null;\n });\n\n return { up, down, between, only, active, matches: (query) => observe(query) };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"forty-cdk-breakpoints.mjs","sources":["../../../projects/forty-cdk/breakpoints/src/breakpoints-defaults.ts","../../../projects/forty-cdk/breakpoints/src/breakpoints.ts","../../../projects/forty-cdk/breakpoints/src/forty-cdk-breakpoints.ts"],"sourcesContent":["import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * A breakpoint map: each named breakpoint paired with its `min-width`\n * threshold in CSS pixels. Names are arbitrary — `injectBreakpoints` derives\n * its query methods (`up`, `down`, `between`, `only`) from whatever keys this\n * map declares, sorted ascending by threshold.\n */\nexport type BreakpointMap = Record<string, number>;\n\n/**\n * The default breakpoint map, mirroring Tailwind CSS's `sm`–`2xl` scale. Used\n * as the library fallback when no `provideForBreakpoints` is in scope, and the\n * source of the typed breakpoint names when the consumer has not augmented\n * {@link BreakpointRegistry}.\n */\nexport const breakpointsTailwind = {\n sm: 640,\n md: 768,\n lg: 1024,\n xl: 1280,\n '2xl': 1536,\n} as const satisfies BreakpointMap;\n\n/** The breakpoint names from the default Tailwind scale. */\nexport type TailwindBreakpointName = keyof typeof breakpointsTailwind;\n\n/** Resolved shape stored against {@link FOR_BREAKPOINTS}. */\nexport interface ForBreakpointsDefaults {\n /** The active breakpoint map for the current injector scope. */\n breakpoints: BreakpointMap;\n}\n\nconst FALLBACK: ForBreakpointsDefaults = {\n breakpoints: breakpointsTailwind,\n};\n\nconst { token, provideDefaults } = createDefaults<ForBreakpointsDefaults>(\n 'FOR_BREAKPOINTS',\n FALLBACK,\n);\n\n/**\n * Token holding the resolved breakpoint map for the current injector scope.\n * The library always provides a fully-populated value (the Tailwind fallback\n * at the root, or the map from the nearest `provideForBreakpoints`).\n */\nexport const FOR_BREAKPOINTS = token;\n\n/**\n * Configures the breakpoint map for this injector scope so `injectBreakpoints`\n * can be called with no arguments. Provide it once in your application config:\n *\n * ```ts\n * providers: [\n * provideForBreakpoints({ mobile: 0, tablet: 640, laptop: 1024, desktop: 1280 }),\n * ]\n * ```\n *\n * Providing it again on a component injector replaces the map for that subtree\n * only (the nearest scope wins; the map is replaced wholesale, never merged\n * key-by-key). Omit it entirely to use {@link breakpointsTailwind}.\n */\nexport function provideForBreakpoints(breakpoints: BreakpointMap): Provider[] {\n return provideDefaults({ breakpoints });\n}\n","import { Injector, computed, inject, runInInjectionContext, type Signal } from '@angular/core';\n\nimport { injectMediaQuery } from 'forty-cdk/core';\nimport { FOR_BREAKPOINTS, type TailwindBreakpointName } from './breakpoints-defaults';\n\n/**\n * Extension point for typing custom breakpoint names. Augment it via module\n * declaration merging so `injectBreakpoints` autocompletes your own names\n * instead of the default Tailwind scale:\n *\n * ```ts\n * import type { appBreakpoints } from './breakpoints';\n *\n * declare module 'forty-cdk' {\n * interface BreakpointRegistry extends Record<keyof typeof appBreakpoints, true> {}\n * }\n * ```\n *\n * When left empty (no augmentation), {@link BreakpointName} falls back to the\n * keys of {@link breakpointsTailwind}.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface BreakpointRegistry {}\n\n/**\n * The set of valid breakpoint names. Resolves to the augmented\n * {@link BreakpointRegistry} keys when present, otherwise the Tailwind scale\n * (`'sm' | 'md' | 'lg' | 'xl' | '2xl'`).\n */\nexport type BreakpointName = [keyof BreakpointRegistry] extends [never]\n ? TailwindBreakpointName\n : keyof BreakpointRegistry & string;\n\n/** Reactive handle returned by {@link injectBreakpoints}. */\nexport interface ForBreakpoints<K extends string = BreakpointName> {\n /**\n * Matches the named breakpoint and wider — `(min-width: <threshold>px)`.\n * @param name A breakpoint declared in the active map.\n */\n up(name: K): Signal<boolean>;\n /**\n * Matches narrower than the named breakpoint —\n * `(max-width: <threshold - 0.02>px)`. The 0.02px back-off keeps `up(name)`\n * and `down(name)` from both matching at the exact threshold.\n * @param name A breakpoint declared in the active map.\n */\n down(name: K): Signal<boolean>;\n /**\n * Matches from `min` (inclusive) up to but not including `max`.\n * @param min Lower breakpoint, inclusive.\n * @param max Upper breakpoint, exclusive.\n */\n between(min: K, max: K): Signal<boolean>;\n /**\n * Matches only the named breakpoint's own band — from its threshold up to\n * but not including the next-larger breakpoint (open-ended for the largest).\n * @param name A breakpoint declared in the active map.\n */\n only(name: K): Signal<boolean>;\n /**\n * The largest breakpoint whose `min-width` currently matches, or `null` when\n * the viewport is narrower than the smallest breakpoint (and on the server).\n */\n readonly active: Signal<K | null>;\n /**\n * Escape hatch for an arbitrary media query string (orientation, pointer,\n * `prefers-color-scheme`, …) that the named helpers don't cover.\n * @param query Any valid media query.\n */\n matches(query: string): Signal<boolean>;\n}\n\n/**\n * A signal-first, zoneless, SSR-safe viewport breakpoint observer. Reads the\n * breakpoint map from the ambient {@link FOR_BREAKPOINTS} token (configured\n * with `provideForBreakpoints`, or the Tailwind fallback), so call sites never\n * repeat the breakpoint set:\n *\n * ```ts\n * private bp = injectBreakpoints();\n * protected isDesktop = this.bp.up('desktop');\n * protected active = this.bp.active;\n * ```\n *\n * Each query method returns a `Signal<boolean>` backed by a cached\n * `MediaQueryList`. The returned handle captures the calling injection\n * context, so its methods can be invoked lazily from `computed()` or a\n * template — not only during construction. Listeners are torn down with the\n * injector. On the server (or where `matchMedia` is unavailable) every signal\n * reads `false` and `active` reads `null`.\n *\n * Must be called from an injection context.\n *\n * @returns A {@link ForBreakpoints} handle of reactive query methods.\n */\nexport function injectBreakpoints(): ForBreakpoints {\n const injector = inject(Injector);\n const map = inject(FOR_BREAKPOINTS).breakpoints;\n const names = Object.keys(map).sort((a, b) => map[a]! - map[b]!);\n const cache = new Map<string, Signal<boolean>>();\n\n const observe = (query: string): Signal<boolean> => {\n let result = cache.get(query);\n if (result === undefined) {\n result = runInInjectionContext(injector, () => injectMediaQuery(query));\n cache.set(query, result);\n }\n return result;\n };\n\n const thresholdOf = (name: string): number => {\n const value = map[name];\n if (value === undefined) {\n throw new Error(\n `[forty-cdk/breakpoints] Unknown breakpoint \"${name}\". Defined breakpoints: ${\n names.join(', ') || '(none)'\n }.`,\n );\n }\n return value;\n };\n\n const up = (name: string): Signal<boolean> => observe(`(min-width: ${thresholdOf(name)}px)`);\n\n const down = (name: string): Signal<boolean> =>\n observe(`(max-width: ${thresholdOf(name) - 0.02}px)`);\n\n const between = (min: string, max: string): Signal<boolean> =>\n observe(`(min-width: ${thresholdOf(min)}px) and (max-width: ${thresholdOf(max) - 0.02}px)`);\n\n const only = (name: string): Signal<boolean> => {\n const lower = thresholdOf(name);\n const index = names.indexOf(name);\n const next = index < names.length - 1 ? thresholdOf(names[index + 1]!) : null;\n return next === null\n ? observe(`(min-width: ${lower}px)`)\n : observe(`(min-width: ${lower}px) and (max-width: ${next - 0.02}px)`);\n };\n\n const active = computed<BreakpointName | null>(() => {\n let current: string | null = null;\n for (const name of names) {\n if (observe(`(min-width: ${map[name]}px)`)()) {\n current = name;\n }\n }\n return current as BreakpointName | null;\n });\n\n return { up, down, between, only, active, matches: (query) => observe(query) };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -846,7 +846,7 @@ class CalendarYearNavigator {
846
846
  *
847
847
  * `ForCalendar` is the grid widget, not a form value — it exposes `[(value)]`
848
848
  * as a `model<D | null>` in `selectionMode="single"` (default), and
849
- * `[(range)]` as a `model<CalendarDateRange<D> | null>` in
849
+ * `[(range)]` as a `model<DateRange<D> | null>` in
850
850
  * `selectionMode="range"`. The `FormValueControl<D>` contract arrives with the
851
851
  * follow-up `ForDatePicker` / `ForDateField`. See the primitive's README for a
852
852
  * complete styleless usage example.