@muxima-ui/core 1.4.1 → 1.5.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 (86) hide show
  1. package/README.md +11 -0
  2. package/fesm2022/muxima-ui-core-alert.mjs +5 -3
  3. package/fesm2022/muxima-ui-core-alert.mjs.map +1 -1
  4. package/fesm2022/muxima-ui-core-breadcrumb.mjs +5 -3
  5. package/fesm2022/muxima-ui-core-breadcrumb.mjs.map +1 -1
  6. package/fesm2022/muxima-ui-core-carousel.mjs +19 -17
  7. package/fesm2022/muxima-ui-core-carousel.mjs.map +1 -1
  8. package/fesm2022/muxima-ui-core-chips.mjs +19 -14
  9. package/fesm2022/muxima-ui-core-chips.mjs.map +1 -1
  10. package/fesm2022/muxima-ui-core-clipboard.mjs +10 -6
  11. package/fesm2022/muxima-ui-core-clipboard.mjs.map +1 -1
  12. package/fesm2022/muxima-ui-core-color-picker.mjs +53 -50
  13. package/fesm2022/muxima-ui-core-color-picker.mjs.map +1 -1
  14. package/fesm2022/muxima-ui-core-combobox.mjs +15 -12
  15. package/fesm2022/muxima-ui-core-combobox.mjs.map +1 -1
  16. package/fesm2022/muxima-ui-core-command.mjs +21 -16
  17. package/fesm2022/muxima-ui-core-command.mjs.map +1 -1
  18. package/fesm2022/muxima-ui-core-data-grid.mjs +50 -52
  19. package/fesm2022/muxima-ui-core-data-grid.mjs.map +1 -1
  20. package/fesm2022/muxima-ui-core-date-picker.mjs +97 -69
  21. package/fesm2022/muxima-ui-core-date-picker.mjs.map +1 -1
  22. package/fesm2022/muxima-ui-core-editor.mjs +25 -19
  23. package/fesm2022/muxima-ui-core-editor.mjs.map +1 -1
  24. package/fesm2022/muxima-ui-core-file-upload.mjs +30 -25
  25. package/fesm2022/muxima-ui-core-file-upload.mjs.map +1 -1
  26. package/fesm2022/muxima-ui-core-i18n.mjs +550 -0
  27. package/fesm2022/muxima-ui-core-i18n.mjs.map +1 -0
  28. package/fesm2022/muxima-ui-core-image-cropper.mjs +27 -24
  29. package/fesm2022/muxima-ui-core-image-cropper.mjs.map +1 -1
  30. package/fesm2022/muxima-ui-core-kanban.mjs +22 -19
  31. package/fesm2022/muxima-ui-core-kanban.mjs.map +1 -1
  32. package/fesm2022/muxima-ui-core-notification-center.mjs +41 -36
  33. package/fesm2022/muxima-ui-core-notification-center.mjs.map +1 -1
  34. package/fesm2022/muxima-ui-core-pagination.mjs +29 -26
  35. package/fesm2022/muxima-ui-core-pagination.mjs.map +1 -1
  36. package/fesm2022/muxima-ui-core-progress.mjs +5 -3
  37. package/fesm2022/muxima-ui-core-progress.mjs.map +1 -1
  38. package/fesm2022/muxima-ui-core-rating.mjs +12 -8
  39. package/fesm2022/muxima-ui-core-rating.mjs.map +1 -1
  40. package/fesm2022/muxima-ui-core-select.mjs +14 -11
  41. package/fesm2022/muxima-ui-core-select.mjs.map +1 -1
  42. package/fesm2022/muxima-ui-core-sidebar.mjs +10 -7
  43. package/fesm2022/muxima-ui-core-sidebar.mjs.map +1 -1
  44. package/fesm2022/muxima-ui-core-slider.mjs +8 -6
  45. package/fesm2022/muxima-ui-core-slider.mjs.map +1 -1
  46. package/fesm2022/muxima-ui-core-stepper.mjs +5 -3
  47. package/fesm2022/muxima-ui-core-stepper.mjs.map +1 -1
  48. package/fesm2022/muxima-ui-core-table.mjs +4 -4
  49. package/fesm2022/muxima-ui-core-table.mjs.map +1 -1
  50. package/fesm2022/muxima-ui-core-time-picker.mjs +7 -5
  51. package/fesm2022/muxima-ui-core-time-picker.mjs.map +1 -1
  52. package/fesm2022/muxima-ui-core-toast.mjs +8 -5
  53. package/fesm2022/muxima-ui-core-toast.mjs.map +1 -1
  54. package/fesm2022/muxima-ui-core-tour.mjs +10 -11
  55. package/fesm2022/muxima-ui-core-tour.mjs.map +1 -1
  56. package/fesm2022/muxima-ui-core.mjs +1 -1
  57. package/fesm2022/muxima-ui-core.mjs.map +1 -1
  58. package/package.json +5 -1
  59. package/types/muxima-ui-core-alert.d.ts +3 -1
  60. package/types/muxima-ui-core-breadcrumb.d.ts +6 -4
  61. package/types/muxima-ui-core-carousel.d.ts +4 -2
  62. package/types/muxima-ui-core-chips.d.ts +23 -3
  63. package/types/muxima-ui-core-clipboard.d.ts +6 -3
  64. package/types/muxima-ui-core-color-picker.d.ts +40 -7
  65. package/types/muxima-ui-core-combobox.d.ts +6 -3
  66. package/types/muxima-ui-core-command.d.ts +7 -3
  67. package/types/muxima-ui-core-data-grid.d.ts +31 -11
  68. package/types/muxima-ui-core-date-picker.d.ts +59 -14
  69. package/types/muxima-ui-core-editor.d.ts +13 -2
  70. package/types/muxima-ui-core-file-upload.d.ts +22 -6
  71. package/types/muxima-ui-core-i18n.d.ts +322 -0
  72. package/types/muxima-ui-core-image-cropper.d.ts +19 -6
  73. package/types/muxima-ui-core-kanban.d.ts +16 -3
  74. package/types/muxima-ui-core-notification-center.d.ts +30 -8
  75. package/types/muxima-ui-core-pagination.d.ts +16 -1
  76. package/types/muxima-ui-core-progress.d.ts +10 -8
  77. package/types/muxima-ui-core-rating.d.ts +6 -2
  78. package/types/muxima-ui-core-select.d.ts +6 -3
  79. package/types/muxima-ui-core-sidebar.d.ts +6 -3
  80. package/types/muxima-ui-core-slider.d.ts +4 -2
  81. package/types/muxima-ui-core-stepper.d.ts +10 -8
  82. package/types/muxima-ui-core-table.d.ts +3 -3
  83. package/types/muxima-ui-core-time-picker.d.ts +3 -1
  84. package/types/muxima-ui-core-toast.d.ts +3 -0
  85. package/types/muxima-ui-core-tour.d.ts +6 -1
  86. package/types/muxima-ui-core.d.ts +1 -1
@@ -1,5 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, booleanAttribute, numberAttribute, model, output, viewChild, inject, signal, computed, effect, untracked, DestroyRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { input, computed, booleanAttribute, numberAttribute, model, output, viewChild, inject, signal, effect, untracked, DestroyRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { injectMxMessages } from '@muxima-ui/core/i18n';
3
4
  import { LiveAnnouncer } from '@angular/cdk/a11y';
4
5
  import { mxUniqueId } from '@muxima-ui/core/form-field';
5
6
 
@@ -93,7 +94,9 @@ const HANDLES = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];
93
94
  */
