@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 +7 -0
- package/README.md +127 -0
- package/fesm2022/praxisui-tabs.mjs +2192 -0
- package/fesm2022/praxisui-tabs.mjs.map +1 -0
- package/index.d.ts +273 -0
- package/package.json +41 -0
package/LICENSE
ADDED
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.
|