@muxima-ui/core 1.2.0 → 1.4.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.
@@ -0,0 +1,105 @@
1
+ import * as _angular_core from '@angular/core';
2
+
3
+ /** Rectângulo em píxeis. */
4
+ interface MxRect {
5
+ x: number;
6
+ y: number;
7
+ width: number;
8
+ height: number;
9
+ }
10
+ /** Puxadores de redimensionar: cantos e lados. */
11
+ type MxCropHandle = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';
12
+ /** Mantém o rectângulo dentro dos limites, sem mudar o tamanho (a não ser que não caiba). */
13
+ declare function mxClampRect(r: MxRect, bounds: MxRect): MxRect;
14
+ /** Maior rectângulo com a proporção dada, centrado nos limites (ocupa `fill` do espaço). */
15
+ declare function mxCenteredRect(bounds: MxRect, ratio: number | null, fill?: number): MxRect;
16
+ /**
17
+ * Redimensiona a partir de um puxador por (dx, dy), respeitando a proporção, o tamanho
18
+ * mínimo e os limites. O lado oposto ao puxador fica parado.
19
+ */
20
+ declare function mxResizeRect(r: MxRect, handle: MxCropHandle, dx: number, dy: number, bounds: MxRect, ratio: number | null, min?: number): MxRect;
21
+
22
+ /** Área recortada em píxeis da imagem original, com a rotação aplicada antes. */
23
+ interface MxCropArea extends MxRect {
24
+ rotation: number;
25
+ }
26
+ /**
27
+ * Recortar uma imagem antes de a enviar: arrastar a área, redimensionar pelos cantos,
28
+ * zoom e rodar. Com teclado: setas movem a área, Alt + setas mudam o tamanho (Shift para
29
+ * passos maiores); cada mudança é anunciada.
30
+ *
31
+ * ```html
32
+ * <mx-image-cropper #c [src]="ficheiro" [aspectRatio]="1" round />
33
+ * <button mxButton (click)="c.toBlob().then(enviar)">Guardar</button>
34
+ * ```
35
+ *
36
+ * `src` aceita um URL ou um File. `toBlob()` devolve a imagem recortada na resolução original.
37
+ */
38
+ declare class MxImageCropper {
39
+ readonly src: _angular_core.InputSignal<string | File | Blob | null>;
40
+ readonly alt: _angular_core.InputSignal<string>;
41
+ /** Largura / altura da área (1 = quadrado, 16/9...). null = livre. */
42
+ readonly aspectRatio: _angular_core.InputSignal<number | null>;
43
+ /** Máscara redonda (fotografias de perfil). toBlob devolve PNG com cantos transparentes. */
44
+ readonly round: _angular_core.InputSignalWithTransform<boolean, unknown>;
45
+ readonly controls: _angular_core.InputSignalWithTransform<boolean, unknown>;
46
+ readonly height: _angular_core.InputSignal<string>;
47
+ /** Tamanho mínimo da área no ecrã, em px. */
48
+ readonly minSize: _angular_core.InputSignalWithTransform<number, unknown>;
49
+ readonly zoom: _angular_core.ModelSignal<number>;
50
+ readonly rotation: _angular_core.ModelSignal<number>;
51
+ readonly helpText: _angular_core.InputSignal<string>;
52
+ readonly zoomText: _angular_core.InputSignal<string>;
53
+ readonly rotateLeftText: _angular_core.InputSignal<string>;
54
+ readonly rotateRightText: _angular_core.InputSignal<string>;
55
+ readonly resetText: _angular_core.InputSignal<string>;
56
+ /** Área recortada em píxeis da imagem original. */
57
+ readonly areaChange: _angular_core.OutputEmitterRef<MxCropArea>;
58
+ private readonly stage;
59
+ private readonly img;
60
+ private readonly announcer;
61
+ protected readonly helpId: string;
62
+ protected readonly handles: MxCropHandle[];
63
+ protected readonly url: _angular_core.WritableSignal<string | null>;
64
+ protected readonly natural: _angular_core.WritableSignal<{
65
+ w: number;
66
+ h: number;
67
+ }>;
68
+ private readonly stageSize;
69
+ protected readonly ready: _angular_core.WritableSignal<boolean>;
70
+ readonly box: _angular_core.WritableSignal<MxRect>;
71
+ protected readonly live: _angular_core.WritableSignal<string>;
72
+ private objectUrl;
73
+ private liveTimer?;
74
+ /** Escala que faz a imagem caber no palco, vezes o zoom. */
75
+ private readonly fit;
76
+ protected readonly scale: _angular_core.Signal<number>;
77
+ protected readonly zoomPct: _angular_core.Signal<number>;
78
+ /** Rectângulo da imagem no palco (onde a área pode estar). */
79
+ private readonly bounds;
80
+ /** Área em píxeis da imagem (rodada). */
81
+ readonly area: _angular_core.Signal<MxCropArea>;
82
+ protected readonly boxLabel: _angular_core.Signal<string>;
83
+ constructor();
84
+ private measure;
85
+ protected onLoad(): void;
86
+ /** Volta ao zoom 1, sem rotação, área centrada. */
87
+ reset(): void;
88
+ setZoom(z: number): void;
89
+ rotate(deg: number): void;
90
+ private say;
91
+ protected onKeydown(e: KeyboardEvent): void;
92
+ private drag;
93
+ protected startMove(e: PointerEvent): void;
94
+ protected startResize(e: PointerEvent, h: MxCropHandle): void;
95
+ /** Desenha o recorte num canvas na resolução original. */
96
+ toCanvas(): HTMLCanvasElement;
97
+ /** Recorte como Blob (PNG por omissão; com `round` é sempre PNG). */
98
+ toBlob(type?: string, quality?: number): Promise<Blob | null>;
99
+ toDataURL(type?: string, quality?: number): string;
100
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MxImageCropper, never>;
101
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MxImageCropper, "mx-image-cropper", ["mxImageCropper"], { "src": { "alias": "src"; "required": false; "isSignal": true; }; "alt": { "alias": "alt"; "required": false; "isSignal": true; }; "aspectRatio": { "alias": "aspectRatio"; "required": false; "isSignal": true; }; "round": { "alias": "round"; "required": false; "isSignal": true; }; "controls": { "alias": "controls"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "minSize": { "alias": "minSize"; "required": false; "isSignal": true; }; "zoom": { "alias": "zoom"; "required": false; "isSignal": true; }; "rotation": { "alias": "rotation"; "required": false; "isSignal": true; }; "helpText": { "alias": "helpText"; "required": false; "isSignal": true; }; "zoomText": { "alias": "zoomText"; "required": false; "isSignal": true; }; "rotateLeftText": { "alias": "rotateLeftText"; "required": false; "isSignal": true; }; "rotateRightText": { "alias": "rotateRightText"; "required": false; "isSignal": true; }; "resetText": { "alias": "resetText"; "required": false; "isSignal": true; }; }, { "zoom": "zoomChange"; "rotation": "rotationChange"; "areaChange": "areaChange"; }, never, never, true, never>;
102
+ }
103
+
104
+ export { MxImageCropper, mxCenteredRect, mxClampRect, mxResizeRect };
105
+ export type { MxCropArea, MxCropHandle, MxRect };
@@ -0,0 +1,83 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { TemplateRef } from '@angular/core';
3
+ import { CdkDrag, CdkDropList, CdkDragDrop } from '@angular/cdk/drag-drop';
4
+
5
+ interface MxKanbanColumn<T = any> {
6
+ id: string;
7
+ title: string;
8
+ items: T[];
9
+ /** Máximo de cartões na coluna (WIP). Acima disso não se larga lá. */
10
+ limit?: number;
11
+ }
12
+ interface MxKanbanMove<T = any> {
13
+ item: T;
14
+ from: string;
15
+ to: string;
16
+ fromIndex: number;
17
+ toIndex: number;
18
+ }
19
+ /** Conteúdo do cartão: `<ng-template mxKanbanCard let-item let-column="column">`. */
20
+ declare class MxKanbanCard {
21
+ readonly template: TemplateRef<any>;
22
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MxKanbanCard, never>;
23
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MxKanbanCard, "ng-template[mxKanbanCard]", never, {}, {}, never, never, true, never>;
24
+ }
25
+ /** Rodapé de cada coluna (ex.: botão "Adicionar"): `<ng-template mxKanbanColumnFooter let-column>`. */
26
+ declare class MxKanbanColumnFooter {
27
+ readonly template: TemplateRef<any>;
28
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MxKanbanColumnFooter, never>;
29
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MxKanbanColumnFooter, "ng-template[mxKanbanColumnFooter]", never, {}, {}, never, never, true, never>;
30
+ }
31
+ /**
32
+ * Quadro Kanban: cartões em colunas, com arrastar e largar (rato e toque) e mover com
33
+ * o teclado. Num cartão: Espaço agarra, setas movem (cima e baixo na coluna, esquerda e
34
+ * direita entre colunas), Espaço larga e Esc cancela. Cada passo é anunciado.
35
+ *
36
+ * ```html
37
+ * <mx-kanban [(columns)]="quadro" [itemLabel]="titulo" (moved)="guardar($event)">
38
+ * <ng-template mxKanbanCard let-tarefa>{{ tarefa.titulo }}</ng-template>
39
+ * </mx-kanban>
40
+ * ```
41
+ */
42
+ declare class MxKanban<T = any> {
43
+ readonly columns: _angular_core.ModelSignal<MxKanbanColumn<T>[]>;
44
+ /** Chave única de cada cartão: nome do campo ou função. */
45
+ readonly itemKey: _angular_core.InputSignal<string | ((item: T) => unknown)>;
46
+ /** Nome do cartão nos anúncios. Por omissão o campo `title` ou `titulo`. */
47
+ readonly itemLabel: _angular_core.InputSignal<(item: T) => string>;
48
+ readonly ariaLabel: _angular_core.InputSignal<string>;
49
+ readonly headingLevel: _angular_core.InputSignal<number>;
50
+ readonly emptyText: _angular_core.InputSignal<string>;
51
+ readonly helpText: _angular_core.InputSignal<string>;
52
+ readonly moved: _angular_core.OutputEmitterRef<MxKanbanMove<T>>;
53
+ protected readonly cardTpl: _angular_core.Signal<MxKanbanCard | undefined>;
54
+ protected readonly footerTpl: _angular_core.Signal<MxKanbanColumnFooter | undefined>;
55
+ private readonly announcer;
56
+ private readonly host;
57
+ private readonly injector;
58
+ private readonly uid;
59
+ protected readonly helpId: string;
60
+ /** Cartão agarrado com o teclado: posição actual e de onde saiu. */
61
+ private readonly grabbed;
62
+ protected titleId(i: number): string;
63
+ protected listId(i: number): string;
64
+ keyOf(item: T): unknown;
65
+ protected labelOf(item: T): string;
66
+ protected isGrabbed(c: number, i: number): boolean;
67
+ protected isFull(col: MxKanbanColumn<T>): boolean;
68
+ protected canEnter(ci: number): (drag: CdkDrag, drop: CdkDropList) => boolean;
69
+ /** Move um cartão e devolve as colunas novas (sem mudar as antigas). */
70
+ private move;
71
+ protected onDrop(e: CdkDragDrop<number>): void;
72
+ private emitMove;
73
+ private focusCard;
74
+ private where;
75
+ protected onKeydown(event: KeyboardEvent, ci: number, ii: number): void;
76
+ protected onBlur(ci: number, ii: number): void;
77
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MxKanban<any>, never>;
78
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MxKanban<any>, "mx-kanban", ["mxKanban"], { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "itemKey": { "alias": "itemKey"; "required": false; "isSignal": true; }; "itemLabel": { "alias": "itemLabel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "helpText": { "alias": "helpText"; "required": false; "isSignal": true; }; }, { "columns": "columnsChange"; "moved": "moved"; }, ["cardTpl", "footerTpl"], never, true, never>;
79
+ }
80
+ declare const MX_KANBAN: readonly [typeof MxKanban, typeof MxKanbanCard, typeof MxKanbanColumnFooter];
81
+
82
+ export { MX_KANBAN, MxKanban, MxKanbanCard, MxKanbanColumnFooter };
83
+ export type { MxKanbanColumn, MxKanbanMove };
@@ -0,0 +1,163 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { ElementRef, TemplateRef } from '@angular/core';
3
+
4
+ /** Onde fica o cartão em relação ao elemento destacado. */
5
+ type MxTourPlacement = 'auto' | 'top' | 'bottom' | 'start' | 'end';
6
+ /** Nome de um `mxTourAnchor`, um elemento, ou um ElementRef. */
7
+ type MxTourTarget = string | Element | ElementRef<Element>;
8
+ /** Contexto do modelo de conteúdo de um passo. */
9
+ interface MxTourStepContext {
10
+ $implicit: MxTourStep;
11
+ index: number;
12
+ tour: MxTourRef;
13
+ }
14
+ /** Um passo da visita guiada. */
15
+ interface MxTourStep {
16
+ /** Elemento a destacar. Sem alvo (ou se não existir), o cartão aparece ao centro. */
17
+ target?: MxTourTarget | null;
18
+ title: string;
19
+ /** Texto do passo. */
20
+ content?: string;
21
+ /** Conteúdo rico, em vez de `content`. */
22
+ template?: TemplateRef<MxTourStepContext>;
23
+ placement?: MxTourPlacement;
24
+ /** Espaço à volta do elemento destacado, em px. Por omissão 6. */
25
+ padding?: number;
26
+ /** Corre antes de mostrar o passo (ex.: abrir um separador). Pode devolver uma Promise. */
27
+ beforeShow?: () => void | Promise<unknown>;
28
+ }
29
+ interface MxTourLabels {
30
+ next: string;
31
+ previous: string;
32
+ done: string;
33
+ skip: string;
34
+ close: string;
35
+ /** Texto do progresso, por exemplo "Passo 2 de 5". */
36
+ progress: (current: number, total: number) => string;
37
+ }
38
+ declare const MX_TOUR_LABELS: MxTourLabels;
39
+ interface MxTourOptions {
40
+ /** Passo inicial (base 0). */
41
+ startAt?: number;
42
+ labels?: Partial<MxTourLabels>;
43
+ /** false: sem Saltar, sem botão de fechar e sem Escape (a visita tem de ser feita até ao fim). */
44
+ dismissible?: boolean;
45
+ /** Mostra os pontos de progresso. Por omissão true. */
46
+ showDots?: boolean;
47
+ }
48
+ /** Como terminou a visita. */
49
+ interface MxTourResult {
50
+ /** true se chegou ao fim com Concluir. */
51
+ completed: boolean;
52
+ /** Último passo mostrado (base 0). */
53
+ index: number;
54
+ }
55
+ /** Referência a uma visita em curso. */
56
+ declare class MxTourRef {
57
+ readonly steps: readonly MxTourStep[];
58
+ private readonly onClose;
59
+ /** Passo actual (base 0). */
60
+ readonly index: _angular_core.WritableSignal<number>;
61
+ /** Resolve quando a visita fecha. */
62
+ readonly afterClosed: Promise<MxTourResult>;
63
+ readonly labels: MxTourLabels;
64
+ readonly dismissible: boolean;
65
+ readonly showDots: boolean;
66
+ private resolve;
67
+ private done;
68
+ constructor(steps: readonly MxTourStep[], options: MxTourOptions, onClose: (r: MxTourResult) => void);
69
+ get isOpen(): boolean;
70
+ get isLast(): boolean;
71
+ next(): void;
72
+ previous(): void;
73
+ goTo(index: number): void;
74
+ /** Fecha a visita; `completed` diz se foi até ao fim. */
75
+ close(completed?: boolean): void;
76
+ }
77
+ interface Box {
78
+ top: number;
79
+ left: number;
80
+ width: number;
81
+ height: number;
82
+ }
83
+ /** Painel da visita: o destaque, o fundo escurecido e o cartão do passo. Uso interno. */
84
+ declare class MxTourPanel {
85
+ protected readonly ref: MxTourRef;
86
+ private readonly tour;
87
+ protected readonly titleId: string;
88
+ protected readonly bodyId: string;
89
+ protected readonly progressId: string;
90
+ private readonly card;
91
+ private readonly zone;
92
+ private readonly cdr;
93
+ /** Passo que está desenhado (muda depois de beforeShow). */
94
+ protected readonly step: _angular_core.WritableSignal<MxTourStep | null>;
95
+ private readonly target;
96
+ protected readonly spot: _angular_core.WritableSignal<Box | null>;
97
+ protected readonly pos: _angular_core.WritableSignal<{
98
+ top: number;
99
+ left: number;
100
+ }>;
101
+ protected readonly placement: _angular_core.WritableSignal<"top" | "bottom" | "start" | "end">;
102
+ protected readonly ready: _angular_core.WritableSignal<boolean>;
103
+ private frame;
104
+ private resizeObserver?;
105
+ private showToken;
106
+ constructor();
107
+ private show;
108
+ private schedule;
109
+ private update;
110
+ protected onKeydown(event: KeyboardEvent): void;
111
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MxTourPanel, never>;
112
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MxTourPanel, "mx-tour-panel", never, {}, {}, never, never, true, never>;
113
+ }
114
+ /**
115
+ * Visita guiada: destaca elementos da página, um passo de cada vez, com um cartão
116
+ * que explica cada um. O cartão é um diálogo modal: o foco fica nele, Escape fecha
117
+ * e, no fim, o foco volta para onde estava.
118
+ *
119
+ * ```html
120
+ * <input mxInput mxTourAnchor="pesquisa" aria-label="Pesquisar" />
121
+ * <button mxButton mxTourAnchor="nova">Nova factura</button>
122
+ * ```
123
+ *
124
+ * ```ts
125
+ * private readonly tour = inject(MxTour);
126
+ * mostrar() {
127
+ * this.tour.start([
128
+ * { title: 'Bem-vindo', content: 'Mostramos o essencial em 2 passos.' },
129
+ * { target: 'pesquisa', title: 'Pesquisa', content: 'Procura clientes e facturas.' },
130
+ * { target: 'nova', title: 'Nova factura', content: 'Começa aqui.' },
131
+ * ]).afterClosed.then((r) => r.completed && guardarQueViu());
132
+ * }
133
+ * ```
134
+ */
135
+ declare class MxTour {
136
+ private readonly injector;
137
+ private readonly anchors;
138
+ private overlayRef?;
139
+ /** A visita em curso, ou null. */
140
+ readonly active: _angular_core.WritableSignal<MxTourRef | null>;
141
+ readonly isOpen: _angular_core.Signal<boolean>;
142
+ /** Começa uma visita. Se já houver uma aberta, fecha-a primeiro. */
143
+ start(steps: readonly MxTourStep[], options?: MxTourOptions): MxTourRef;
144
+ /** Regista um elemento com um nome (usado por `mxTourAnchor`). */
145
+ register(name: string, element: Element): void;
146
+ unregister(name: string, element: Element): void;
147
+ /** Encontra o elemento de um alvo: nome de âncora, selector CSS, elemento ou ElementRef. */
148
+ resolve(target: MxTourTarget | null | undefined): Element | null;
149
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MxTour, never>;
150
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<MxTour>;
151
+ }
152
+ /** Dá um nome a um elemento para ser alvo de um passo: `mxTourAnchor="pesquisa"`. */
153
+ declare class MxTourAnchor {
154
+ readonly name: _angular_core.InputSignal<string>;
155
+ private readonly tour;
156
+ private readonly el;
157
+ constructor();
158
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MxTourAnchor, never>;
159
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MxTourAnchor, "[mxTourAnchor]", ["mxTourAnchor"], { "name": { "alias": "mxTourAnchor"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
160
+ }
161
+
162
+ export { MX_TOUR_LABELS, MxTour, MxTourAnchor, MxTourPanel, MxTourRef };
163
+ export type { MxTourLabels, MxTourOptions, MxTourPlacement, MxTourResult, MxTourStep, MxTourStepContext, MxTourTarget };
@@ -1,3 +1,3 @@
1
- declare const MUXIMA_VERSION = "1.2.0";
1
+ declare const MUXIMA_VERSION = "1.4.0";
2
2
 
3
3
  export { MUXIMA_VERSION };