@star-ng/ui 0.0.0-stage → 0.1.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 (217) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -2
  3. package/fesm2022/star-ng-ui-accordion.mjs +376 -0
  4. package/fesm2022/star-ng-ui-accordion.mjs.map +1 -0
  5. package/fesm2022/star-ng-ui-autocomplete.mjs +782 -0
  6. package/fesm2022/star-ng-ui-autocomplete.mjs.map +1 -0
  7. package/fesm2022/star-ng-ui-avatar.mjs +154 -0
  8. package/fesm2022/star-ng-ui-avatar.mjs.map +1 -0
  9. package/fesm2022/star-ng-ui-badge.mjs +153 -0
  10. package/fesm2022/star-ng-ui-badge.mjs.map +1 -0
  11. package/fesm2022/star-ng-ui-breadcrumb.mjs +199 -0
  12. package/fesm2022/star-ng-ui-breadcrumb.mjs.map +1 -0
  13. package/fesm2022/star-ng-ui-button.mjs +282 -0
  14. package/fesm2022/star-ng-ui-button.mjs.map +1 -0
  15. package/fesm2022/star-ng-ui-card.mjs +112 -0
  16. package/fesm2022/star-ng-ui-card.mjs.map +1 -0
  17. package/fesm2022/star-ng-ui-chart.mjs +1904 -0
  18. package/fesm2022/star-ng-ui-chart.mjs.map +1 -0
  19. package/fesm2022/star-ng-ui-checkbox.mjs +345 -0
  20. package/fesm2022/star-ng-ui-checkbox.mjs.map +1 -0
  21. package/fesm2022/star-ng-ui-core.mjs +392 -0
  22. package/fesm2022/star-ng-ui-core.mjs.map +1 -0
  23. package/fesm2022/star-ng-ui-data-display.mjs +1556 -0
  24. package/fesm2022/star-ng-ui-data-display.mjs.map +1 -0
  25. package/fesm2022/star-ng-ui-date-picker.mjs +2786 -0
  26. package/fesm2022/star-ng-ui-date-picker.mjs.map +1 -0
  27. package/fesm2022/star-ng-ui-dialog.mjs +948 -0
  28. package/fesm2022/star-ng-ui-dialog.mjs.map +1 -0
  29. package/fesm2022/star-ng-ui-drawer.mjs +158 -0
  30. package/fesm2022/star-ng-ui-drawer.mjs.map +1 -0
  31. package/fesm2022/star-ng-ui-editor.mjs +416 -0
  32. package/fesm2022/star-ng-ui-editor.mjs.map +1 -0
  33. package/fesm2022/star-ng-ui-field.mjs +378 -0
  34. package/fesm2022/star-ng-ui-field.mjs.map +1 -0
  35. package/fesm2022/star-ng-ui-file-upload.mjs +762 -0
  36. package/fesm2022/star-ng-ui-file-upload.mjs.map +1 -0
  37. package/fesm2022/star-ng-ui-i18n-de.mjs +179 -0
  38. package/fesm2022/star-ng-ui-i18n-de.mjs.map +1 -0
  39. package/fesm2022/star-ng-ui-i18n-es.mjs +179 -0
  40. package/fesm2022/star-ng-ui-i18n-es.mjs.map +1 -0
  41. package/fesm2022/star-ng-ui-input-group.mjs +188 -0
  42. package/fesm2022/star-ng-ui-input-group.mjs.map +1 -0
  43. package/fesm2022/star-ng-ui-input-mask.mjs +434 -0
  44. package/fesm2022/star-ng-ui-input-mask.mjs.map +1 -0
  45. package/fesm2022/star-ng-ui-input-number.mjs +691 -0
  46. package/fesm2022/star-ng-ui-input-number.mjs.map +1 -0
  47. package/fesm2022/star-ng-ui-input-otp.mjs +343 -0
  48. package/fesm2022/star-ng-ui-input-otp.mjs.map +1 -0
  49. package/fesm2022/star-ng-ui-input-tags.mjs +616 -0
  50. package/fesm2022/star-ng-ui-input-tags.mjs.map +1 -0
  51. package/fesm2022/star-ng-ui-knob.mjs +514 -0
  52. package/fesm2022/star-ng-ui-knob.mjs.map +1 -0
  53. package/fesm2022/star-ng-ui-layout.mjs +608 -0
  54. package/fesm2022/star-ng-ui-layout.mjs.map +1 -0
  55. package/fesm2022/star-ng-ui-listbox.mjs +978 -0
  56. package/fesm2022/star-ng-ui-listbox.mjs.map +1 -0
  57. package/fesm2022/star-ng-ui-media.mjs +833 -0
  58. package/fesm2022/star-ng-ui-media.mjs.map +1 -0
  59. package/fesm2022/star-ng-ui-menu.mjs +1840 -0
  60. package/fesm2022/star-ng-ui-menu.mjs.map +1 -0
  61. package/fesm2022/star-ng-ui-message.mjs +191 -0
  62. package/fesm2022/star-ng-ui-message.mjs.map +1 -0
  63. package/fesm2022/star-ng-ui-paginator.mjs +387 -0
  64. package/fesm2022/star-ng-ui-paginator.mjs.map +1 -0
  65. package/fesm2022/star-ng-ui-panel.mjs +324 -0
  66. package/fesm2022/star-ng-ui-panel.mjs.map +1 -0
  67. package/fesm2022/star-ng-ui-password.mjs +517 -0
  68. package/fesm2022/star-ng-ui-password.mjs.map +1 -0
  69. package/fesm2022/star-ng-ui-popover.mjs +241 -0
  70. package/fesm2022/star-ng-ui-popover.mjs.map +1 -0
  71. package/fesm2022/star-ng-ui-progress-bar.mjs +183 -0
  72. package/fesm2022/star-ng-ui-progress-bar.mjs.map +1 -0
  73. package/fesm2022/star-ng-ui-radio.mjs +411 -0
  74. package/fesm2022/star-ng-ui-radio.mjs.map +1 -0
  75. package/fesm2022/star-ng-ui-rating.mjs +211 -0
  76. package/fesm2022/star-ng-ui-rating.mjs.map +1 -0
  77. package/fesm2022/star-ng-ui-select-button.mjs +613 -0
  78. package/fesm2022/star-ng-ui-select-button.mjs.map +1 -0
  79. package/fesm2022/star-ng-ui-select.mjs +2523 -0
  80. package/fesm2022/star-ng-ui-select.mjs.map +1 -0
  81. package/fesm2022/star-ng-ui-skeleton.mjs +160 -0
  82. package/fesm2022/star-ng-ui-skeleton.mjs.map +1 -0
  83. package/fesm2022/star-ng-ui-slider.mjs +552 -0
  84. package/fesm2022/star-ng-ui-slider.mjs.map +1 -0
  85. package/fesm2022/star-ng-ui-spinner.mjs +148 -0
  86. package/fesm2022/star-ng-ui-spinner.mjs.map +1 -0
  87. package/fesm2022/star-ng-ui-stepper.mjs +360 -0
  88. package/fesm2022/star-ng-ui-stepper.mjs.map +1 -0
  89. package/fesm2022/star-ng-ui-table.mjs +3477 -0
  90. package/fesm2022/star-ng-ui-table.mjs.map +1 -0
  91. package/fesm2022/star-ng-ui-tabs.mjs +464 -0
  92. package/fesm2022/star-ng-ui-tabs.mjs.map +1 -0
  93. package/fesm2022/star-ng-ui-tag.mjs +129 -0
  94. package/fesm2022/star-ng-ui-tag.mjs.map +1 -0
  95. package/fesm2022/star-ng-ui-theme-switch.mjs +105 -0
  96. package/fesm2022/star-ng-ui-theme-switch.mjs.map +1 -0
  97. package/fesm2022/star-ng-ui-theme.mjs +98 -0
  98. package/fesm2022/star-ng-ui-theme.mjs.map +1 -0
  99. package/fesm2022/star-ng-ui-toast.mjs +298 -0
  100. package/fesm2022/star-ng-ui-toast.mjs.map +1 -0
  101. package/fesm2022/star-ng-ui-toggle-switch.mjs +316 -0
  102. package/fesm2022/star-ng-ui-toggle-switch.mjs.map +1 -0
  103. package/fesm2022/star-ng-ui-tooltip.mjs +297 -0
  104. package/fesm2022/star-ng-ui-tooltip.mjs.map +1 -0
  105. package/fesm2022/star-ng-ui-transloco.mjs +40 -0
  106. package/fesm2022/star-ng-ui-transloco.mjs.map +1 -0
  107. package/fesm2022/star-ng-ui-tree.mjs +1446 -0
  108. package/fesm2022/star-ng-ui-tree.mjs.map +1 -0
  109. package/fesm2022/star-ng-ui-utility.mjs +2134 -0
  110. package/fesm2022/star-ng-ui-utility.mjs.map +1 -0
  111. package/fesm2022/star-ng-ui.mjs +51 -0
  112. package/package.json +281 -3
  113. package/styles/_base.scss +70 -0
  114. package/styles/_shared.scss +2 -0
  115. package/styles/_tokens.scss +190 -0
  116. package/styles/controls/_accordion.scss +75 -0
  117. package/styles/controls/_autocomplete.scss +44 -0
  118. package/styles/controls/_avatar.scss +39 -0
  119. package/styles/controls/_breadcrumb.scss +45 -0
  120. package/styles/controls/_button.scss +137 -0
  121. package/styles/controls/_card.scss +38 -0
  122. package/styles/controls/_chart.scss +214 -0
  123. package/styles/controls/_chip.scss +51 -0
  124. package/styles/controls/_choice.scss +153 -0
  125. package/styles/controls/_data-display.scss +118 -0
  126. package/styles/controls/_date-picker.scss +300 -0
  127. package/styles/controls/_dialog.scss +123 -0
  128. package/styles/controls/_drawer.scss +118 -0
  129. package/styles/controls/_editor.scss +74 -0
  130. package/styles/controls/_field.scss +92 -0
  131. package/styles/controls/_file-upload.scss +136 -0
  132. package/styles/controls/_input-group.scss +104 -0
  133. package/styles/controls/_input-mask.scss +46 -0
  134. package/styles/controls/_input-number.scss +125 -0
  135. package/styles/controls/_knob.scss +76 -0
  136. package/styles/controls/_layout.scss +182 -0
  137. package/styles/controls/_listbox.scss +38 -0
  138. package/styles/controls/_media.scss +222 -0
  139. package/styles/controls/_menu.scss +254 -0
  140. package/styles/controls/_message.scss +48 -0
  141. package/styles/controls/_org-chart.scss +128 -0
  142. package/styles/controls/_paginator.scss +59 -0
  143. package/styles/controls/_panel.scss +83 -0
  144. package/styles/controls/_popover.scss +40 -0
  145. package/styles/controls/_progress-bar.scss +74 -0
  146. package/styles/controls/_select-button.scss +61 -0
  147. package/styles/controls/_select.scss +216 -0
  148. package/styles/controls/_skeleton.scss +43 -0
  149. package/styles/controls/_slider.scss +163 -0
  150. package/styles/controls/_spinner.scss +34 -0
  151. package/styles/controls/_stepper.scss +109 -0
  152. package/styles/controls/_table.scss +523 -0
  153. package/styles/controls/_tabs.scss +93 -0
  154. package/styles/controls/_tag.scss +84 -0
  155. package/styles/controls/_toast.scss +141 -0
  156. package/styles/controls/_tooltip.scss +14 -0
  157. package/styles/controls/_tree.scss +113 -0
  158. package/styles/controls/_utility.scss +654 -0
  159. package/styles/star-ng.css +5803 -0
  160. package/styles/star-ng.min.css +1 -0
  161. package/styles/star-ng.scss +50 -0
  162. package/theme/star-theme-first-paint.js +1 -0
  163. package/types/star-ng-ui-accordion.d.ts +82 -0
  164. package/types/star-ng-ui-autocomplete.d.ts +171 -0
  165. package/types/star-ng-ui-avatar.d.ts +43 -0
  166. package/types/star-ng-ui-badge.d.ts +46 -0
  167. package/types/star-ng-ui-breadcrumb.d.ts +39 -0
  168. package/types/star-ng-ui-button.d.ts +79 -0
  169. package/types/star-ng-ui-card.d.ts +29 -0
  170. package/types/star-ng-ui-chart.d.ts +337 -0
  171. package/types/star-ng-ui-checkbox.d.ts +92 -0
  172. package/types/star-ng-ui-core.d.ts +310 -0
  173. package/types/star-ng-ui-data-display.d.ts +339 -0
  174. package/types/star-ng-ui-date-picker.d.ts +701 -0
  175. package/types/star-ng-ui-dialog.d.ts +254 -0
  176. package/types/star-ng-ui-drawer.d.ts +29 -0
  177. package/types/star-ng-ui-editor.d.ts +96 -0
  178. package/types/star-ng-ui-field.d.ts +146 -0
  179. package/types/star-ng-ui-file-upload.d.ts +192 -0
  180. package/types/star-ng-ui-i18n-de.d.ts +7 -0
  181. package/types/star-ng-ui-i18n-es.d.ts +7 -0
  182. package/types/star-ng-ui-input-group.d.ts +58 -0
  183. package/types/star-ng-ui-input-mask.d.ts +126 -0
  184. package/types/star-ng-ui-input-number.d.ts +193 -0
  185. package/types/star-ng-ui-input-otp.d.ts +86 -0
  186. package/types/star-ng-ui-input-tags.d.ts +159 -0
  187. package/types/star-ng-ui-knob.d.ts +121 -0
  188. package/types/star-ng-ui-layout.d.ts +154 -0
  189. package/types/star-ng-ui-listbox.d.ts +197 -0
  190. package/types/star-ng-ui-media.d.ts +161 -0
  191. package/types/star-ng-ui-menu.d.ts +332 -0
  192. package/types/star-ng-ui-message.d.ts +52 -0
  193. package/types/star-ng-ui-paginator.d.ts +85 -0
  194. package/types/star-ng-ui-panel.d.ts +65 -0
  195. package/types/star-ng-ui-password.d.ts +129 -0
  196. package/types/star-ng-ui-popover.d.ts +57 -0
  197. package/types/star-ng-ui-progress-bar.d.ts +49 -0
  198. package/types/star-ng-ui-radio.d.ts +116 -0
  199. package/types/star-ng-ui-rating.d.ts +52 -0
  200. package/types/star-ng-ui-select-button.d.ts +169 -0
  201. package/types/star-ng-ui-select.d.ts +540 -0
  202. package/types/star-ng-ui-skeleton.d.ts +47 -0
  203. package/types/star-ng-ui-slider.d.ts +145 -0
  204. package/types/star-ng-ui-spinner.d.ts +29 -0
  205. package/types/star-ng-ui-stepper.d.ts +89 -0
  206. package/types/star-ng-ui-table.d.ts +829 -0
  207. package/types/star-ng-ui-tabs.d.ts +109 -0
  208. package/types/star-ng-ui-tag.d.ts +35 -0
  209. package/types/star-ng-ui-theme-switch.d.ts +36 -0
  210. package/types/star-ng-ui-theme.d.ts +95 -0
  211. package/types/star-ng-ui-toast.d.ts +84 -0
  212. package/types/star-ng-ui-toggle-switch.d.ts +81 -0
  213. package/types/star-ng-ui-tooltip.d.ts +66 -0
  214. package/types/star-ng-ui-transloco.d.ts +14 -0
  215. package/types/star-ng-ui-tree.d.ts +310 -0
  216. package/types/star-ng-ui-utility.d.ts +533 -0
  217. package/types/star-ng-ui.d.ts +51 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-ng-ui-dialog.mjs","names":[],"sources":["../../../projects/star-ng/dialog/dialog.ts","../../../projects/star-ng/dialog/confirm.ts","../../../projects/star-ng/dialog/dialog-service.ts"],"sourcesContent":["import { _IdGenerator } from '@angular/cdk/a11y';\nimport {\n afterRenderEffect,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n model,\n output,\n viewChild,\n} from '@angular/core';\nimport { STAR_UI_TEXT } from '@star-ng/ui/core';\n\nconst FOCUSABLE =\n 'button:not([disabled]), [href], input:not([disabled]), select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\nexport type StarDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';\n\n/**\n * Dialog (PrimeNG `p-dialog`) built on the native `<dialog>` element: top-layer rendering,\n * focus trap, focus restore and Escape handling come from the browser. Entry / exit animate\n * with `@starting-style`; page scroll locks with `:has(dialog[open])`.\n *\n * ```html\n * <star-dialog [(visible)]=\"editOpen\" header=\"Edit order\" size=\"lg\">\n * ...body...\n * <div starDialogFooter>\n * <star-button variant=\"ghost\" (pressed)=\"editOpen.set(false)\">Cancel</star-button>\n * <star-button (pressed)=\"save()\">Save</star-button>\n * </div>\n * </star-dialog>\n * ```\n * Put `autofocus` (native elements) or `data-autofocus` (components) on the element that\n * should receive focus first.\n */\n@Component({\n selector: 'star-dialog',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <!-- Backdrop click only; keyboard users close with Escape (native cancel event). -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <dialog\n #dialog\n class=\"star-dialog\"\n [class]=\"'star-dialog--' + size()\"\n [class.star-dialog--modal]=\"modal()\"\n [style.width]=\"width()\"\n [attr.aria-labelledby]=\"header() ? headerId : null\"\n [attr.aria-label]=\"header() ? null : ariaLabel()\"\n [attr.role]=\"role()\"\n (cancel)=\"onCancel($event)\"\n (close)=\"onNativeClose()\"\n (click)=\"onDialogClick($event)\"\n >\n <div class=\"star-dialog__surface\">\n @if (showHeader()) {\n <header class=\"star-dialog__header\">\n <div class=\"star-dialog__heading\">\n @if (header()) {\n <h2 class=\"star-dialog__title\" [id]=\"headerId\">{{ header() }}</h2>\n }\n <ng-content select=\"[starDialogHeader]\" />\n </div>\n @if (closable()) {\n <button\n type=\"button\"\n class=\"star-btn star-btn--ghost star-btn--icon star-dialog__close\"\n [attr.aria-label]=\"text.close\"\n (click)=\"close()\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n }\n <div class=\"star-dialog__body\"><ng-content /></div>\n <ng-content select=\"[starDialogFooter]\" />\n </div>\n </dialog>\n `,\n})\nexport class StarDialog {\n protected readonly text = inject(STAR_UI_TEXT);\n\n readonly visible = model(false);\n readonly header = input('');\n readonly size = input<StarDialogSize>('md');\n /** Fixed CSS width; overrides `size`. */\n readonly width = input<string | null>(null);\n /** Modal blocks the page behind (backdrop). Non-modal dialogs float above it. */\n readonly modal = input(true, { transform: booleanAttribute });\n readonly closable = input(true, { transform: booleanAttribute });\n readonly closeOnEscape = input(true, { transform: booleanAttribute });\n /** Clicking the backdrop closes the dialog. */\n readonly dismissableMask = input(false, { transform: booleanAttribute });\n readonly showHeader = input(true, { transform: booleanAttribute });\n readonly role = input<'dialog' | 'alertdialog'>('dialog');\n readonly ariaLabel = input<string | null>(null);\n\n readonly shown = output<void>();\n readonly hidden = output<void>();\n\n protected readonly headerId = inject(_IdGenerator).getId('star-dialog-title-');\n private readonly dialog = viewChild.required<ElementRef<HTMLDialogElement>>('dialog');\n private isOpen = false;\n\n constructor() {\n afterRenderEffect({\n write: () => {\n const element = this.dialog().nativeElement;\n const visible = this.visible();\n if (visible && !element.open) {\n if (this.modal()) element.showModal?.();\n else element.show?.();\n this.isOpen = true;\n this.focusInitial(element);\n this.shown.emit();\n } else if (!visible && element.open) {\n element.close();\n // Do not wait for the native 'close' event: some hosts (background or embedded\n // browsers) deliver it late or not at all.\n this.markHidden();\n }\n },\n });\n }\n\n close(): void {\n this.visible.set(false);\n }\n\n /**\n * Native `autofocus` only works on focusable elements. `data-autofocus` also works on a\n * wrapper component such as `<star-button data-autofocus>`: its first focusable child gets focus.\n */\n private focusInitial(element: HTMLDialogElement): void {\n const marked = element.querySelector<HTMLElement>('[data-autofocus]');\n if (!marked) return;\n const target = marked.matches(FOCUSABLE)\n ? marked\n : marked.querySelector<HTMLElement>(FOCUSABLE);\n target?.focus();\n }\n\n protected onCancel(event: Event): void {\n // We own the state: never let the browser close without updating `visible`.\n event.preventDefault();\n if (this.closeOnEscape() && this.closable()) this.close();\n }\n\n /** Browser-initiated close (for example a form with method=\"dialog\"). */\n protected onNativeClose(): void {\n if (this.visible()) this.visible.set(false);\n this.markHidden();\n }\n\n /** Emits `hidden` once per open. */\n private markHidden(): void {\n if (!this.isOpen) return;\n this.isOpen = false;\n this.hidden.emit();\n }\n\n protected onDialogClick(event: MouseEvent): void {\n // A click whose target is the <dialog> itself landed on the ::backdrop.\n if (event.target === this.dialog().nativeElement && this.dismissableMask() && this.modal()) {\n this.close();\n }\n }\n}\n","import {\n afterRenderEffect,\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n Service,\n signal,\n viewChild,\n} from '@angular/core';\nimport { StarButton, StarButtonVariant } from '@star-ng/ui/button';\nimport { STAR_UI_TEXT } from '@star-ng/ui/core';\nimport { StarPopover } from '@star-ng/ui/popover';\nimport { StarDialog } from './dialog';\n\nexport interface StarConfirmOptions {\n readonly header: string;\n readonly message: string;\n /** Phosphor icon class, for example `ph-bold ph-warning`. */\n readonly icon?: string;\n readonly acceptLabel?: string;\n readonly rejectLabel?: string;\n readonly acceptVariant?: StarButtonVariant;\n /** Hide the reject button (acknowledge-only dialog). */\n readonly rejectVisible?: boolean;\n /** `reject` (default) puts first focus on the safe choice. */\n readonly defaultFocus?: 'accept' | 'reject';\n /**\n * Anchor element: shows a small popup next to it (PrimeNG `p-confirmpopup`) instead of a\n * modal dialog. Use for low-risk confirmations on a row or button.\n */\n readonly target?: HTMLElement;\n}\n\ninterface PendingConfirm extends StarConfirmOptions {\n readonly resolve: (accepted: boolean) => void;\n}\n\n/**\n * Promise-based confirmation (PrimeNG `ConfirmationService` + `p-confirmdialog` /\n * `p-confirmpopup`). Requests queue; place one `<star-confirm-host />` in the app shell.\n * Pass `target` to anchor a popup to an element instead of opening a dialog.\n *\n * ```ts\n * if (await this.confirm.ask({ header: 'Delete order', message: 'This cannot be undone.',\n * acceptVariant: 'danger', icon: 'ph-bold ph-trash' })) { ... }\n * ```\n */\n@Service()\nexport class StarConfirmService {\n private readonly queue = signal<readonly PendingConfirm[]>([]);\n readonly current = computed(() => this.queue()[0] ?? null);\n\n ask(options: StarConfirmOptions): Promise<boolean> {\n return new Promise<boolean>((resolve) =>\n this.queue.update((queue) => [...queue, { ...options, resolve }]),\n );\n }\n\n /** Resolves the visible request. */\n settle(accepted: boolean): void {\n const current = this.current();\n if (!current) return;\n this.queue.update((queue) => queue.slice(1));\n current.resolve(accepted);\n }\n}\n\n@Component({\n selector: 'star-confirm-host',\n imports: [StarDialog, StarButton, StarPopover],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @let request = dialogRequest();\n @let popup = popupRequest();\n <star-popover #popover [ariaLabel]=\"popup?.header ?? null\" (hidden)=\"onPopupHidden()\">\n @if (popup) {\n <div\n class=\"star-confirm star-confirm--popup\"\n role=\"alertdialog\"\n [attr.aria-label]=\"popup.header\"\n >\n @if (popup.icon) {\n <span class=\"star-confirm__icon\" aria-hidden=\"true\"><i [class]=\"popup.icon\"></i></span>\n }\n <p class=\"star-confirm__message\">{{ popup.message }}</p>\n </div>\n <div class=\"star-confirm__actions\">\n @if (popup.rejectVisible !== false) {\n <star-button size=\"sm\" variant=\"ghost\" (pressed)=\"confirm.settle(false)\">\n {{ popup.rejectLabel ?? text.reject }}\n </star-button>\n }\n <star-button\n size=\"sm\"\n [variant]=\"popup.acceptVariant ?? 'primary'\"\n (pressed)=\"confirm.settle(true)\"\n >\n {{ popup.acceptLabel ?? text.accept }}\n </star-button>\n </div>\n }\n </star-popover>\n <star-dialog\n [role]=\"'alertdialog'\"\n size=\"sm\"\n [visible]=\"!!request\"\n [header]=\"request ? request.header : ''\"\n (visibleChange)=\"!$event && confirm.settle(false)\"\n >\n @if (request) {\n <div class=\"star-confirm\">\n @if (request.icon) {\n <span class=\"star-confirm__icon\" aria-hidden=\"true\"\n ><i [class]=\"request.icon\"></i\n ></span>\n }\n <p class=\"star-confirm__message\">{{ request.message }}</p>\n </div>\n }\n @if (request) {\n <div starDialogFooter class=\"star-dialog__footer\">\n @if (request.rejectVisible !== false) {\n <star-button\n variant=\"ghost\"\n [attr.data-autofocus]=\"request.defaultFocus !== 'accept' ? '' : null\"\n (pressed)=\"confirm.settle(false)\"\n >\n {{ request.rejectLabel ?? text.reject }}\n </star-button>\n }\n <star-button\n [variant]=\"request.acceptVariant ?? 'primary'\"\n [attr.data-autofocus]=\"request.defaultFocus === 'accept' ? '' : null\"\n (pressed)=\"confirm.settle(true)\"\n >\n {{ request.acceptLabel ?? text.accept }}\n </star-button>\n </div>\n }\n </star-dialog>\n `,\n})\nexport class StarConfirmHost {\n protected readonly confirm = inject(StarConfirmService);\n protected readonly text = inject(STAR_UI_TEXT);\n private readonly popover = viewChild.required(StarPopover);\n\n protected readonly dialogRequest = computed(() => {\n const current = this.confirm.current();\n return current && !current.target ? current : null;\n });\n protected readonly popupRequest = computed(() => {\n const current = this.confirm.current();\n return current?.target ? current : null;\n });\n private shownPopup: StarConfirmOptions | null = null;\n\n constructor() {\n afterRenderEffect({\n write: () => {\n const request = this.popupRequest();\n const popover = this.popover();\n if (request?.target && request !== this.shownPopup) {\n this.shownPopup = request;\n popover.show(request.target);\n } else if (!request && this.shownPopup) {\n this.shownPopup = null;\n popover.hide();\n }\n },\n });\n }\n\n /** Outside click or Escape closes the popup: treat as reject. */\n protected onPopupHidden(): void {\n if (this.shownPopup && this.confirm.current() === this.shownPopup) {\n this.shownPopup = null;\n this.confirm.settle(false);\n }\n }\n}\n","import { NgComponentOutlet } from '@angular/common';\nimport {\n ApplicationRef,\n ChangeDetectionStrategy,\n Component,\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n inject,\n InjectionToken,\n Injector,\n input,\n Service,\n signal,\n Type,\n} from '@angular/core';\nimport { StarDialog, StarDialogSize } from './dialog';\n\n/** Data passed to the component opened by `StarDialogService.open()`. */\nexport const STAR_DIALOG_DATA = new InjectionToken<unknown>('STAR_DIALOG_DATA');\n\nexport interface StarDialogConfig<D = unknown> {\n readonly header?: string;\n readonly size?: StarDialogSize;\n readonly width?: string;\n readonly data?: D;\n /** Default true. */\n readonly closable?: boolean;\n /** Default true. */\n readonly closeOnEscape?: boolean;\n /** Close on a backdrop click. Default false. */\n readonly dismissableMask?: boolean;\n readonly role?: 'dialog' | 'alertdialog';\n /** Accessible name when there is no header. */\n readonly ariaLabel?: string;\n}\n\n/**\n * Handle of a dialog opened from code. The opened component injects it to close itself with a\n * result: `inject(StarDialogRef<Result>).close(result)`.\n */\nexport class StarDialogRef<R = unknown> {\n private resolve!: (result: R | undefined) => void;\n /** Resolves when the dialog has closed: the result, or `undefined` (Escape, ×, backdrop). */\n readonly closed = new Promise<R | undefined>((resolve) => (this.resolve = resolve));\n private result: R | undefined;\n private done = false;\n\n constructor(private readonly hide: () => void) {}\n\n close(result?: R): void {\n if (this.done) return;\n this.result = result;\n this.hide();\n }\n\n /** Called by the container once the native dialog has closed. */\n settle(): void {\n if (this.done) return;\n this.done = true;\n this.resolve(this.result);\n }\n}\n\n/** Internal host: an `star-dialog` whose body is the requested component. */\n@Component({\n selector: 'star-dialog-container',\n imports: [StarDialog, NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @let c = config();\n <star-dialog\n [(visible)]=\"visible\"\n [header]=\"c.header ?? ''\"\n [size]=\"c.size ?? 'md'\"\n [width]=\"c.width ?? null\"\n [closable]=\"c.closable ?? true\"\n [closeOnEscape]=\"c.closeOnEscape ?? true\"\n [dismissableMask]=\"c.dismissableMask ?? false\"\n [role]=\"c.role ?? 'dialog'\"\n [ariaLabel]=\"c.ariaLabel ?? null\"\n (hidden)=\"hidden()\"\n >\n <ng-container *ngComponentOutlet=\"component(); injector: contentInjector()\" />\n </star-dialog>\n `,\n})\nexport class StarDialogContainer {\n readonly component = input.required<Type<unknown>>();\n readonly config = input.required<StarDialogConfig>();\n readonly contentInjector = input.required<Injector>();\n readonly visible = signal(true);\n /** Set by the service; runs after the native dialog closed. */\n hidden: () => void = () => undefined;\n}\n\n/**\n * Opens a component in a modal `star-dialog` from code (PrimeNG `DialogService` /\n * `DynamicDialog`). No host element in the template is needed; dialogs stack in the top layer.\n *\n * ```ts\n * const ref = this.dialogs.open(EditOrder, { header: 'Edit order', size: 'lg', data: { id } });\n * const saved = await ref.closed; // value passed to ref.close(...) inside EditOrder\n * ```\n * Inside the opened component: `inject(STAR_DIALOG_DATA)` and `inject(StarDialogRef)`.\n * Put its action buttons in an element with class `star-dialog__footer`.\n */\n@Service()\nexport class StarDialogService {\n private readonly appRef = inject(ApplicationRef);\n private readonly environment = inject(EnvironmentInjector);\n private readonly openRefs = new Set<ComponentRef<StarDialogContainer>>();\n\n open<C, D = unknown, R = unknown>(\n component: Type<C>,\n config: StarDialogConfig<D> = {},\n injector: Injector = this.environment,\n ): StarDialogRef<R> {\n let host: ComponentRef<StarDialogContainer> | null = null;\n const ref = new StarDialogRef<R>(() => host?.instance.visible.set(false));\n const contentInjector = Injector.create({\n parent: injector,\n providers: [\n { provide: STAR_DIALOG_DATA, useValue: config.data },\n { provide: StarDialogRef, useValue: ref },\n ],\n });\n host = createComponent(StarDialogContainer, { environmentInjector: this.environment });\n host.setInput('component', component);\n host.setInput('config', config);\n host.setInput('contentInjector', contentInjector);\n host.instance.hidden = () => {\n ref.settle();\n this.destroy(host!);\n };\n document.body.appendChild(host.location.nativeElement);\n this.appRef.attachView(host.hostView);\n this.openRefs.add(host);\n return ref;\n }\n\n /** Closes every open dialog (for example on sign-out). */\n closeAll(): void {\n for (const host of this.openRefs) host.instance.visible.set(false);\n }\n\n private destroy(host: ComponentRef<StarDialogContainer>): void {\n if (!this.openRefs.delete(host)) return;\n this.appRef.detachView(host.hostView);\n host.destroy();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, input } from "@angular/core";
3
+ import { StarDialog } from "@star-ng/ui/dialog";
4
+ var StarDrawer = class StarDrawer extends StarDialog {
5
+ position = input("right", ...ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []);
6
+ drawerSize = input("28rem", ...ngDevMode ? [{ debugName: "drawerSize" }] : /* istanbul ignore next */ []);
7
+ static ɵfac = i0.ɵɵngDeclareFactory({
8
+ minVersion: "12.0.0",
9
+ version: "22.2.6",
10
+ ngImport: i0,
11
+ type: StarDrawer,
12
+ deps: null,
13
+ target: i0.ɵɵFactoryTarget.Component
14
+ });
15
+ static ɵcmp = i0.ɵɵngDeclareComponent({
16
+ minVersion: "17.0.0",
17
+ version: "22.2.6",
18
+ type: StarDrawer,
19
+ isStandalone: true,
20
+ selector: "star-drawer",
21
+ inputs: {
22
+ position: {
23
+ classPropertyName: "position",
24
+ publicName: "position",
25
+ isSignal: true,
26
+ isRequired: false,
27
+ transformFunction: null
28
+ },
29
+ drawerSize: {
30
+ classPropertyName: "drawerSize",
31
+ publicName: "drawerSize",
32
+ isSignal: true,
33
+ isRequired: false,
34
+ transformFunction: null
35
+ }
36
+ },
37
+ usesInheritance: true,
38
+ ngImport: i0,
39
+ template: `
40
+ <!-- Backdrop click only; keyboard users close with Escape (native cancel event). -->
41
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
42
+ <dialog
43
+ #dialog
44
+ class="star-drawer"
45
+ [class]="'star-drawer star-drawer--' + position()"
46
+ [class.star-dialog--modal]="modal()"
47
+ [style.--star-drawer-size]="drawerSize()"
48
+ [attr.aria-labelledby]="header() ? headerId : null"
49
+ [attr.aria-label]="header() ? null : ariaLabel()"
50
+ (cancel)="onCancel($event)"
51
+ (close)="onNativeClose()"
52
+ (click)="onDialogClick($event)"
53
+ >
54
+ <div class="star-dialog__surface">
55
+ @if (showHeader()) {
56
+ <header class="star-dialog__header">
57
+ <div class="star-dialog__heading">
58
+ @if (header()) {
59
+ <h2 class="star-dialog__title" [id]="headerId">{{ header() }}</h2>
60
+ }
61
+ <ng-content select="[starDialogHeader]" />
62
+ </div>
63
+ @if (closable()) {
64
+ <button
65
+ type="button"
66
+ class="star-btn star-btn--ghost star-btn--icon star-dialog__close"
67
+ [attr.aria-label]="text.close"
68
+ (click)="close()"
69
+ >
70
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
71
+ </button>
72
+ }
73
+ </header>
74
+ }
75
+ <div class="star-dialog__body"><ng-content /></div>
76
+ <ng-content select="[starDialogFooter]" />
77
+ </div>
78
+ </dialog>
79
+ `,
80
+ isInline: true,
81
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
82
+ });
83
+ };
84
+ i0.ɵɵngDeclareClassMetadata({
85
+ minVersion: "12.0.0",
86
+ version: "22.2.6",
87
+ ngImport: i0,
88
+ type: StarDrawer,
89
+ decorators: [{
90
+ type: Component,
91
+ args: [{
92
+ selector: "star-drawer",
93
+ changeDetection: ChangeDetectionStrategy.OnPush,
94
+ template: `
95
+ <!-- Backdrop click only; keyboard users close with Escape (native cancel event). -->
96
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
97
+ <dialog
98
+ #dialog
99
+ class="star-drawer"
100
+ [class]="'star-drawer star-drawer--' + position()"
101
+ [class.star-dialog--modal]="modal()"
102
+ [style.--star-drawer-size]="drawerSize()"
103
+ [attr.aria-labelledby]="header() ? headerId : null"
104
+ [attr.aria-label]="header() ? null : ariaLabel()"
105
+ (cancel)="onCancel($event)"
106
+ (close)="onNativeClose()"
107
+ (click)="onDialogClick($event)"
108
+ >
109
+ <div class="star-dialog__surface">
110
+ @if (showHeader()) {
111
+ <header class="star-dialog__header">
112
+ <div class="star-dialog__heading">
113
+ @if (header()) {
114
+ <h2 class="star-dialog__title" [id]="headerId">{{ header() }}</h2>
115
+ }
116
+ <ng-content select="[starDialogHeader]" />
117
+ </div>
118
+ @if (closable()) {
119
+ <button
120
+ type="button"
121
+ class="star-btn star-btn--ghost star-btn--icon star-dialog__close"
122
+ [attr.aria-label]="text.close"
123
+ (click)="close()"
124
+ >
125
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
126
+ </button>
127
+ }
128
+ </header>
129
+ }
130
+ <div class="star-dialog__body"><ng-content /></div>
131
+ <ng-content select="[starDialogFooter]" />
132
+ </div>
133
+ </dialog>
134
+ `
135
+ }]
136
+ }],
137
+ propDecorators: {
138
+ position: [{
139
+ type: i0.Input,
140
+ args: [{
141
+ isSignal: true,
142
+ alias: "position",
143
+ required: false
144
+ }]
145
+ }],
146
+ drawerSize: [{
147
+ type: i0.Input,
148
+ args: [{
149
+ isSignal: true,
150
+ alias: "drawerSize",
151
+ required: false
152
+ }]
153
+ }]
154
+ }
155
+ });
156
+ export { StarDrawer };
157
+
158
+ //# sourceMappingURL=star-ng-ui-drawer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-ng-ui-drawer.mjs","names":[],"sources":["../../../projects/star-ng/drawer/drawer.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { StarDialog } from '@star-ng/ui/dialog';\n\n/**\n * Drawer (PrimeNG `p-drawer`): side sheet on the native `<dialog>` element. Same API as\n * `star-dialog` (`[(visible)]`, `header`, `modal`, `dismissableMask`, `closeOnEscape`, footer slot)\n * plus `position` and a CSS `size`. `left` and `right` are the physical edges of the screen, as in\n * CSS; `start` and `end` follow the writing direction (`end` is the right edge in LTR and the left\n * edge in RTL). Use `start` / `end` for a drawer that must switch sides in right-to-left.\n *\n * `<star-drawer [(visible)]=\"detailsOpen\" header=\"ORD-1042\" position=\"right\" size=\"32rem\">…</star-drawer>`\n */\n@Component({\n selector: 'star-drawer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <!-- Backdrop click only; keyboard users close with Escape (native cancel event). -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <dialog\n #dialog\n class=\"star-drawer\"\n [class]=\"'star-drawer star-drawer--' + position()\"\n [class.star-dialog--modal]=\"modal()\"\n [style.--star-drawer-size]=\"drawerSize()\"\n [attr.aria-labelledby]=\"header() ? headerId : null\"\n [attr.aria-label]=\"header() ? null : ariaLabel()\"\n (cancel)=\"onCancel($event)\"\n (close)=\"onNativeClose()\"\n (click)=\"onDialogClick($event)\"\n >\n <div class=\"star-dialog__surface\">\n @if (showHeader()) {\n <header class=\"star-dialog__header\">\n <div class=\"star-dialog__heading\">\n @if (header()) {\n <h2 class=\"star-dialog__title\" [id]=\"headerId\">{{ header() }}</h2>\n }\n <ng-content select=\"[starDialogHeader]\" />\n </div>\n @if (closable()) {\n <button\n type=\"button\"\n class=\"star-btn star-btn--ghost star-btn--icon star-dialog__close\"\n [attr.aria-label]=\"text.close\"\n (click)=\"close()\"\n >\n <i class=\"ph-bold ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n }\n <div class=\"star-dialog__body\"><ng-content /></div>\n <ng-content select=\"[starDialogFooter]\" />\n </div>\n </dialog>\n `,\n})\nexport class StarDrawer extends StarDialog {\n readonly position = input<'left' | 'right' | 'start' | 'end' | 'top' | 'bottom'>('right');\n /** Width (left / right / start / end) or height (top / bottom). */\n readonly drawerSize = input('28rem');\n}\n"],"mappings":";;;AAyDA,IAAa,aAAb,MAAa,mBAAmB,WAAU;CAC/B,WAAW,MAA6D,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAEhF,aAAa,MAAM,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAHzB,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAU,MAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAV,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAU,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,iBAAA;EAAA,UAAA;EAAA,UA1CX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCT,UAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAEU,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAU,YAAA,CAAA;EA7CtB,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,iBAAiB,wBAAwB;GACzC,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCX,CAAA"}
@@ -0,0 +1,416 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, SecurityContext, afterRenderEffect, booleanAttribute, inject, input, model, output, signal, viewChild } from "@angular/core";
3
+ import { DomSanitizer } from "@angular/platform-browser";
4
+ import { STAR_UI_TEXT } from "@star-ng/ui/core";
5
+ import { StarToolbar } from "@star-ng/ui/layout";
6
+ const COMMANDS = [
7
+ {
8
+ command: "bold",
9
+ label: "editorBold",
10
+ icon: "ph-bold ph-text-b"
11
+ },
12
+ {
13
+ command: "italic",
14
+ label: "editorItalic",
15
+ icon: "ph-bold ph-text-italic"
16
+ },
17
+ {
18
+ command: "underline",
19
+ label: "editorUnderline",
20
+ icon: "ph-bold ph-text-underline"
21
+ },
22
+ {
23
+ command: "formatBlock",
24
+ value: "h3",
25
+ label: "editorHeading",
26
+ icon: "ph-bold ph-text-h"
27
+ },
28
+ {
29
+ command: "insertUnorderedList",
30
+ label: "editorBulletList",
31
+ icon: "ph-bold ph-list-bullets"
32
+ },
33
+ {
34
+ command: "insertOrderedList",
35
+ label: "editorNumberedList",
36
+ icon: "ph-bold ph-list-numbers"
37
+ },
38
+ {
39
+ command: "removeFormat",
40
+ label: "editorClearFormatting",
41
+ icon: "ph-bold ph-text-t-slash"
42
+ }
43
+ ];
44
+ var StarEditor = class StarEditor {
45
+ text = inject(STAR_UI_TEXT);
46
+ sanitizer = inject(DomSanitizer);
47
+ value = model("", ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
48
+ placeholder = input("", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
49
+ minHeight = input("8rem", ...ngDevMode ? [{ debugName: "minHeight" }] : /* istanbul ignore next */ []);
50
+ ariaLabel = input(null, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
51
+ disabled = input(false, {
52
+ ...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
53
+ transform: booleanAttribute
54
+ });
55
+ readonly = input(false, {
56
+ ...ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {},
57
+ transform: booleanAttribute
58
+ });
59
+ invalid = input(false, {
60
+ ...ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {},
61
+ transform: booleanAttribute
62
+ });
63
+ touched = input(false, {
64
+ ...ngDevMode ? { debugName: "touched" } : /* istanbul ignore next */ {},
65
+ transform: booleanAttribute
66
+ });
67
+ touch = output();
68
+ commands = COMMANDS;
69
+ label(cmd) {
70
+ return this.text[cmd.label];
71
+ }
72
+ area = viewChild.required("area", ...ngDevMode ? [{ debugName: "area" }] : /* istanbul ignore next */ []);
73
+ active = signal(/* @__PURE__ */ new Set(), ...ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []);
74
+ lastWritten = null;
75
+ constructor() {
76
+ afterRenderEffect({ write: () => {
77
+ const html = this.value();
78
+ if (html === this.lastWritten) return;
79
+ this.area().nativeElement.innerHTML = this.sanitize(html);
80
+ this.lastWritten = html;
81
+ } });
82
+ }
83
+ sanitize(html) {
84
+ return this.sanitizer.sanitize(SecurityContext.HTML, html) ?? "";
85
+ }
86
+ onInput() {
87
+ const element = this.area().nativeElement;
88
+ const html = element.textContent?.trim() ? this.sanitize(element.innerHTML) : "";
89
+ this.lastWritten = html;
90
+ this.value.set(html);
91
+ this.refreshState();
92
+ }
93
+ run(cmd) {
94
+ this.area().nativeElement.focus();
95
+ document.execCommand?.(cmd.command, false, cmd.value);
96
+ this.onInput();
97
+ }
98
+ link() {
99
+ const url = prompt(this.text.editorLinkPrompt);
100
+ if (!url || !/^https?:\/\//i.test(url)) return;
101
+ this.area().nativeElement.focus();
102
+ document.execCommand?.("createLink", false, url);
103
+ this.onInput();
104
+ }
105
+ isActive(cmd) {
106
+ return cmd.command === "formatBlock" || cmd.command === "removeFormat" ? null : this.active().has(cmd.command);
107
+ }
108
+ refreshState() {
109
+ const on = /* @__PURE__ */ new Set();
110
+ for (const cmd of COMMANDS) try {
111
+ if (document.queryCommandState?.(cmd.command)) on.add(cmd.command);
112
+ } catch {}
113
+ this.active.set(on);
114
+ }
115
+ focus() {
116
+ this.area().nativeElement.focus();
117
+ }
118
+ static ɵfac = i0.ɵɵngDeclareFactory({
119
+ minVersion: "12.0.0",
120
+ version: "22.2.6",
121
+ ngImport: i0,
122
+ type: StarEditor,
123
+ deps: [],
124
+ target: i0.ɵɵFactoryTarget.Component
125
+ });
126
+ static ɵcmp = i0.ɵɵngDeclareComponent({
127
+ minVersion: "17.0.0",
128
+ version: "22.2.6",
129
+ type: StarEditor,
130
+ isStandalone: true,
131
+ selector: "star-editor",
132
+ inputs: {
133
+ value: {
134
+ classPropertyName: "value",
135
+ publicName: "value",
136
+ isSignal: true,
137
+ isRequired: false,
138
+ transformFunction: null
139
+ },
140
+ placeholder: {
141
+ classPropertyName: "placeholder",
142
+ publicName: "placeholder",
143
+ isSignal: true,
144
+ isRequired: false,
145
+ transformFunction: null
146
+ },
147
+ minHeight: {
148
+ classPropertyName: "minHeight",
149
+ publicName: "minHeight",
150
+ isSignal: true,
151
+ isRequired: false,
152
+ transformFunction: null
153
+ },
154
+ ariaLabel: {
155
+ classPropertyName: "ariaLabel",
156
+ publicName: "ariaLabel",
157
+ isSignal: true,
158
+ isRequired: false,
159
+ transformFunction: null
160
+ },
161
+ disabled: {
162
+ classPropertyName: "disabled",
163
+ publicName: "disabled",
164
+ isSignal: true,
165
+ isRequired: false,
166
+ transformFunction: null
167
+ },
168
+ readonly: {
169
+ classPropertyName: "readonly",
170
+ publicName: "readonly",
171
+ isSignal: true,
172
+ isRequired: false,
173
+ transformFunction: null
174
+ },
175
+ invalid: {
176
+ classPropertyName: "invalid",
177
+ publicName: "invalid",
178
+ isSignal: true,
179
+ isRequired: false,
180
+ transformFunction: null
181
+ },
182
+ touched: {
183
+ classPropertyName: "touched",
184
+ publicName: "touched",
185
+ isSignal: true,
186
+ isRequired: false,
187
+ transformFunction: null
188
+ }
189
+ },
190
+ outputs: {
191
+ value: "valueChange",
192
+ touch: "touch"
193
+ },
194
+ host: {
195
+ properties: {
196
+ "class.star-editor--disabled": "disabled()",
197
+ "class.star-editor--invalid": "invalid() && touched()"
198
+ },
199
+ classAttribute: "star-editor"
200
+ },
201
+ viewQueries: [{
202
+ propertyName: "area",
203
+ first: true,
204
+ predicate: ["area"],
205
+ descendants: true,
206
+ isSignal: true
207
+ }],
208
+ ngImport: i0,
209
+ template: `
210
+ <star-toolbar
211
+ class="star-editor__toolbar"
212
+ [ariaLabel]="text.editorFormatting(ariaLabel() ?? text.editorLabel)"
213
+ >
214
+ <ng-container starToolbarStart>
215
+ @for (cmd of commands; track cmd.command + (cmd.value ?? '')) {
216
+ <button
217
+ type="button"
218
+ class="star-editor__btn"
219
+ [attr.aria-label]="label(cmd)"
220
+ [attr.aria-pressed]="isActive(cmd)"
221
+ [disabled]="disabled() || readonly()"
222
+ (mousedown)="$event.preventDefault()"
223
+ (click)="run(cmd)"
224
+ >
225
+ <i [class]="cmd.icon" aria-hidden="true"></i>
226
+ </button>
227
+ }
228
+ <button
229
+ type="button"
230
+ class="star-editor__btn"
231
+ [attr.aria-label]="text.editorLink"
232
+ [disabled]="disabled() || readonly()"
233
+ (mousedown)="$event.preventDefault()"
234
+ (click)="link()"
235
+ >
236
+ <i class="ph-bold ph-link" aria-hidden="true"></i>
237
+ </button>
238
+ </ng-container>
239
+ </star-toolbar>
240
+ <div
241
+ #area
242
+ class="star-editor__area"
243
+ role="textbox"
244
+ aria-multiline="true"
245
+ [attr.tabindex]="disabled() ? -1 : 0"
246
+ [attr.contenteditable]="disabled() || readonly() ? 'false' : 'true'"
247
+ [attr.aria-label]="ariaLabel()"
248
+ [attr.aria-readonly]="readonly() || null"
249
+ [attr.aria-disabled]="disabled() || null"
250
+ [attr.data-placeholder]="placeholder()"
251
+ [style.min-height]="minHeight()"
252
+ (input)="onInput()"
253
+ (keyup)="refreshState()"
254
+ (mouseup)="refreshState()"
255
+ (blur)="touch.emit()"
256
+ ></div>
257
+ `,
258
+ isInline: true,
259
+ dependencies: [{
260
+ kind: "component",
261
+ type: StarToolbar,
262
+ selector: "star-toolbar",
263
+ inputs: ["ariaLabel"]
264
+ }],
265
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
266
+ });
267
+ };
268
+ i0.ɵɵngDeclareClassMetadata({
269
+ minVersion: "12.0.0",
270
+ version: "22.2.6",
271
+ ngImport: i0,
272
+ type: StarEditor,
273
+ decorators: [{
274
+ type: Component,
275
+ args: [{
276
+ selector: "star-editor",
277
+ imports: [StarToolbar],
278
+ changeDetection: ChangeDetectionStrategy.OnPush,
279
+ host: {
280
+ class: "star-editor",
281
+ "[class.star-editor--disabled]": "disabled()",
282
+ "[class.star-editor--invalid]": "invalid() && touched()"
283
+ },
284
+ template: `
285
+ <star-toolbar
286
+ class="star-editor__toolbar"
287
+ [ariaLabel]="text.editorFormatting(ariaLabel() ?? text.editorLabel)"
288
+ >
289
+ <ng-container starToolbarStart>
290
+ @for (cmd of commands; track cmd.command + (cmd.value ?? '')) {
291
+ <button
292
+ type="button"
293
+ class="star-editor__btn"
294
+ [attr.aria-label]="label(cmd)"
295
+ [attr.aria-pressed]="isActive(cmd)"
296
+ [disabled]="disabled() || readonly()"
297
+ (mousedown)="$event.preventDefault()"
298
+ (click)="run(cmd)"
299
+ >
300
+ <i [class]="cmd.icon" aria-hidden="true"></i>
301
+ </button>
302
+ }
303
+ <button
304
+ type="button"
305
+ class="star-editor__btn"
306
+ [attr.aria-label]="text.editorLink"
307
+ [disabled]="disabled() || readonly()"
308
+ (mousedown)="$event.preventDefault()"
309
+ (click)="link()"
310
+ >
311
+ <i class="ph-bold ph-link" aria-hidden="true"></i>
312
+ </button>
313
+ </ng-container>
314
+ </star-toolbar>
315
+ <div
316
+ #area
317
+ class="star-editor__area"
318
+ role="textbox"
319
+ aria-multiline="true"
320
+ [attr.tabindex]="disabled() ? -1 : 0"
321
+ [attr.contenteditable]="disabled() || readonly() ? 'false' : 'true'"
322
+ [attr.aria-label]="ariaLabel()"
323
+ [attr.aria-readonly]="readonly() || null"
324
+ [attr.aria-disabled]="disabled() || null"
325
+ [attr.data-placeholder]="placeholder()"
326
+ [style.min-height]="minHeight()"
327
+ (input)="onInput()"
328
+ (keyup)="refreshState()"
329
+ (mouseup)="refreshState()"
330
+ (blur)="touch.emit()"
331
+ ></div>
332
+ `
333
+ }]
334
+ }],
335
+ ctorParameters: () => [],
336
+ propDecorators: {
337
+ value: [{
338
+ type: i0.Input,
339
+ args: [{
340
+ isSignal: true,
341
+ alias: "value",
342
+ required: false
343
+ }]
344
+ }, {
345
+ type: i0.Output,
346
+ args: ["valueChange"]
347
+ }],
348
+ placeholder: [{
349
+ type: i0.Input,
350
+ args: [{
351
+ isSignal: true,
352
+ alias: "placeholder",
353
+ required: false
354
+ }]
355
+ }],
356
+ minHeight: [{
357
+ type: i0.Input,
358
+ args: [{
359
+ isSignal: true,
360
+ alias: "minHeight",
361
+ required: false
362
+ }]
363
+ }],
364
+ ariaLabel: [{
365
+ type: i0.Input,
366
+ args: [{
367
+ isSignal: true,
368
+ alias: "ariaLabel",
369
+ required: false
370
+ }]
371
+ }],
372
+ disabled: [{
373
+ type: i0.Input,
374
+ args: [{
375
+ isSignal: true,
376
+ alias: "disabled",
377
+ required: false
378
+ }]
379
+ }],
380
+ readonly: [{
381
+ type: i0.Input,
382
+ args: [{
383
+ isSignal: true,
384
+ alias: "readonly",
385
+ required: false
386
+ }]
387
+ }],
388
+ invalid: [{
389
+ type: i0.Input,
390
+ args: [{
391
+ isSignal: true,
392
+ alias: "invalid",
393
+ required: false
394
+ }]
395
+ }],
396
+ touched: [{
397
+ type: i0.Input,
398
+ args: [{
399
+ isSignal: true,
400
+ alias: "touched",
401
+ required: false
402
+ }]
403
+ }],
404
+ touch: [{
405
+ type: i0.Output,
406
+ args: ["touch"]
407
+ }],
408
+ area: [{
409
+ type: i0.ViewChild,
410
+ args: ["area", { isSignal: true }]
411
+ }]
412
+ }
413
+ });
414
+ export { StarEditor };
415
+
416
+ //# sourceMappingURL=star-ng-ui-editor.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-ng-ui-editor.mjs","names":[],"sources":["../../../projects/star-ng/editor/editor.ts"],"sourcesContent":["import {\n afterRenderEffect,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n model,\n output,\n SecurityContext,\n signal,\n viewChild,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { STAR_UI_TEXT, StarUiText } from '@star-ng/ui/core';\nimport { StarToolbar } from '@star-ng/ui/layout';\n\ninterface EditorCommand {\n readonly command: string;\n readonly label: keyof StarUiText;\n readonly icon: string;\n readonly value?: string;\n}\n\nconst COMMANDS: readonly EditorCommand[] = [\n { command: 'bold', label: 'editorBold', icon: 'ph-bold ph-text-b' },\n { command: 'italic', label: 'editorItalic', icon: 'ph-bold ph-text-italic' },\n { command: 'underline', label: 'editorUnderline', icon: 'ph-bold ph-text-underline' },\n { command: 'formatBlock', value: 'h3', label: 'editorHeading', icon: 'ph-bold ph-text-h' },\n { command: 'insertUnorderedList', label: 'editorBulletList', icon: 'ph-bold ph-list-bullets' },\n { command: 'insertOrderedList', label: 'editorNumberedList', icon: 'ph-bold ph-list-numbers' },\n { command: 'removeFormat', label: 'editorClearFormatting', icon: 'ph-bold ph-text-t-slash' },\n];\n\n/**\n * Rich text field (PrimeNG `p-editor`, without Quill): a `contenteditable` area with a\n * formatting toolbar (bold, italic, underline, heading, lists, link, clear). Value is HTML,\n * sanitized with Angular's `DomSanitizer` both when it is shown and when it is stored.\n *\n * Note: formatting uses `document.execCommand`, which browsers still support but no longer\n * develop. For complex documents use a dedicated editor library.\n *\n * `<star-editor [formField]=\"form.response\" ariaLabel=\"Response\" />`\n */\n@Component({\n selector: 'star-editor',\n imports: [StarToolbar],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-editor',\n '[class.star-editor--disabled]': 'disabled()',\n '[class.star-editor--invalid]': 'invalid() && touched()',\n },\n template: `\n <star-toolbar\n class=\"star-editor__toolbar\"\n [ariaLabel]=\"text.editorFormatting(ariaLabel() ?? text.editorLabel)\"\n >\n <ng-container starToolbarStart>\n @for (cmd of commands; track cmd.command + (cmd.value ?? '')) {\n <button\n type=\"button\"\n class=\"star-editor__btn\"\n [attr.aria-label]=\"label(cmd)\"\n [attr.aria-pressed]=\"isActive(cmd)\"\n [disabled]=\"disabled() || readonly()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"run(cmd)\"\n >\n <i [class]=\"cmd.icon\" aria-hidden=\"true\"></i>\n </button>\n }\n <button\n type=\"button\"\n class=\"star-editor__btn\"\n [attr.aria-label]=\"text.editorLink\"\n [disabled]=\"disabled() || readonly()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"link()\"\n >\n <i class=\"ph-bold ph-link\" aria-hidden=\"true\"></i>\n </button>\n </ng-container>\n </star-toolbar>\n <div\n #area\n class=\"star-editor__area\"\n role=\"textbox\"\n aria-multiline=\"true\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.contenteditable]=\"disabled() || readonly() ? 'false' : 'true'\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.data-placeholder]=\"placeholder()\"\n [style.min-height]=\"minHeight()\"\n (input)=\"onInput()\"\n (keyup)=\"refreshState()\"\n (mouseup)=\"refreshState()\"\n (blur)=\"touch.emit()\"\n ></div>\n `,\n})\nexport class StarEditor implements FormValueControl<string> {\n protected readonly text = inject(STAR_UI_TEXT);\n private readonly sanitizer = inject(DomSanitizer);\n\n /** The content as HTML. Edits by the user are stored sanitized. */\n readonly value = model('');\n /** Text shown while the editor is empty. */\n readonly placeholder = input('');\n /** CSS `min-height` of the editing area. */\n readonly minHeight = input('8rem');\n /** Accessible name of the editing area. */\n readonly ariaLabel = input<string | null>(null);\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly readonly = input(false, { transform: booleanAttribute });\n readonly invalid = input(false, { transform: booleanAttribute });\n readonly touched = input(false, { transform: booleanAttribute });\n readonly touch = output<void>();\n\n protected readonly commands = COMMANDS;\n\n protected label(cmd: EditorCommand): string {\n return this.text[cmd.label] as string;\n }\n private readonly area = viewChild.required<ElementRef<HTMLDivElement>>('area');\n private readonly active = signal<ReadonlySet<string>>(new Set());\n private lastWritten: string | null = null;\n\n constructor() {\n // Write the model into the editable area only when it changed from outside.\n afterRenderEffect({\n write: () => {\n const html = this.value();\n if (html === this.lastWritten) return;\n this.area().nativeElement.innerHTML = this.sanitize(html);\n this.lastWritten = html;\n },\n });\n }\n\n private sanitize(html: string): string {\n return this.sanitizer.sanitize(SecurityContext.HTML, html) ?? '';\n }\n\n protected onInput(): void {\n const element = this.area().nativeElement;\n const html = element.textContent?.trim() ? this.sanitize(element.innerHTML) : '';\n this.lastWritten = html;\n this.value.set(html);\n this.refreshState();\n }\n\n protected run(cmd: EditorCommand): void {\n this.area().nativeElement.focus();\n document.execCommand?.(cmd.command, false, cmd.value);\n this.onInput();\n }\n\n protected link(): void {\n const url = prompt(this.text.editorLinkPrompt);\n if (!url || !/^https?:\\/\\//i.test(url)) return;\n this.area().nativeElement.focus();\n document.execCommand?.('createLink', false, url);\n this.onInput();\n }\n\n protected isActive(cmd: EditorCommand): boolean | null {\n return cmd.command === 'formatBlock' || cmd.command === 'removeFormat'\n ? null\n : this.active().has(cmd.command);\n }\n\n protected refreshState(): void {\n const on = new Set<string>();\n for (const cmd of COMMANDS) {\n try {\n if (document.queryCommandState?.(cmd.command)) on.add(cmd.command);\n } catch {\n // Some commands have no state.\n }\n }\n this.active.set(on);\n }\n\n focus(): void {\n this.area().nativeElement.focus();\n }\n}\n"],"mappings":"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"}