94
95
  class MxImageCropper {
95
96
  src = input(null, ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
96
- alt = input('Imagem a recortar', ...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
97
+ alt = input(...(ngDevMode ? [undefined, { debugName: "alt" }] : /* istanbul ignore next */ []));
98
+ i18n = injectMxMessages();
99
+ msg = computed(() => this.i18n().imageCropper, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
97
100
  /** Largura / altura da área (1 = quadrado, 16/9...). null = livre. */
98
101
  aspectRatio = input(null, ...(ngDevMode ? [{ debugName: "aspectRatio" }] : /* istanbul ignore next */ []));
99
102
  /** Máscara redonda (fotografias de perfil). toBlob devolve PNG com cantos transparentes. */
@@ -104,11 +107,11 @@ class MxImageCropper {
104
107
  minSize = input(40, { ...(ngDevMode ? { debugName: "minSize" } : /* istanbul ignore next */ {}), transform: numberAttribute });
105
108
  zoom = model(1, ...(ngDevMode ? [{ debugName: "zoom" }] : /* istanbul ignore next */ []));
106
109
  rotation = model(0, ...(ngDevMode ? [{ debugName: "rotation" }] : /* istanbul ignore next */ []));
107
- helpText = input('Setas movem a área. Alt e setas mudam o tamanho. Shift dá passos maiores.', ...(ngDevMode ? [{ debugName: "helpText" }] : /* istanbul ignore next */ []));
108
- zoomText = input('Zoom', ...(ngDevMode ? [{ debugName: "zoomText" }] : /* istanbul ignore next */ []));
109
- rotateLeftText = input('Rodar para a esquerda', ...(ngDevMode ? [{ debugName: "rotateLeftText" }] : /* istanbul ignore next */ []));
110
- rotateRightText = input('Rodar para a direita', ...(ngDevMode ? [{ debugName: "rotateRightText" }] : /* istanbul ignore next */ []));
111
- resetText = input('Repor', ...(ngDevMode ? [{ debugName: "resetText" }] : /* istanbul ignore next */ []));
110
+ helpText = input(...(ngDevMode ? [undefined, { debugName: "helpText" }] : /* istanbul ignore next */ []));
111
+ zoomText = input(...(ngDevMode ? [undefined, { debugName: "zoomText" }] : /* istanbul ignore next */ []));
112
+ rotateLeftText = input(...(ngDevMode ? [undefined, { debugName: "rotateLeftText" }] : /* istanbul ignore next */ []));
113
+ rotateRightText = input(...(ngDevMode ? [undefined, { debugName: "rotateRightText" }] : /* istanbul ignore next */ []));
114
+ resetText = input(...(ngDevMode ? [undefined, { debugName: "resetText" }] : /* istanbul ignore next */ []));
112
115
  /** Área recortada em píxeis da imagem original. */
113
116
  areaChange = output();
114
117
  stage = viewChild.required('stage');
@@ -168,7 +171,7 @@ class MxImageCropper {
168
171
  }, ...(ngDevMode ? [{ debugName: "area" }] : /* istanbul ignore next */ []));
169
172
  boxLabel = computed(() => {
170
173
  const a = this.area();
171
- return `${a.width} por ${a.height} píxeis`;
174
+ return this.msg().size(a.width, a.height);
172
175
  }, ...(ngDevMode ? [{ debugName: "boxLabel" }] : /* istanbul ignore next */ []));
173
176
  constructor() {
174
177
  effect(() => {
@@ -240,7 +243,7 @@ class MxImageCropper {
240
243
  rotate(deg) {
241
244
  this.rotation.update((r) => (r + deg + 360) % 360);
242
245
  this.box.set(mxCenteredRect(this.bounds(), this.aspectRatio()));
243
- this.say(`Rodada ${this.rotation()} graus`);
246
+ this.say(this.msg().rotated(this.rotation()));
244
247
  }
245
248
  say(text) {
246
249
  clearTimeout(this.liveTimer);
@@ -267,7 +270,7 @@ class MxImageCropper {
267
270
  this.box.set(mxClampRect({ ...b, x: b.x + m[0], y: b.y + m[1] }, this.bounds()));
268
271
  }
269
272
  const a = this.area();
270
- this.say(`${a.width} por ${a.height} píxeis, a ${a.x} da esquerda e ${a.y} do topo`);
273
+ this.say(this.msg().position(a.width, a.height, a.x, a.y));
271
274
  }
272
275
  drag(e, apply) {
273
276
  if (e.button !== 0)
@@ -337,7 +340,7 @@ class MxImageCropper {
337
340
  #img
338
341
  class="mx-cropper-image"
339
342
  [src]="url()"
340
- [alt]="alt()"
343
+ [alt]="(alt() ?? msg().alt)"
341
344
  draggable="false"
342
345
  [style.width.px]="natural().w"
343
346
  [style.height.px]="natural().h"
@@ -352,7 +355,7 @@ class MxImageCropper {
352
355
  class="mx-cropper-box"
353
356
  role="group"
354
357
  tabindex="0"
355
- aria-roledescription="área de recorte"
358
+ [attr.aria-roledescription]="msg().area"
356
359
  [attr.aria-label]="boxLabel()"
357
360
  [attr.aria-describedby]="helpId"
358
361
  [style.left.px]="box().x"
@@ -374,11 +377,11 @@ class MxImageCropper {
374
377
  </div>
375
378
  }
376
379
  </div>
377
- <p class="mx-visually-hidden" [id]="helpId">{{ helpText() }}</p>
380
+ <p class="mx-visually-hidden" [id]="helpId">{{ (helpText() ?? msg().help) }}</p>
378
381
  @if (controls()) {
379
382
  <div class="mx-cropper-controls">
380
383
  <label class="mx-cropper-zoom">
381
- <span>{{ zoomText() }}</span>
384
+ <span>{{ (zoomText() ?? msg().zoom) }}</span>
382
385
  <input
383
386
  type="range"
384
387
  class="mx-slider"
@@ -395,7 +398,7 @@ class MxImageCropper {
395
398
  type="button"
396
399
  class="mx-cropper-button"
397
400
  [disabled]="!ready()"
398
- [attr.aria-label]="rotateLeftText()"
401
+ [attr.aria-label]="(rotateLeftText() ?? msg().rotateLeft)"
399
402
  (click)="rotate(-90)"
400
403
  >
401
404
  <svg viewBox="0 0 16 16" fill="none" aria-hidden="true">
@@ -412,7 +415,7 @@ class MxImageCropper {
412
415
  type="button"
413
416
  class="mx-cropper-button"
414
417
  [disabled]="!ready()"
415
- [attr.aria-label]="rotateRightText()"
418
+ [attr.aria-label]="(rotateRightText() ?? msg().rotateRight)"
416
419
  (click)="rotate(90)"
417
420
  >
418
421
  <svg viewBox="0 0 16 16" fill="none" aria-hidden="true">
@@ -431,7 +434,7 @@ class MxImageCropper {
431
434
  [disabled]="!ready()"
432
435
  (click)="reset()"
433
436
  >
434
- {{ resetText() }}
437
+ {{ (resetText() ?? msg().reset) }}
435
438
  </button>
436
439
  </div>
437
440
  }
@@ -457,7 +460,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
457
460
  #img
458
461
  class="mx-cropper-image"
459
462
  [src]="url()"
460
- [alt]="alt()"
463
+ [alt]="(alt() ?? msg().alt)"
461
464
  draggable="false"
462
465
  [style.width.px]="natural().w"
463
466
  [style.height.px]="natural().h"
@@ -472,7 +475,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
472
475
  class="mx-cropper-box"
473
476
  role="group"
474
477
  tabindex="0"
475
- aria-roledescription="área de recorte"
478
+ [attr.aria-roledescription]="msg().area"
476
479
  [attr.aria-label]="boxLabel()"
477
480
  [attr.aria-describedby]="helpId"
478
481
  [style.left.px]="box().x"
@@ -494,11 +497,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
494
497
  </div>
495
498
  }
496
499
  </div>
497
- <p class="mx-visually-hidden" [id]="helpId">{{ helpText() }}</p>
500
+ <p class="mx-visually-hidden" [id]="helpId">{{ (helpText() ?? msg().help) }}</p>
498
501
  @if (controls()) {
499
502
  <div class="mx-cropper-controls">
500
503
  <label class="mx-cropper-zoom">
501
- <span>{{ zoomText() }}</span>
504
+ <span>{{ (zoomText() ?? msg().zoom) }}</span>
502
505
  <input
503
506
  type="range"
504
507
  class="mx-slider"
@@ -515,7 +518,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
515
518
  type="button"
516
519
  class="mx-cropper-button"
517
520
  [disabled]="!ready()"
518
- [attr.aria-label]="rotateLeftText()"
521
+ [attr.aria-label]="(rotateLeftText() ?? msg().rotateLeft)"
519
522
  (click)="rotate(-90)"
520
523
  >
521
524
  <svg viewBox="0 0 16 16" fill="none" aria-hidden="true">
@@ -532,7 +535,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
532
535
  type="button"
533
536
  class="mx-cropper-button"
534
537
  [disabled]="!ready()"
535
- [attr.aria-label]="rotateRightText()"
538
+ [attr.aria-label]="(rotateRightText() ?? msg().rotateRight)"
536
539
  (click)="rotate(90)"
537
540
  >
538
541
  <svg viewBox="0 0 16 16" fill="none" aria-hidden="true">
@@ -551,7 +554,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
551
554
  [disabled]="!ready()"
552
555
  (click)="reset()"
553
556
  >
554
- {{ resetText() }}
557
+ {{ (resetText() ?? msg().reset) }}
555
558
  </button>
556
559
  </div>
557
560
  }
@@ -1 +1 @@
1
- {"version":3,"file":"muxima-ui-core-image-cropper.mjs","sources":["../../../projects/core/image-cropper/crop-math.ts","../../../projects/core/image-cropper/image-cropper.ts","../../../projects/core/image-cropper/muxima-ui-core-image-cropper.ts"],"sourcesContent":["/** Rectângulo em píxeis. */\nexport interface MxRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Puxadores de redimensionar: cantos e lados. */\nexport type MxCropHandle = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';\n\n/** Mantém o rectângulo dentro dos limites, sem mudar o tamanho (a não ser que não caiba). */\nexport function mxClampRect(r: MxRect, bounds: MxRect): MxRect {\n const width = Math.min(r.width, bounds.width);\n const height = Math.min(r.height, bounds.height);\n return {\n width,\n height,\n x: Math.min(Math.max(r.x, bounds.x), bounds.x + bounds.width - width),\n y: Math.min(Math.max(r.y, bounds.y), bounds.y + bounds.height - height),\n };\n}\n\n/** Maior rectângulo com a proporção dada, centrado nos limites (ocupa `fill` do espaço). */\nexport function mxCenteredRect(bounds: MxRect, ratio: number | null, fill = 0.8): MxRect {\n let width = bounds.width * fill;\n let height = bounds.height * fill;\n if (ratio) {\n if (width / height > ratio) width = height * ratio;\n else height = width / ratio;\n }\n return {\n x: bounds.x + (bounds.width - width) / 2,\n y: bounds.y + (bounds.height - height) / 2,\n width,\n height,\n };\n}\n\n/**\n * Redimensiona a partir de um puxador por (dx, dy), respeitando a proporção, o tamanho\n * mínimo e os limites. O lado oposto ao puxador fica parado.\n */\nexport function mxResizeRect(\n r: MxRect,\n handle: MxCropHandle,\n dx: number,\n dy: number,\n bounds: MxRect,\n ratio: number | null,\n min = 24,\n): MxRect {\n let { x, y, width, height } = r;\n const right = x + width;\n const bottom = y + height;\n if (handle.includes('e'))\n width = Math.min(Math.max(width + dx, min), bounds.x + bounds.width - x);\n if (handle.includes('w')) {\n const nx = Math.min(Math.max(x + dx, bounds.x), right - min);\n width = right - nx;\n x = nx;\n }\n if (handle.includes('s'))\n height = Math.min(Math.max(height + dy, min), bounds.y + bounds.height - y);\n if (handle.includes('n')) {\n const ny = Math.min(Math.max(y + dy, bounds.y), bottom - min);\n height = bottom - ny;\n y = ny;\n }\n if (ratio) {\n // o eixo que o puxador controla manda; nos cantos, o maior movimento\n const horizontal =\n handle === 'e' || handle === 'w' || (handle.length === 2 && Math.abs(dx) >= Math.abs(dy));\n if (horizontal) height = width / ratio;\n else width = height * ratio;\n // não sair dos limites: reduz ambos\n const maxW = handle.includes('w') ? right - bounds.x : bounds.x + bounds.width - x;\n const maxH = handle.includes('n') ? bottom - bounds.y : bounds.y + bounds.height - y;\n const k = Math.min(1, maxW / width, maxH / height);\n width *= k;\n height *= k;\n if (handle.includes('w')) x = right - width;\n if (handle.includes('n')) y = bottom - height;\n if (handle === 'e' || handle === 'w')\n y = Math.min(\n Math.max(r.y + (r.height - height) / 2, bounds.y),\n bounds.y + bounds.height - height,\n );\n if (handle === 'n' || handle === 's')\n x = Math.min(\n Math.max(r.x + (r.width - width) / 2, bounds.x),\n bounds.x + bounds.width - width,\n );\n }\n return { x, y, width, height };\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n model,\n numberAttribute,\n output,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { LiveAnnouncer } from '@angular/cdk/a11y';\nimport { mxUniqueId } from '@muxima-ui/core/form-field';\nimport { MxCropHandle, MxRect, mxCenteredRect, mxClampRect, mxResizeRect } from './crop-math';\n\n/** Área recortada em píxeis da imagem original, com a rotação aplicada antes. */\nexport interface MxCropArea extends MxRect {\n rotation: number;\n}\n\nconst HANDLES: MxCropHandle[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\n\n/**\n * Recortar uma imagem antes de a enviar: arrastar a área, redimensionar pelos cantos,\n * zoom e rodar. Com teclado: setas movem a área, Alt + setas mudam o tamanho (Shift para\n * passos maiores); cada mudança é anunciada.\n *\n * ```html\n * <mx-image-cropper #c [src]=\"ficheiro\" [aspectRatio]=\"1\" round />\n * <button mxButton (click)=\"c.toBlob().then(enviar)\">Guardar</button>\n * ```\n *\n * `src` aceita um URL ou um File. `toBlob()` devolve a imagem recortada na resolução original.\n */\n@Component({\n selector: 'mx-image-cropper',\n exportAs: 'mxImageCropper',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-image-cropper',\n '[attr.data-round]': 'round() ? \"\" : null',\n '[attr.aria-label]': 'null',\n },\n template: `\n <div class=\"mx-cropper-stage\" #stage [style.height]=\"height()\">\n @if (url()) {\n <img\n #img\n class=\"mx-cropper-image\"\n [src]=\"url()\"\n [alt]=\"alt()\"\n draggable=\"false\"\n [style.width.px]=\"natural().w\"\n [style.height.px]=\"natural().h\"\n [style.transform]=\"\n 'translate(-50%, -50%) rotate(' + rotation() + 'deg) scale(' + scale() + ')'\n \"\n (load)=\"onLoad()\"\n />\n }\n @if (ready()) {\n <div\n class=\"mx-cropper-box\"\n role=\"group\"\n tabindex=\"0\"\n aria-roledescription=\"área de recorte\"\n [attr.aria-label]=\"boxLabel()\"\n [attr.aria-describedby]=\"helpId\"\n [style.left.px]=\"box().x\"\n [style.top.px]=\"box().y\"\n [style.width.px]=\"box().width\"\n [style.height.px]=\"box().height\"\n (pointerdown)=\"startMove($event)\"\n (keydown)=\"onKeydown($event)\"\n >\n <span class=\"mx-cropper-grid\" aria-hidden=\"true\"></span>\n @for (h of handles; track h) {\n <span\n class=\"mx-cropper-handle\"\n [attr.data-handle]=\"h\"\n aria-hidden=\"true\"\n (pointerdown)=\"startResize($event, h)\"\n ></span>\n }\n </div>\n }\n </div>\n <p class=\"mx-visually-hidden\" [id]=\"helpId\">{{ helpText() }}</p>\n @if (controls()) {\n <div class=\"mx-cropper-controls\">\n <label class=\"mx-cropper-zoom\">\n <span>{{ zoomText() }}</span>\n <input\n type=\"range\"\n class=\"mx-slider\"\n min=\"1\"\n max=\"4\"\n step=\"0.05\"\n [value]=\"zoom()\"\n [disabled]=\"!ready()\"\n [attr.aria-valuetext]=\"zoomPct() + '%'\"\n (input)=\"setZoom($any($event.target).valueAsNumber)\"\n />\n </label>\n <button\n type=\"button\"\n class=\"mx-cropper-button\"\n [disabled]=\"!ready()\"\n [attr.aria-label]=\"rotateLeftText()\"\n (click)=\"rotate(-90)\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3.5 6.5a5 5 0 1 1 .8 5.2M3.5 2.5v4h4\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"mx-cropper-button\"\n [disabled]=\"!ready()\"\n [attr.aria-label]=\"rotateRightText()\"\n (click)=\"rotate(90)\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12.5 6.5a5 5 0 1 0-.8 5.2M12.5 2.5v4h-4\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"mx-cropper-button mx-cropper-reset\"\n [disabled]=\"!ready()\"\n (click)=\"reset()\"\n >\n {{ resetText() }}\n </button>\n </div>\n }\n <span class=\"mx-visually-hidden\" aria-live=\"polite\">{{ live() }}</span>\n `,\n})\nexport class MxImageCropper {\n readonly src = input<string | File | Blob | null>(null);\n readonly alt = input('Imagem a recortar');\n /** Largura / altura da área (1 = quadrado, 16/9...). null = livre. */\n readonly aspectRatio = input<number | null>(null);\n /** Máscara redonda (fotografias de perfil). toBlob devolve PNG com cantos transparentes. */\n readonly round = input(false, { transform: booleanAttribute });\n readonly controls = input(true, { transform: booleanAttribute });\n readonly height = input('320px');\n /** Tamanho mínimo da área no ecrã, em px. */\n readonly minSize = input(40, { transform: numberAttribute });\n readonly zoom = model(1);\n readonly rotation = model(0);\n readonly helpText = input(\n 'Setas movem a área. Alt e setas mudam o tamanho. Shift dá passos maiores.',\n );\n readonly zoomText = input('Zoom');\n readonly rotateLeftText = input('Rodar para a esquerda');\n readonly rotateRightText = input('Rodar para a direita');\n readonly resetText = input('Repor');\n /** Área recortada em píxeis da imagem original. */\n readonly areaChange = output<MxCropArea>();\n\n private readonly stage = viewChild.required<ElementRef<HTMLElement>>('stage');\n private readonly img = viewChild<ElementRef<HTMLImageElement>>('img');\n private readonly announcer = inject(LiveAnnouncer);\n protected readonly helpId = mxUniqueId('mx-cropper-help');\n protected readonly handles = HANDLES;\n\n protected readonly url = signal<string | null>(null);\n protected readonly natural = signal({ w: 0, h: 0 });\n private readonly stageSize = signal({ w: 0, h: 0 });\n protected readonly ready = signal(false);\n readonly box = signal<MxRect>({ x: 0, y: 0, width: 0, height: 0 });\n protected readonly live = signal('');\n private objectUrl: string | null = null;\n private liveTimer?: ReturnType<typeof setTimeout>;\n\n /** Escala que faz a imagem caber no palco, vezes o zoom. */\n private readonly fit = computed(() => {\n const { w, h } = this.natural();\n const s = this.stageSize();\n if (!w || !h || !s.w || !s.h) return 1;\n const turned = Math.abs(this.rotation()) % 180 === 90;\n const iw = turned ? h : w;\n const ih = turned ? w : h;\n return Math.min(s.w / iw, s.h / ih);\n });\n protected readonly scale = computed(() => this.fit() * this.zoom());\n protected readonly zoomPct = computed(() => Math.round(this.zoom() * 100));\n\n /** Rectângulo da imagem no palco (onde a área pode estar). */\n private readonly bounds = computed<MxRect>(() => {\n const { w, h } = this.natural();\n const s = this.stageSize();\n const turned = Math.abs(this.rotation()) % 180 === 90;\n const iw = (turned ? h : w) * this.scale();\n const ih = (turned ? w : h) * this.scale();\n const bw = Math.min(iw, s.w);\n const bh = Math.min(ih, s.h);\n return { x: (s.w - bw) / 2, y: (s.h - bh) / 2, width: bw, height: bh };\n });\n\n /** Área em píxeis da imagem (rodada). */\n readonly area = computed<MxCropArea>(() => {\n const b = this.box();\n const s = this.stageSize();\n const k = 1 / this.scale();\n const turned = Math.abs(this.rotation()) % 180 === 90;\n const iw = (turned ? this.natural().h : this.natural().w) * this.scale();\n const ih = (turned ? this.natural().w : this.natural().h) * this.scale();\n const ox = (s.w - iw) / 2;\n const oy = (s.h - ih) / 2;\n return {\n x: Math.round((b.x - ox) * k),\n y: Math.round((b.y - oy) * k),\n width: Math.round(b.width * k),\n height: Math.round(b.height * k),\n rotation: this.rotation(),\n };\n });\n\n protected readonly boxLabel = computed(() => {\n const a = this.area();\n return `${a.width} por ${a.height} píxeis`;\n });\n\n constructor() {\n effect(() => {\n const src = this.src();\n this.ready.set(false);\n if (this.objectUrl) URL.revokeObjectURL(this.objectUrl);\n this.objectUrl = null;\n if (!src) {\n this.url.set(null);\n return;\n }\n if (typeof src === 'string') this.url.set(src);\n else {\n this.objectUrl = URL.createObjectURL(src);\n this.url.set(this.objectUrl);\n }\n });\n // mantém a área dentro da imagem quando o zoom ou a rotação mudam\n effect(() => {\n const b = this.bounds();\n if (!this.ready()) return;\n const current = untracked(() => this.box());\n const next = mxClampRect(current, b);\n if (\n next.x !== current.x ||\n next.y !== current.y ||\n next.width !== current.width ||\n next.height !== current.height\n ) {\n untracked(() => this.box.set(next));\n }\n });\n effect(() => {\n if (this.ready()) this.areaChange.emit(this.area());\n });\n const ro =\n typeof ResizeObserver === 'function' ? new ResizeObserver(() => this.measure()) : null;\n queueMicrotask(() => ro?.observe(this.stage().nativeElement));\n inject(DestroyRef).onDestroy(() => {\n ro?.disconnect();\n if (this.objectUrl) URL.revokeObjectURL(this.objectUrl);\n clearTimeout(this.liveTimer);\n });\n }\n\n private measure(): void {\n const r = this.stage().nativeElement.getBoundingClientRect();\n this.stageSize.set({ w: r.width, h: r.height });\n }\n\n protected onLoad(): void {\n const el = this.img()!.nativeElement;\n this.natural.set({ w: el.naturalWidth, h: el.naturalHeight });\n this.measure();\n this.ready.set(true);\n this.reset();\n }\n\n /** Volta ao zoom 1, sem rotação, área centrada. */\n reset(): void {\n this.zoom.set(1);\n this.rotation.set(0);\n queueMicrotask(() => this.box.set(mxCenteredRect(this.bounds(), this.aspectRatio())));\n }\n setZoom(z: number): void {\n const prev = this.box();\n this.zoom.set(Math.min(Math.max(z, 1), 4));\n this.box.set(mxClampRect(prev, this.bounds()));\n }\n rotate(deg: number): void {\n this.rotation.update((r) => (r + deg + 360) % 360);\n this.box.set(mxCenteredRect(this.bounds(), this.aspectRatio()));\n this.say(`Rodada ${this.rotation()} graus`);\n }\n\n private say(text: string): void {\n clearTimeout(this.liveTimer);\n this.liveTimer = setTimeout(() => this.live.set(text), 250);\n }\n\n protected onKeydown(e: KeyboardEvent): void {\n const step = e.shiftKey ? 10 : 1;\n const d: Record<string, [number, number]> = {\n ArrowLeft: [-step, 0],\n ArrowRight: [step, 0],\n ArrowUp: [0, -step],\n ArrowDown: [0, step],\n };\n const m = d[e.key];\n if (!m) return;\n e.preventDefault();\n const b = this.box();\n if (e.altKey) {\n // Alt: muda o tamanho a partir do canto inferior direito\n this.box.set(\n mxResizeRect(\n b,\n 'se',\n m[0],\n m[1] || (this.aspectRatio() ? m[0] / this.aspectRatio()! : 0),\n this.bounds(),\n this.aspectRatio(),\n this.minSize(),\n ),\n );\n } else {\n this.box.set(mxClampRect({ ...b, x: b.x + m[0], y: b.y + m[1] }, this.bounds()));\n }\n const a = this.area();\n this.say(`${a.width} por ${a.height} píxeis, a ${a.x} da esquerda e ${a.y} do topo`);\n }\n\n private drag(e: PointerEvent, apply: (dx: number, dy: number, start: MxRect) => MxRect): void {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n const start = this.box();\n const sx = e.clientX;\n const sy = e.clientY;\n const target = e.currentTarget as HTMLElement;\n target.setPointerCapture?.(e.pointerId);\n const move = (ev: PointerEvent) => this.box.set(apply(ev.clientX - sx, ev.clientY - sy, start));\n const up = () => {\n target.removeEventListener('pointermove', move);\n target.removeEventListener('pointerup', up);\n };\n target.addEventListener('pointermove', move);\n target.addEventListener('pointerup', up);\n }\n protected startMove(e: PointerEvent): void {\n (e.currentTarget as HTMLElement).focus();\n this.drag(e, (dx, dy, s) => mxClampRect({ ...s, x: s.x + dx, y: s.y + dy }, this.bounds()));\n }\n protected startResize(e: PointerEvent, h: MxCropHandle): void {\n this.drag(e, (dx, dy, s) =>\n mxResizeRect(s, h, dx, dy, this.bounds(), this.aspectRatio(), this.minSize()),\n );\n }\n\n /** Desenha o recorte num canvas na resolução original. */\n toCanvas(): HTMLCanvasElement {\n const img = this.img()?.nativeElement;\n const canvas = document.createElement('canvas');\n if (!img || !this.ready()) return canvas;\n const b = this.box();\n const s = this.stageSize();\n const k = 1 / this.scale();\n canvas.width = Math.max(1, Math.round(b.width * k));\n canvas.height = Math.max(1, Math.round(b.height * k));\n const ctx = canvas.getContext('2d');\n if (!ctx) return canvas;\n if (this.round()) {\n ctx.beginPath();\n ctx.ellipse(\n canvas.width / 2,\n canvas.height / 2,\n canvas.width / 2,\n canvas.height / 2,\n 0,\n 0,\n Math.PI * 2,\n );\n ctx.clip();\n }\n ctx.scale(k, k);\n ctx.translate(-b.x, -b.y);\n ctx.translate(s.w / 2, s.h / 2);\n ctx.rotate((this.rotation() * Math.PI) / 180);\n ctx.scale(this.scale(), this.scale());\n ctx.drawImage(img, -this.natural().w / 2, -this.natural().h / 2);\n return canvas;\n }\n /** Recorte como Blob (PNG por omissão; com `round` é sempre PNG). */\n toBlob(type = 'image/png', quality = 0.92): Promise<Blob | null> {\n const canvas = this.toCanvas();\n return new Promise((resolve) =>\n canvas.toBlob(resolve, this.round() ? 'image/png' : type, quality),\n );\n }\n toDataURL(type = 'image/png', quality = 0.92): string {\n return this.toCanvas().toDataURL(this.round() ? 'image/png' : type, quality);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"muxima-ui-core-image-cropper.mjs","sources":["../../../projects/core/image-cropper/crop-math.ts","../../../projects/core/image-cropper/image-cropper.ts","../../../projects/core/image-cropper/muxima-ui-core-image-cropper.ts"],"sourcesContent":["/** Rectângulo em píxeis. */\nexport interface MxRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Puxadores de redimensionar: cantos e lados. */\nexport type MxCropHandle = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';\n\n/** Mantém o rectângulo dentro dos limites, sem mudar o tamanho (a não ser que não caiba). */\nexport function mxClampRect(r: MxRect, bounds: MxRect): MxRect {\n const width = Math.min(r.width, bounds.width);\n const height = Math.min(r.height, bounds.height);\n return {\n width,\n height,\n x: Math.min(Math.max(r.x, bounds.x), bounds.x + bounds.width - width),\n y: Math.min(Math.max(r.y, bounds.y), bounds.y + bounds.height - height),\n };\n}\n\n/** Maior rectângulo com a proporção dada, centrado nos limites (ocupa `fill` do espaço). */\nexport function mxCenteredRect(bounds: MxRect, ratio: number | null, fill = 0.8): MxRect {\n let width = bounds.width * fill;\n let height = bounds.height * fill;\n if (ratio) {\n if (width / height > ratio) width = height * ratio;\n else height = width / ratio;\n }\n return {\n x: bounds.x + (bounds.width - width) / 2,\n y: bounds.y + (bounds.height - height) / 2,\n width,\n height,\n };\n}\n\n/**\n * Redimensiona a partir de um puxador por (dx, dy), respeitando a proporção, o tamanho\n * mínimo e os limites. O lado oposto ao puxador fica parado.\n */\nexport function mxResizeRect(\n r: MxRect,\n handle: MxCropHandle,\n dx: number,\n dy: number,\n bounds: MxRect,\n ratio: number | null,\n min = 24,\n): MxRect {\n let { x, y, width, height } = r;\n const right = x + width;\n const bottom = y + height;\n if (handle.includes('e'))\n width = Math.min(Math.max(width + dx, min), bounds.x + bounds.width - x);\n if (handle.includes('w')) {\n const nx = Math.min(Math.max(x + dx, bounds.x), right - min);\n width = right - nx;\n x = nx;\n }\n if (handle.includes('s'))\n height = Math.min(Math.max(height + dy, min), bounds.y + bounds.height - y);\n if (handle.includes('n')) {\n const ny = Math.min(Math.max(y + dy, bounds.y), bottom - min);\n height = bottom - ny;\n y = ny;\n }\n if (ratio) {\n // o eixo que o puxador controla manda; nos cantos, o maior movimento\n const horizontal =\n handle === 'e' || handle === 'w' || (handle.length === 2 && Math.abs(dx) >= Math.abs(dy));\n if (horizontal) height = width / ratio;\n else width = height * ratio;\n // não sair dos limites: reduz ambos\n const maxW = handle.includes('w') ? right - bounds.x : bounds.x + bounds.width - x;\n const maxH = handle.includes('n') ? bottom - bounds.y : bounds.y + bounds.height - y;\n const k = Math.min(1, maxW / width, maxH / height);\n width *= k;\n height *= k;\n if (handle.includes('w')) x = right - width;\n if (handle.includes('n')) y = bottom - height;\n if (handle === 'e' || handle === 'w')\n y = Math.min(\n Math.max(r.y + (r.height - height) / 2, bounds.y),\n bounds.y + bounds.height - height,\n );\n if (handle === 'n' || handle === 's')\n x = Math.min(\n Math.max(r.x + (r.width - width) / 2, bounds.x),\n bounds.x + bounds.width - width,\n );\n }\n return { x, y, width, height };\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n model,\n numberAttribute,\n output,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { injectMxMessages } from '@muxima-ui/core/i18n';\nimport { LiveAnnouncer } from '@angular/cdk/a11y';\nimport { mxUniqueId } from '@muxima-ui/core/form-field';\nimport { MxCropHandle, MxRect, mxCenteredRect, mxClampRect, mxResizeRect } from './crop-math';\n\n/** Área recortada em píxeis da imagem original, com a rotação aplicada antes. */\nexport interface MxCropArea extends MxRect {\n rotation: number;\n}\n\nconst HANDLES: MxCropHandle[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\n\n/**\n * Recortar uma imagem antes de a enviar: arrastar a área, redimensionar pelos cantos,\n * zoom e rodar. Com teclado: setas movem a área, Alt + setas mudam o tamanho (Shift para\n * passos maiores); cada mudança é anunciada.\n *\n * ```html\n * <mx-image-cropper #c [src]=\"ficheiro\" [aspectRatio]=\"1\" round />\n * <button mxButton (click)=\"c.toBlob().then(enviar)\">Guardar</button>\n * ```\n *\n * `src` aceita um URL ou um File. `toBlob()` devolve a imagem recortada na resolução original.\n */\n@Component({\n selector: 'mx-image-cropper',\n exportAs: 'mxImageCropper',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-image-cropper',\n '[attr.data-round]': 'round() ? \"\" : null',\n '[attr.aria-label]': 'null',\n },\n template: `\n <div class=\"mx-cropper-stage\" #stage [style.height]=\"height()\">\n @if (url()) {\n <img\n #img\n class=\"mx-cropper-image\"\n [src]=\"url()\"\n [alt]=\"(alt() ?? msg().alt)\"\n draggable=\"false\"\n [style.width.px]=\"natural().w\"\n [style.height.px]=\"natural().h\"\n [style.transform]=\"\n 'translate(-50%, -50%) rotate(' + rotation() + 'deg) scale(' + scale() + ')'\n \"\n (load)=\"onLoad()\"\n />\n }\n @if (ready()) {\n <div\n class=\"mx-cropper-box\"\n role=\"group\"\n tabindex=\"0\"\n [attr.aria-roledescription]=\"msg().area\"\n [attr.aria-label]=\"boxLabel()\"\n [attr.aria-describedby]=\"helpId\"\n [style.left.px]=\"box().x\"\n [style.top.px]=\"box().y\"\n [style.width.px]=\"box().width\"\n [style.height.px]=\"box().height\"\n (pointerdown)=\"startMove($event)\"\n (keydown)=\"onKeydown($event)\"\n >\n <span class=\"mx-cropper-grid\" aria-hidden=\"true\"></span>\n @for (h of handles; track h) {\n <span\n class=\"mx-cropper-handle\"\n [attr.data-handle]=\"h\"\n aria-hidden=\"true\"\n (pointerdown)=\"startResize($event, h)\"\n ></span>\n }\n </div>\n }\n </div>\n <p class=\"mx-visually-hidden\" [id]=\"helpId\">{{ (helpText() ?? msg().help) }}</p>\n @if (controls()) {\n <div class=\"mx-cropper-controls\">\n <label class=\"mx-cropper-zoom\">\n <span>{{ (zoomText() ?? msg().zoom) }}</span>\n <input\n type=\"range\"\n class=\"mx-slider\"\n min=\"1\"\n max=\"4\"\n step=\"0.05\"\n [value]=\"zoom()\"\n [disabled]=\"!ready()\"\n [attr.aria-valuetext]=\"zoomPct() + '%'\"\n (input)=\"setZoom($any($event.target).valueAsNumber)\"\n />\n </label>\n <button\n type=\"button\"\n class=\"mx-cropper-button\"\n [disabled]=\"!ready()\"\n [attr.aria-label]=\"(rotateLeftText() ?? msg().rotateLeft)\"\n (click)=\"rotate(-90)\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3.5 6.5a5 5 0 1 1 .8 5.2M3.5 2.5v4h4\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"mx-cropper-button\"\n [disabled]=\"!ready()\"\n [attr.aria-label]=\"(rotateRightText() ?? msg().rotateRight)\"\n (click)=\"rotate(90)\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12.5 6.5a5 5 0 1 0-.8 5.2M12.5 2.5v4h-4\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"mx-cropper-button mx-cropper-reset\"\n [disabled]=\"!ready()\"\n (click)=\"reset()\"\n >\n {{ (resetText() ?? msg().reset) }}\n </button>\n </div>\n }\n <span class=\"mx-visually-hidden\" aria-live=\"polite\">{{ live() }}</span>\n `,\n})\nexport class MxImageCropper {\n readonly src = input<string | File | Blob | null>(null);\n readonly alt = input<string>();\n private readonly i18n = injectMxMessages();\n protected readonly msg = computed(() => this.i18n().imageCropper);\n /** Largura / altura da área (1 = quadrado, 16/9...). null = livre. */\n readonly aspectRatio = input<number | null>(null);\n /** Máscara redonda (fotografias de perfil). toBlob devolve PNG com cantos transparentes. */\n readonly round = input(false, { transform: booleanAttribute });\n readonly controls = input(true, { transform: booleanAttribute });\n readonly height = input('320px');\n /** Tamanho mínimo da área no ecrã, em px. */\n readonly minSize = input(40, { transform: numberAttribute });\n readonly zoom = model(1);\n readonly rotation = model(0);\n readonly helpText = input<string>();\n readonly zoomText = input<string>();\n readonly rotateLeftText = input<string>();\n readonly rotateRightText = input<string>();\n readonly resetText = input<string>();\n /** Área recortada em píxeis da imagem original. */\n readonly areaChange = output<MxCropArea>();\n\n private readonly stage = viewChild.required<ElementRef<HTMLElement>>('stage');\n private readonly img = viewChild<ElementRef<HTMLImageElement>>('img');\n private readonly announcer = inject(LiveAnnouncer);\n protected readonly helpId = mxUniqueId('mx-cropper-help');\n protected readonly handles = HANDLES;\n\n protected readonly url = signal<string | null>(null);\n protected readonly natural = signal({ w: 0, h: 0 });\n private readonly stageSize = signal({ w: 0, h: 0 });\n protected readonly ready = signal(false);\n readonly box = signal<MxRect>({ x: 0, y: 0, width: 0, height: 0 });\n protected readonly live = signal('');\n private objectUrl: string | null = null;\n private liveTimer?: ReturnType<typeof setTimeout>;\n\n /** Escala que faz a imagem caber no palco, vezes o zoom. */\n private readonly fit = computed(() => {\n const { w, h } = this.natural();\n const s = this.stageSize();\n if (!w || !h || !s.w || !s.h) return 1;\n const turned = Math.abs(this.rotation()) % 180 === 90;\n const iw = turned ? h : w;\n const ih = turned ? w : h;\n return Math.min(s.w / iw, s.h / ih);\n });\n protected readonly scale = computed(() => this.fit() * this.zoom());\n protected readonly zoomPct = computed(() => Math.round(this.zoom() * 100));\n\n /** Rectângulo da imagem no palco (onde a área pode estar). */\n private readonly bounds = computed<MxRect>(() => {\n const { w, h } = this.natural();\n const s = this.stageSize();\n const turned = Math.abs(this.rotation()) % 180 === 90;\n const iw = (turned ? h : w) * this.scale();\n const ih = (turned ? w : h) * this.scale();\n const bw = Math.min(iw, s.w);\n const bh = Math.min(ih, s.h);\n return { x: (s.w - bw) / 2, y: (s.h - bh) / 2, width: bw, height: bh };\n });\n\n /** Área em píxeis da imagem (rodada). */\n readonly area = computed<MxCropArea>(() => {\n const b = this.box();\n const s = this.stageSize();\n const k = 1 / this.scale();\n const turned = Math.abs(this.rotation()) % 180 === 90;\n const iw = (turned ? this.natural().h : this.natural().w) * this.scale();\n const ih = (turned ? this.natural().w : this.natural().h) * this.scale();\n const ox = (s.w - iw) / 2;\n const oy = (s.h - ih) / 2;\n return {\n x: Math.round((b.x - ox) * k),\n y: Math.round((b.y - oy) * k),\n width: Math.round(b.width * k),\n height: Math.round(b.height * k),\n rotation: this.rotation(),\n };\n });\n\n protected readonly boxLabel = computed(() => {\n const a = this.area();\n return this.msg().size(a.width, a.height);\n });\n\n constructor() {\n effect(() => {\n const src = this.src();\n this.ready.set(false);\n if (this.objectUrl) URL.revokeObjectURL(this.objectUrl);\n this.objectUrl = null;\n if (!src) {\n this.url.set(null);\n return;\n }\n if (typeof src === 'string') this.url.set(src);\n else {\n this.objectUrl = URL.createObjectURL(src);\n this.url.set(this.objectUrl);\n }\n });\n // mantém a área dentro da imagem quando o zoom ou a rotação mudam\n effect(() => {\n const b = this.bounds();\n if (!this.ready()) return;\n const current = untracked(() => this.box());\n const next = mxClampRect(current, b);\n if (\n next.x !== current.x ||\n next.y !== current.y ||\n next.width !== current.width ||\n next.height !== current.height\n ) {\n untracked(() => this.box.set(next));\n }\n });\n effect(() => {\n if (this.ready()) this.areaChange.emit(this.area());\n });\n const ro =\n typeof ResizeObserver === 'function' ? new ResizeObserver(() => this.measure()) : null;\n queueMicrotask(() => ro?.observe(this.stage().nativeElement));\n inject(DestroyRef).onDestroy(() => {\n ro?.disconnect();\n if (this.objectUrl) URL.revokeObjectURL(this.objectUrl);\n clearTimeout(this.liveTimer);\n });\n }\n\n private measure(): void {\n const r = this.stage().nativeElement.getBoundingClientRect();\n this.stageSize.set({ w: r.width, h: r.height });\n }\n\n protected onLoad(): void {\n const el = this.img()!.nativeElement;\n this.natural.set({ w: el.naturalWidth, h: el.naturalHeight });\n this.measure();\n this.ready.set(true);\n this.reset();\n }\n\n /** Volta ao zoom 1, sem rotação, área centrada. */\n reset(): void {\n this.zoom.set(1);\n this.rotation.set(0);\n queueMicrotask(() => this.box.set(mxCenteredRect(this.bounds(), this.aspectRatio())));\n }\n setZoom(z: number): void {\n const prev = this.box();\n this.zoom.set(Math.min(Math.max(z, 1), 4));\n this.box.set(mxClampRect(prev, this.bounds()));\n }\n rotate(deg: number): void {\n this.rotation.update((r) => (r + deg + 360) % 360);\n this.box.set(mxCenteredRect(this.bounds(), this.aspectRatio()));\n this.say(this.msg().rotated(this.rotation()));\n }\n\n private say(text: string): void {\n clearTimeout(this.liveTimer);\n this.liveTimer = setTimeout(() => this.live.set(text), 250);\n }\n\n protected onKeydown(e: KeyboardEvent): void {\n const step = e.shiftKey ? 10 : 1;\n const d: Record<string, [number, number]> = {\n ArrowLeft: [-step, 0],\n ArrowRight: [step, 0],\n ArrowUp: [0, -step],\n ArrowDown: [0, step],\n };\n const m = d[e.key];\n if (!m) return;\n e.preventDefault();\n const b = this.box();\n if (e.altKey) {\n // Alt: muda o tamanho a partir do canto inferior direito\n this.box.set(\n mxResizeRect(\n b,\n 'se',\n m[0],\n m[1] || (this.aspectRatio() ? m[0] / this.aspectRatio()! : 0),\n this.bounds(),\n this.aspectRatio(),\n this.minSize(),\n ),\n );\n } else {\n this.box.set(mxClampRect({ ...b, x: b.x + m[0], y: b.y + m[1] }, this.bounds()));\n }\n const a = this.area();\n this.say(this.msg().position(a.width, a.height, a.x, a.y));\n }\n\n private drag(e: PointerEvent, apply: (dx: number, dy: number, start: MxRect) => MxRect): void {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n const start = this.box();\n const sx = e.clientX;\n const sy = e.clientY;\n const target = e.currentTarget as HTMLElement;\n target.setPointerCapture?.(e.pointerId);\n const move = (ev: PointerEvent) => this.box.set(apply(ev.clientX - sx, ev.clientY - sy, start));\n const up = () => {\n target.removeEventListener('pointermove', move);\n target.removeEventListener('pointerup', up);\n };\n target.addEventListener('pointermove', move);\n target.addEventListener('pointerup', up);\n }\n protected startMove(e: PointerEvent): void {\n (e.currentTarget as HTMLElement).focus();\n this.drag(e, (dx, dy, s) => mxClampRect({ ...s, x: s.x + dx, y: s.y + dy }, this.bounds()));\n }\n protected startResize(e: PointerEvent, h: MxCropHandle): void {\n this.drag(e, (dx, dy, s) =>\n mxResizeRect(s, h, dx, dy, this.bounds(), this.aspectRatio(), this.minSize()),\n );\n }\n\n /** Desenha o recorte num canvas na resolução original. */\n toCanvas(): HTMLCanvasElement {\n const img = this.img()?.nativeElement;\n const canvas = document.createElement('canvas');\n if (!img || !this.ready()) return canvas;\n const b = this.box();\n const s = this.stageSize();\n const k = 1 / this.scale();\n canvas.width = Math.max(1, Math.round(b.width * k));\n canvas.height = Math.max(1, Math.round(b.height * k));\n const ctx = canvas.getContext('2d');\n if (!ctx) return canvas;\n if (this.round()) {\n ctx.beginPath();\n ctx.ellipse(\n canvas.width / 2,\n canvas.height / 2,\n canvas.width / 2,\n canvas.height / 2,\n 0,\n 0,\n Math.PI * 2,\n );\n ctx.clip();\n }\n ctx.scale(k, k);\n ctx.translate(-b.x, -b.y);\n ctx.translate(s.w / 2, s.h / 2);\n ctx.rotate((this.rotation() * Math.PI) / 180);\n ctx.scale(this.scale(), this.scale());\n ctx.drawImage(img, -this.natural().w / 2, -this.natural().h / 2);\n return canvas;\n }\n /** Recorte como Blob (PNG por omissão; com `round` é sempre PNG). */\n toBlob(type = 'image/png', quality = 0.92): Promise<Blob | null> {\n const canvas = this.toCanvas();\n return new Promise((resolve) =>\n canvas.toBlob(resolve, this.round() ? 'image/png' : type, quality),\n );\n }\n toDataURL(type = 'image/png', quality = 0.92): string {\n return this.toCanvas().toDataURL(this.round() ? 'image/png' : type, quality);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, TemplateRef, Directive, model, input, output, contentChild, ElementRef, Injector, signal, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { inject, TemplateRef, Directive, model, input, computed, output, contentChild, ElementRef, Injector, signal, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { injectMxMessages } from '@muxima-ui/core/i18n';
3
4
  import { NgTemplateOutlet } from '@angular/common';
4
5
  import { LiveAnnouncer } from '@angular/cdk/a11y';
5
6
  import { CdkDropListGroup, CdkDropList, CdkDrag, CdkDragPlaceholder } from '@angular/cdk/drag-drop';
@@ -42,10 +43,12 @@ class MxKanban {
42
43
  itemKey = input('id', ...(ngDevMode ? [{ debugName: "itemKey" }] : /* istanbul ignore next */ []));
43
44
  /** Nome do cartão nos anúncios. Por omissão o campo `title` ou `titulo`. */
44
45
  itemLabel = input((i) => String(i?.title ?? i?.titulo ?? i?.id ?? ''), ...(ngDevMode ? [{ debugName: "itemLabel" }] : /* istanbul ignore next */ []));
45
- ariaLabel = input('Quadro', { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
46
+ ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
47
+ i18n = injectMxMessages();
48
+ msg = computed(() => this.i18n().kanban, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
46
49
  headingLevel = input(3, ...(ngDevMode ? [{ debugName: "headingLevel" }] : /* istanbul ignore next */ []));
47
- emptyText = input('Sem cartões', ...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
48
- helpText = input('Espaço para agarrar. Setas para mover. Espaço para largar, Esc para cancelar.', ...(ngDevMode ? [{ debugName: "helpText" }] : /* istanbul ignore next */ []));
50
+ emptyText = input(...(ngDevMode ? [undefined, { debugName: "emptyText" }] : /* istanbul ignore next */ []));
51
+ helpText = input(...(ngDevMode ? [undefined, { debugName: "helpText" }] : /* istanbul ignore next */ []));
49
52
  moved = output();
50
53
  cardTpl = contentChild(MxKanbanCard, ...(ngDevMode ? [{ debugName: "cardTpl" }] : /* istanbul ignore next */ []));
51
54
  footerTpl = contentChild(MxKanbanColumnFooter, ...(ngDevMode ? [{ debugName: "footerTpl" }] : /* istanbul ignore next */ []));
@@ -107,7 +110,7 @@ class MxKanban {
107
110
  }
108
111
  where(col, index) {
109
112
  const c = this.columns()[col];
110
- return `${c.title}, posição ${index + 1} de ${c.items.length}`;
113
+ return this.msg().position(c.title, index + 1, c.items.length);
111
114
  }
112
115
  onKeydown(event, ci, ii) {
113
116
  if (event.target !== event.currentTarget)
@@ -119,7 +122,7 @@ class MxKanban {
119
122
  if (key === ' ' || key === 'Enter') {
120
123
  event.preventDefault();
121
124
  this.grabbed.set({ col: ci, index: ii, fromCol: ci, fromIndex: ii, snapshot: cols });
122
- this.announcer.announce(`${this.labelOf(cols[ci].items[ii])} agarrado. ${this.where(ci, ii)}.`, 'assertive');
125
+ this.announcer.announce(this.msg().pickedUp(this.labelOf(cols[ci].items[ii]), this.where(ci, ii)), 'assertive');
123
126
  return;
124
127
  }
125
128
  // navegar entre cartões
@@ -154,7 +157,7 @@ class MxKanban {
154
157
  this.grabbed.set(null);
155
158
  if (g.col !== g.fromCol || g.index !== g.fromIndex)
156
159
  this.emitMove(item, g.fromCol, g.fromIndex, g.col, g.index);
157
- this.announcer.announce(`${this.labelOf(item)} largado. ${this.where(g.col, g.index)}.`, 'assertive');
160
+ this.announcer.announce(this.msg().dropped(this.labelOf(item), this.where(g.col, g.index)), 'assertive');
158
161
  this.focusCard(g.col, g.index);
159
162
  return;
160
163
  }
@@ -162,7 +165,7 @@ class MxKanban {
162
165
  event.preventDefault();
163
166
  this.columns.set(g.snapshot);
164
167
  this.grabbed.set(null);
165
- this.announcer.announce(`Movimento cancelado. ${this.labelOf(item)} voltou a ${this.where(g.fromCol, g.fromIndex)}.`, 'assertive');
168
+ this.announcer.announce(this.msg().cancelled(this.labelOf(item), this.where(g.fromCol, g.fromIndex)), 'assertive');
166
169
  this.focusCard(g.fromCol, g.fromIndex);
167
170
  return;
168
171
  }
@@ -177,7 +180,7 @@ class MxKanban {
177
180
  const target = cols[c];
178
181
  if (target.limit && target.items.length >= target.limit) {
179
182
  event.preventDefault();
180
- this.announcer.announce(`${target.title} está cheia, máximo ${target.limit}.`, 'assertive');
183
+ this.announcer.announce(this.msg().full(target.title, target.limit), 'assertive');
181
184
  return;
182
185
  }
183
186
  to = [c, Math.min(g.index, target.items.length)];
@@ -208,8 +211,8 @@ class MxKanban {
208
211
  }
209
212
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxKanban, deps: [], target: i0.ɵɵFactoryTarget.Component });
210
213
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: MxKanban, isStandalone: true, selector: "mx-kanban", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, itemKey: { classPropertyName: "itemKey", publicName: "itemKey", isSignal: true, isRequired: false, transformFunction: null }, itemLabel: { classPropertyName: "itemLabel", publicName: "itemLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, headingLevel: { classPropertyName: "headingLevel", publicName: "headingLevel", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, helpText: { classPropertyName: "helpText", publicName: "helpText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columns: "columnsChange", moved: "moved" }, host: { properties: { "attr.aria-label": "null" }, classAttribute: "mx-kanban" }, queries: [{ propertyName: "cardTpl", first: true, predicate: MxKanbanCard, descendants: true, isSignal: true }, { propertyName: "footerTpl", first: true, predicate: MxKanbanColumnFooter, descendants: true, isSignal: true }], exportAs: ["mxKanban"], ngImport: i0, template: `
211
- <p class="mx-visually-hidden" [id]="helpId">{{ helpText() }}</p>
212
- <div class="mx-kanban-board" cdkDropListGroup role="group" [attr.aria-label]="ariaLabel()">
214
+ <p class="mx-visually-hidden" [id]="helpId">{{ (helpText() ?? msg().help) }}</p>
215
+ <div class="mx-kanban-board" cdkDropListGroup role="group" [attr.aria-label]="(ariaLabel() ?? msg().label)">
213
216
  @for (col of columns(); track col.id; let ci = $index) {
214
217
  <div
215
218
  class="mx-kanban-column"
@@ -229,7 +232,7 @@ class MxKanban {
229
232
  <span class="mx-kanban-count">
230
233
  {{ col.items.length }}{{ col.limit ? ' / ' + col.limit : '' }}
231
234
  <span class="mx-visually-hidden">{{
232
- (col.items.length === 1 ? 'cartão' : 'cartões') + (col.limit ? ', máximo ' + col.limit : '')
235
+ msg().cards(col.items.length, col.limit ?? null)
233
236
  }}</span>
234
237
  </span>
235
238
  </div>
@@ -251,7 +254,7 @@ class MxKanban {
251
254
  [attr.data-kanban]="ci + ':' + ii"
252
255
  [attr.data-grabbed]="isGrabbed(ci, ii) ? '' : null"
253
256
  [attr.aria-describedby]="helpId"
254
- [attr.aria-label]="isGrabbed(ci, ii) ? labelOf(item) + ', agarrado' : null"
257
+ [attr.aria-label]="isGrabbed(ci, ii) ? msg().grabbed(labelOf(item)) : null"
255
258
  (keydown)="onKeydown($event, ci, ii)"
256
259
  (blur)="onBlur(ci, ii)"
257
260
  >
@@ -265,7 +268,7 @@ class MxKanban {
265
268
  <div class="mx-kanban-placeholder" *cdkDragPlaceholder></div>
266
269
  </li>
267
270
  } @empty {
268
- <li class="mx-kanban-empty">{{ emptyText() }}</li>
271
+ <li class="mx-kanban-empty">{{ (emptyText() ?? msg().empty) }}</li>
269
272
  }
270
273
  </ul>
271
274
  @if (footerTpl(); as f) {
@@ -288,8 +291,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
288
291
  encapsulation: ViewEncapsulation.None,
289
292
  host: { class: 'mx-kanban', '[attr.aria-label]': 'null' },
290
293
  template: `
291
- <p class="mx-visually-hidden" [id]="helpId">{{ helpText() }}</p>
292
- <div class="mx-kanban-board" cdkDropListGroup role="group" [attr.aria-label]="ariaLabel()">
294
+ <p class="mx-visually-hidden" [id]="helpId">{{ (helpText() ?? msg().help) }}</p>
295
+ <div class="mx-kanban-board" cdkDropListGroup role="group" [attr.aria-label]="(ariaLabel() ?? msg().label)">
293
296
  @for (col of columns(); track col.id; let ci = $index) {
294
297
  <div
295
298
  class="mx-kanban-column"
@@ -309,7 +312,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
309
312
  <span class="mx-kanban-count">
310
313
  {{ col.items.length }}{{ col.limit ? ' / ' + col.limit : '' }}
311
314
  <span class="mx-visually-hidden">{{
312
- (col.items.length === 1 ? 'cartão' : 'cartões') + (col.limit ? ', máximo ' + col.limit : '')
315
+ msg().cards(col.items.length, col.limit ?? null)
313
316
  }}</span>
314
317
  </span>
315
318
  </div>
@@ -331,7 +334,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
331
334
  [attr.data-kanban]="ci + ':' + ii"
332
335
  [attr.data-grabbed]="isGrabbed(ci, ii) ? '' : null"
333
336
  [attr.aria-describedby]="helpId"
334
- [attr.aria-label]="isGrabbed(ci, ii) ? labelOf(item) + ', agarrado' : null"
337
+ [attr.aria-label]="isGrabbed(ci, ii) ? msg().grabbed(labelOf(item)) : null"
335
338
  (keydown)="onKeydown($event, ci, ii)"
336
339
  (blur)="onBlur(ci, ii)"
337
340
  >
@@ -345,7 +348,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
345
348
  <div class="mx-kanban-placeholder" *cdkDragPlaceholder></div>
346
349
  </li>
347
350
  } @empty {
348
- <li class="mx-kanban-empty">{{ emptyText() }}</li>
351
+ <li class="mx-kanban-empty">{{ (emptyText() ?? msg().empty) }}</li>
349
352
  }
350
353
  </ul>
351
354
  @if (footerTpl(); as f) {