@praxisui/settings-panel 0.0.1

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.
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ This package is licensed under the Apache License, Version 2.0.
2
+
3
+ For the full license text, see the repository root LICENSE file:
4
+ ../../LICENSE
5
+
6
+ Apache License 2.0: https://www.apache.org/licenses/LICENSE-2.0
7
+
package/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # @praxisui/settings-panel
2
+
3
+ Painel de configurações baseado em drawer para hospedar editores de configuração com UX consistente (Apply, Save & Close, Reset, Cancel).
4
+
5
+ ## Instalação
6
+
7
+ ```bash
8
+ npm i @praxisui/settings-panel
9
+ ```
10
+
11
+ Peer dependencies (Angular v20):
12
+ - `@angular/core` `^20.0.0`
13
+ - `@angular/common` `^20.0.0`
14
+ - `@angular/cdk` `^20.0.0`
15
+ - `@angular/material` `^20.0.0`
16
+ - `@praxisui/dynamic-fields` `^0.0.1`
17
+
18
+ ## Visão Geral
19
+
20
+ - Abra um painel com `SettingsPanelService.open(...)` informando um componente standalone como conteúdo.
21
+ - O componente implementa o contrato `SettingsValueProvider` para o painel habilitar/desabilitar ações do rodapé.
22
+ - O host observa `SettingsPanelRef.applied$` e `saved$` para aplicar/persistir mudanças.
23
+
24
+ ## API Principal
25
+
26
+ Serviço
27
+ - `open(config: SettingsPanelConfig): SettingsPanelRef`
28
+ - `config.id: string` Identificador único da instância
29
+ - `config.title?: string` Título do cabeçalho (opcional `titleIcon`)
30
+ - `config.content: { component: Type<any>; inputs?: Record<string, any> }` Componente + inputs iniciais
31
+
32
+ Ref
33
+ - `applied$: Observable<any>` Emite quando o usuário clica em Apply (painel permanece aberto)
34
+ - `saved$: Observable<any>` Emite quando o usuário clica em Save & Close
35
+ - `closed$: Observable<SettingsPanelCloseReason>` Emite ao fechar (`'cancel' | 'save' | 'backdrop' | 'esc'`)
36
+ - `apply(value: any)` Emite Apply programaticamente
37
+ - `save(value: any)` Emite Save & Close programaticamente
38
+ - `reset()` Notifica que o conteúdo foi resetado ao estado inicial
39
+ - `close(reason?: SettingsPanelCloseReason)` Fecha o painel
40
+
41
+ Injection Tokens
42
+ - `SETTINGS_PANEL_DATA` Dados passados ao componente de conteúdo (os mesmos de `content.inputs`)
43
+ - `SETTINGS_PANEL_REF` A instância viva do `SettingsPanelRef`
44
+
45
+ ## Contrato do Editor (SettingsValueProvider)
46
+
47
+ O componente hospedado deve expor os membros abaixo para o painel controlar os botões do rodapé:
48
+
49
+ Obrigatórios
50
+ - `isDirty$: Observable<boolean>` true quando há alterações não aplicadas (habilita Apply/Save)
51
+ - `isValid$: Observable<boolean>` true quando o estado é válido (desabilita ações se false)
52
+ - `isBusy$: Observable<boolean>` true durante operações assíncronas (desabilita ações)
53
+ - `getSettingsValue(): any` Snapshot atual usado em Apply/Save
54
+
55
+ Opcionais
56
+ - `onSave?(): any | Promise<any> | Observable<any>` Se presente, o Save chamará este método; caso contrário o painel usa `getSettingsValue()`
57
+ - `reset?(): void` Chamado quando o usuário clica Reset
58
+ - Avançados: `suggestExpanded$?`, `preferredWidth$?`, `requiresFullHeight$?`, `onPanelResize?`, `onBeforeClose?`, `onFocusChange?`, `customActions$?`, `hideDefaultButtons$?`
59
+
60
+ Comportamento do Rodapé
61
+ - Botões: Reset, Cancel, Apply, Save & Close
62
+ - Habilitação: `isDirty && isValid && !isBusy`
63
+ - Tooltips explicam por que ações estão desabilitadas (busy, inválido, sem mudanças)
64
+ - Atalhos: Ctrl/Cmd+S e Ctrl/Cmd+Enter disparam Save
65
+
66
+ ## Exemplo (abrindo um painel)
67
+
68
+ ```ts
69
+ // Em um componente host (ex.: Filtro Praxis)
70
+ const ref = this.settingsPanel.open({
71
+ id: `filter.${this.configKey}`,
72
+ title: 'Configurações do Filtro',
73
+ content: { component: FilterSettingsComponent, inputs: currentConfig },
74
+ });
75
+
76
+ // Tratar Apply (manter painel aberto)
77
+ ref.applied$.pipe(take(1)).subscribe((cfg: FilterConfig) => {
78
+ const safe = validateConfig(cfg);
79
+ applyChanges(safe);
80
+ persistConfig(safe, 'Configurações aplicadas');
81
+ });
82
+
83
+ // Tratar Save & Close
84
+ ref.saved$.pipe(take(1)).subscribe((cfg: FilterConfig) => {
85
+ const safe = validateConfig(cfg);
86
+ applyChanges(safe);
87
+ persistConfig(safe, 'Configurações salvas');
88
+ });
89
+ ```
90
+
91
+ ## Editor Mínimo
92
+
93
+ ```ts
94
+ @Component({ standalone: true /* imports… */ })
95
+ export class MySettingsEditor implements SettingsValueProvider {
96
+ private fb = inject(FormBuilder);
97
+ form = this.fb.group({ foo: ['bar', Validators.required] });
98
+
99
+ // Streams obrigatórias
100
+ isDirty$ = this.form.valueChanges.pipe(map(() => this.form.dirty), startWith(false));
101
+ isValid$ = this.form.statusChanges.pipe(map(() => this.form.valid), startWith(this.form.valid));
102
+ isBusy$ = of(false);
103
+
104
+ getSettingsValue() {
105
+ return this.form.getRawValue();
106
+ }
107
+
108
+ reset() {
109
+ this.form.reset({ foo: 'bar' });
110
+ }
111
+ }
112
+ ```
113
+
114
+ ## Build local e Publicação
115
+
116
+ ```bash
117
+ # build do pacote
118
+ ng build praxis-settings-panel
119
+
120
+ # verificar conteúdo do pacote
121
+ cd dist/praxis-settings-panel && npm pack
122
+ ```
123
+
124
+ O pacote publicado inclui este `README.md` via configuração de `assets` no `ng-package.json`.
125
+
126
+ ## Links
127
+ - Repositório: https://github.com/codexrodrigues/praxis
128
+ - Issues: https://github.com/codexrodrigues/praxis/issues