@praxisui/tabs 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,127 @@
1
+ # @praxis/tabs — Praxis Tabs
2
+
3
+ Componente de abas (grupo e nav) configurável por metadados, com suporte a widgets internos, presets de estilo e editor integrado via Settings Panel.
4
+
5
+ ## Visão Geral
6
+
7
+ - Dois modos de renderização: `group` (mat-tab-group) e `nav` (mat-tab-nav-bar).
8
+ - Suporte a conteúdo dinâmico por campo (`DynamicFieldLoader`) e por widget (`DynamicWidgetLoader`).
9
+ - Integração com Settings Panel para edição/configuração em tempo de execução.
10
+ - Persistência opcional de configuração por `tabsId` usando `ConfigStorage`.
11
+ - Lazy load opcional do conteúdo para melhor desempenho.
12
+ - Eventos reemitidos com contexto (para conexões entre widgets/páginas).
13
+
14
+ ## API do Componente
15
+
16
+ Selector
17
+ - `praxis-tabs`
18
+
19
+ Inputs
20
+ - `config: TabsMetadata | null` Metadados completos para aparência, comportamento e conteúdo.
21
+ - `tabsId?: string` Identificador estável para persistir/restaurar a configuração.
22
+ - `form?: FormGroup` FormGroup opcional para campos dinâmicos declarados em `content`.
23
+ - `context?: any` Contexto propagado a widgets internos (via `DynamicWidgetLoader`).
24
+ - `editModeEnabled?: boolean` Exibe botão de edição quando verdadeiro (abre o editor).
25
+
26
+ Outputs
27
+ - `selectedIndexChange: number` Índice selecionado atualizado (ambos modos).
28
+ - `selectedTabChange: MatTabChangeEvent` Evento nativo do MatTabGroup.
29
+ - `focusChange, animationDone, indexFocused, selectFocusedIndex` Eventos nativos do Angular Material.
30
+ - `widgetEvent: { tabId?, tabIndex?, linkId?, linkIndex?, sourceId, output?, payload? }` Reemissão de eventos dos widgets internos com contexto da aba/link.
31
+
32
+ Persistência
33
+ - Quando `tabsId` é fornecido, a configuração é salva/recuperada de `ConfigStorage` na chave `tabs:<tabsId>`.
34
+
35
+ ## Estrutura de Metadados (resumo)
36
+
37
+ ```ts
38
+ export interface TabsMetadata {
39
+ appearance?: {
40
+ density?: 'compact' | 'comfortable' | 'spacious';
41
+ themeClass?: string;
42
+ customCss?: string; // CSS injetado inline
43
+ tokens?: Partial<TabsStyleTokens>; // tokens -> CSS gerado em runtime
44
+ };
45
+ behavior?: { lazyLoad?: boolean; closeable?: boolean; reorderable?: boolean };
46
+ accessibility?: { ariaLabels?: Record<string,string>; keyboardNavigation?: boolean; highContrast?: boolean; reduceMotion?: boolean };
47
+ group?: { alignTabs?: 'start' | 'center' | 'end'; headerPosition?: 'above'|'below'; selectedIndex?: number; dynamicHeight?: boolean; disableRipple?: boolean; disablePagination?: boolean; fitInkBarToContent?: boolean; stretchTabs?: boolean; color?: 'primary'|'accent'|'warn'; backgroundColor?: 'primary'|'accent'|'warn'|undefined; animationDuration?: string; };
48
+ tabs?: Array<{ id?: string; textLabel?: string; disabled?: boolean; labelClass?: string|string[]; bodyClass?: string|string[]; content?: any[]; widgets?: WidgetDefinition[] }>;
49
+ nav?: { links: Array<{ id?: string; label: string; disabled?: boolean; content?: any[]; widgets?: WidgetDefinition[] }>; selectedIndex?: number; disableRipple?: boolean; disablePagination?: boolean; fitInkBarToContent?: boolean; stretchTabs?: boolean; color?: 'primary'|'accent'|'warn'; backgroundColor?: 'primary'|'accent'|'warn'|undefined; animationDuration?: string };
50
+ }
51
+ ```
52
+
53
+ Tokens de Estilo (M3 aproximados)
54
+ - Exemplos: `active-indicator-color`, `active-label-text-color`, `inactive-label-text-color`, `pagination-icon-color`, `divider-color`, `background-color`.
55
+ - São transformados em CSS scoped por `data-tabs-id` em tempo de execução.
56
+
57
+ ## Editor de Configuração (Settings Panel)
58
+
59
+ Abrindo o editor completo programaticamente:
60
+
61
+ ```ts
62
+ const ref = settings.open({
63
+ id: `praxis-tabs-editor:${tabsId || 'default'}`,
64
+ title: 'Configurar Tabs',
65
+ content: { component: PraxisTabsConfigEditor, inputs: { config, tabsId } },
66
+ });
67
+ ref.applied$.subscribe(value => apply(value)); // mantém painel aberto
68
+ ref.saved$.subscribe(value => apply(value)); // fecha painel
69
+ ```
70
+
71
+ Contrato do Editor (`PraxisTabsConfigEditor` implementa `SettingsValueProvider`):
72
+ - `isDirty$`, `isValid$`, `isBusy$` controlam a habilitação dos botões.
73
+ - `getSettingsValue()` e `onSave()` retornam `{ config: TabsMetadata }`.
74
+ - Abas do editor: Comportamento, Grupo, Nav, JSON, Estilo, Abas, Links.
75
+ - JSON: editor de texto com validação e botão “Formatar”.
76
+ - Estilo: presets de tokens, classe de tema, CSS customizado e snippet SCSS sugerido.
77
+ - Abas/Links: adicionar/remover/reordenar, inserir widgets, presets rápidos (form/table/crud) usando `resourcePath`.
78
+
79
+ Quick Setup
80
+ - `openQuickSetup()` abre `TabsQuickSetupComponent` para criação rápida de abas/links.
81
+ - `applied$`/`saved$` aplicam a configuração ao componente.
82
+
83
+ ## Eventos e Conexões
84
+
85
+ `widgetEvent` reemite eventos de widgets internos com contexto da origem, permitindo conexões no Builder/Graph:
86
+
87
+ - Forma do evento: `{ tabId?, tabIndex?, linkId?, linkIndex?, sourceId, output?, payload }`.
88
+ - De um componente interno para fora:
89
+ - From: `{ widget: '<key do tabs>', output: 'widgetEvent' }`
90
+ - Map (exemplo tabela interna): `payload.payload.id`
91
+ - To: `<widget externo>.<input>`
92
+ - De fora para um componente interno (dot-path):
93
+ - Grupo: `inputs.config.tabs[<idx>].widgets[<widx>].inputs.<input>`
94
+ - Nav: `inputs.config.nav.links[<idx>].widgets[<widx>].inputs.<input>`
95
+
96
+ ## Lazy Load
97
+
98
+ - Ative `behavior.lazyLoad = true` para renderizar conteúdo somente quando a aba/link é visitado.
99
+ - O componente gerencia caches de índices visitados para não re-renderizar desnecessariamente.
100
+
101
+ ## Exemplo Mínimo
102
+
103
+ ```html
104
+ <praxis-tabs [config]="tabsCfg" [tabsId]="'cliente-tabs'" [editModeEnabled]="true" (widgetEvent)="onWidgetEvent($event)"></praxis-tabs>
105
+ ```
106
+
107
+ ```ts
108
+ // tabsCfg simples (modo grupo)
109
+ const tabsCfg: TabsMetadata = {
110
+ group: { selectedIndex: 0 },
111
+ tabs: [
112
+ { id: 't1', textLabel: 'Geral', widgets: [{ id: 'praxis-dynamic-form', inputs: { resourcePath: 'clientes' } }] },
113
+ { id: 't2', textLabel: 'Pedidos', widgets: [{ id: 'praxis-table', inputs: { resourcePath: 'pedidos' } }] },
114
+ ],
115
+ };
116
+ ```
117
+
118
+ ## Acessibilidade
119
+
120
+ - Suporte a `aria-label`/`aria-labelledby` em grupo e abas/links.
121
+ - Opções para reduzir animações (`accessibility.reduceMotion`) e alto contraste (`accessibility.highContrast`).
122
+
123
+ ## Notas
124
+
125
+ - Para persistência por usuário/escopo, forneça `tabsId` estável e deixe o componente gerir `ConfigStorage`.
126
+ - Tokens de estilo aceitam CSS vars ou cores (`#RRGGBB`/`rgb(...)`).
127
+ - Em M2, `color` e `backgroundColor` seguem as opções do Angular Material; em M3, prefira tokens.