@wrrdev/fenix-ui 1.0.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.
- package/README.md +117 -0
- package/dist/cdn.d.ts +6 -0
- package/dist/cdn.d.ts.map +1 -0
- package/dist/components/alert/alert.d.ts +14 -0
- package/dist/components/alert/alert.d.ts.map +1 -0
- package/dist/components/alert/alert.js +74 -0
- package/dist/components/alert/alert.js.map +1 -0
- package/dist/components/alert/index.d.ts +8 -0
- package/dist/components/alert/index.d.ts.map +1 -0
- package/dist/components/alert/index.js +7 -0
- package/dist/components/alert/index.js.map +1 -0
- package/dist/components/autocomplete/autocomplete.d.ts +20 -0
- package/dist/components/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/components/autocomplete/autocomplete.js +144 -0
- package/dist/components/autocomplete/autocomplete.js.map +1 -0
- package/dist/components/autocomplete/index.d.ts +8 -0
- package/dist/components/autocomplete/index.d.ts.map +1 -0
- package/dist/components/autocomplete/index.js +7 -0
- package/dist/components/autocomplete/index.js.map +1 -0
- package/dist/components/badge/badge.d.ts +14 -0
- package/dist/components/badge/badge.d.ts.map +1 -0
- package/dist/components/badge/badge.js +46 -0
- package/dist/components/badge/badge.js.map +1 -0
- package/dist/components/badge/index.d.ts +2 -0
- package/dist/components/badge/index.d.ts.map +1 -0
- package/dist/components/badge/index.js +7 -0
- package/dist/components/badge/index.js.map +1 -0
- package/dist/components/button/button.d.ts +30 -0
- package/dist/components/button/button.d.ts.map +1 -0
- package/dist/components/button/button.js +194 -0
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/button/index.d.ts +2 -0
- package/dist/components/button/index.d.ts.map +1 -0
- package/dist/components/button/index.js +7 -0
- package/dist/components/button/index.js.map +1 -0
- package/dist/components/calendar/calendar.d.ts +39 -0
- package/dist/components/calendar/calendar.d.ts.map +1 -0
- package/dist/components/calendar/calendar.js +346 -0
- package/dist/components/calendar/calendar.js.map +1 -0
- package/dist/components/calendar/index.d.ts +2 -0
- package/dist/components/calendar/index.d.ts.map +1 -0
- package/dist/components/calendar/index.js +7 -0
- package/dist/components/calendar/index.js.map +1 -0
- package/dist/components/checkbox/checkbox.d.ts +24 -0
- package/dist/components/checkbox/checkbox.d.ts.map +1 -0
- package/dist/components/checkbox/checkbox.js +142 -0
- package/dist/components/checkbox/checkbox.js.map +1 -0
- package/dist/components/checkbox/index.d.ts +2 -0
- package/dist/components/checkbox/index.d.ts.map +1 -0
- package/dist/components/checkbox/index.js +7 -0
- package/dist/components/checkbox/index.js.map +1 -0
- package/dist/components/datepicker/datepicker.d.ts +62 -0
- package/dist/components/datepicker/datepicker.d.ts.map +1 -0
- package/dist/components/datepicker/datepicker.js +441 -0
- package/dist/components/datepicker/datepicker.js.map +1 -0
- package/dist/components/datepicker/index.d.ts +3 -0
- package/dist/components/datepicker/index.d.ts.map +1 -0
- package/dist/components/datepicker/index.js +8 -0
- package/dist/components/datepicker/index.js.map +1 -0
- package/dist/components/dialog/dialog.d.ts +19 -0
- package/dist/components/dialog/dialog.d.ts.map +1 -0
- package/dist/components/dialog/dialog.js +134 -0
- package/dist/components/dialog/dialog.js.map +1 -0
- package/dist/components/dialog/index.d.ts +8 -0
- package/dist/components/dialog/index.d.ts.map +1 -0
- package/dist/components/dialog/index.js +7 -0
- package/dist/components/dialog/index.js.map +1 -0
- package/dist/components/drawer/drawer.d.ts +27 -0
- package/dist/components/drawer/drawer.d.ts.map +1 -0
- package/dist/components/drawer/drawer.js +195 -0
- package/dist/components/drawer/drawer.js.map +1 -0
- package/dist/components/drawer/index.d.ts +8 -0
- package/dist/components/drawer/index.d.ts.map +1 -0
- package/dist/components/drawer/index.js +7 -0
- package/dist/components/drawer/index.js.map +1 -0
- package/dist/components/dropdown/dropdown.d.ts +28 -0
- package/dist/components/dropdown/dropdown.d.ts.map +1 -0
- package/dist/components/dropdown/dropdown.js +137 -0
- package/dist/components/dropdown/dropdown.js.map +1 -0
- package/dist/components/dropdown/index.d.ts +9 -0
- package/dist/components/dropdown/index.d.ts.map +1 -0
- package/dist/components/dropdown/index.js +9 -0
- package/dist/components/dropdown/index.js.map +1 -0
- package/dist/components/floatlabel/floatlabel.d.ts +42 -0
- package/dist/components/floatlabel/floatlabel.d.ts.map +1 -0
- package/dist/components/floatlabel/floatlabel.js +270 -0
- package/dist/components/floatlabel/floatlabel.js.map +1 -0
- package/dist/components/floatlabel/index.d.ts +2 -0
- package/dist/components/floatlabel/index.d.ts.map +1 -0
- package/dist/components/floatlabel/index.js +7 -0
- package/dist/components/floatlabel/index.js.map +1 -0
- package/dist/components/input/index.d.ts +2 -0
- package/dist/components/input/index.d.ts.map +1 -0
- package/dist/components/input/index.js +7 -0
- package/dist/components/input/index.js.map +1 -0
- package/dist/components/input/input.d.ts +22 -0
- package/dist/components/input/input.d.ts.map +1 -0
- package/dist/components/input/input.js +169 -0
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/multiselect/index.d.ts +2 -0
- package/dist/components/multiselect/index.d.ts.map +1 -0
- package/dist/components/multiselect/index.js +7 -0
- package/dist/components/multiselect/index.js.map +1 -0
- package/dist/components/multiselect/multiselect.d.ts +32 -0
- package/dist/components/multiselect/multiselect.d.ts.map +1 -0
- package/dist/components/multiselect/multiselect.js +389 -0
- package/dist/components/multiselect/multiselect.js.map +1 -0
- package/dist/components/pagination/index.d.ts +8 -0
- package/dist/components/pagination/index.d.ts.map +1 -0
- package/dist/components/pagination/index.js +7 -0
- package/dist/components/pagination/index.js.map +1 -0
- package/dist/components/pagination/pagination.d.ts +23 -0
- package/dist/components/pagination/pagination.d.ts.map +1 -0
- package/dist/components/pagination/pagination.js +121 -0
- package/dist/components/pagination/pagination.js.map +1 -0
- package/dist/components/progress/index.d.ts +8 -0
- package/dist/components/progress/index.d.ts.map +1 -0
- package/dist/components/progress/index.js +7 -0
- package/dist/components/progress/index.js.map +1 -0
- package/dist/components/progress/progress.d.ts +18 -0
- package/dist/components/progress/progress.d.ts.map +1 -0
- package/dist/components/progress/progress.js +99 -0
- package/dist/components/progress/progress.js.map +1 -0
- package/dist/components/radio/index.d.ts +2 -0
- package/dist/components/radio/index.d.ts.map +1 -0
- package/dist/components/radio/index.js +7 -0
- package/dist/components/radio/index.js.map +1 -0
- package/dist/components/radio/radio.d.ts +23 -0
- package/dist/components/radio/radio.d.ts.map +1 -0
- package/dist/components/radio/radio.js +133 -0
- package/dist/components/radio/radio.js.map +1 -0
- package/dist/components/select/index.d.ts +2 -0
- package/dist/components/select/index.d.ts.map +1 -0
- package/dist/components/select/index.js +7 -0
- package/dist/components/select/index.js.map +1 -0
- package/dist/components/select/select.d.ts +36 -0
- package/dist/components/select/select.d.ts.map +1 -0
- package/dist/components/select/select.js +287 -0
- package/dist/components/select/select.js.map +1 -0
- package/dist/components/skeleton/index.d.ts +8 -0
- package/dist/components/skeleton/index.d.ts.map +1 -0
- package/dist/components/skeleton/index.js +7 -0
- package/dist/components/skeleton/index.js.map +1 -0
- package/dist/components/skeleton/skeleton.d.ts +13 -0
- package/dist/components/skeleton/skeleton.d.ts.map +1 -0
- package/dist/components/skeleton/skeleton.js +57 -0
- package/dist/components/skeleton/skeleton.js.map +1 -0
- package/dist/components/spinner/index.d.ts +2 -0
- package/dist/components/spinner/index.d.ts.map +1 -0
- package/dist/components/spinner/index.js +7 -0
- package/dist/components/spinner/index.js.map +1 -0
- package/dist/components/spinner/spinner.d.ts +16 -0
- package/dist/components/spinner/spinner.d.ts.map +1 -0
- package/dist/components/spinner/spinner.js +50 -0
- package/dist/components/spinner/spinner.js.map +1 -0
- package/dist/components/switch/index.d.ts +2 -0
- package/dist/components/switch/index.d.ts.map +1 -0
- package/dist/components/switch/index.js +7 -0
- package/dist/components/switch/index.js.map +1 -0
- package/dist/components/switch/switch.d.ts +22 -0
- package/dist/components/switch/switch.d.ts.map +1 -0
- package/dist/components/switch/switch.js +115 -0
- package/dist/components/switch/switch.js.map +1 -0
- package/dist/components/table/index.d.ts +2 -0
- package/dist/components/table/index.d.ts.map +1 -0
- package/dist/components/table/index.js +7 -0
- package/dist/components/table/index.js.map +1 -0
- package/dist/components/table/table.d.ts +38 -0
- package/dist/components/table/table.d.ts.map +1 -0
- package/dist/components/table/table.js +258 -0
- package/dist/components/table/table.js.map +1 -0
- package/dist/components/tabs/index.d.ts +9 -0
- package/dist/components/tabs/index.d.ts.map +1 -0
- package/dist/components/tabs/index.js +9 -0
- package/dist/components/tabs/index.js.map +1 -0
- package/dist/components/tabs/tabs.d.ts +38 -0
- package/dist/components/tabs/tabs.d.ts.map +1 -0
- package/dist/components/tabs/tabs.js +162 -0
- package/dist/components/tabs/tabs.js.map +1 -0
- package/dist/components/textarea/index.d.ts +8 -0
- package/dist/components/textarea/index.d.ts.map +1 -0
- package/dist/components/textarea/index.js +7 -0
- package/dist/components/textarea/index.js.map +1 -0
- package/dist/components/textarea/textarea.d.ts +19 -0
- package/dist/components/textarea/textarea.d.ts.map +1 -0
- package/dist/components/textarea/textarea.js +109 -0
- package/dist/components/textarea/textarea.js.map +1 -0
- package/dist/components/toast/index.d.ts +8 -0
- package/dist/components/toast/index.d.ts.map +1 -0
- package/dist/components/toast/index.js +8 -0
- package/dist/components/toast/index.js.map +1 -0
- package/dist/components/toast/toast.d.ts +40 -0
- package/dist/components/toast/toast.d.ts.map +1 -0
- package/dist/components/toast/toast.js +176 -0
- package/dist/components/toast/toast.js.map +1 -0
- package/dist/components/tooltip/index.d.ts +8 -0
- package/dist/components/tooltip/index.d.ts.map +1 -0
- package/dist/components/tooltip/index.js +7 -0
- package/dist/components/tooltip/index.js.map +1 -0
- package/dist/components/tooltip/tooltip.d.ts +14 -0
- package/dist/components/tooltip/tooltip.d.ts.map +1 -0
- package/dist/components/tooltip/tooltip.js +86 -0
- package/dist/components/tooltip/tooltip.js.map +1 -0
- package/dist/core/base.d.ts +29 -0
- package/dist/core/base.d.ts.map +1 -0
- package/dist/core/base.js +41 -0
- package/dist/core/base.js.map +1 -0
- package/dist/core/css.d.ts +6 -0
- package/dist/core/css.d.ts.map +1 -0
- package/dist/core/css.js +11 -0
- package/dist/core/css.js.map +1 -0
- package/dist/core/define.d.ts +8 -0
- package/dist/core/define.d.ts.map +1 -0
- package/dist/core/define.js +10 -0
- package/dist/core/define.js.map +1 -0
- package/dist/core/presets.d.ts +40 -0
- package/dist/core/presets.d.ts.map +1 -0
- package/dist/core/presets.js +80 -0
- package/dist/core/presets.js.map +1 -0
- package/dist/core/theme.d.ts +47 -0
- package/dist/core/theme.d.ts.map +1 -0
- package/dist/core/theme.js +76 -0
- package/dist/core/theme.js.map +1 -0
- package/dist/core/tokens.d.ts +36 -0
- package/dist/core/tokens.d.ts.map +1 -0
- package/dist/core/tokens.js +83 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/docs/app.d.ts +37 -0
- package/dist/docs/app.d.ts.map +1 -0
- package/dist/fenix-ui.esm.js +4471 -0
- package/dist/fenix-ui.esm.js.map +1 -0
- package/dist/fenix-ui.umd.min.js +2022 -0
- package/dist/fenix-ui2.esm.js +82 -0
- package/dist/fenix-ui2.esm.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/auto-import.d.ts +18 -0
- package/dist/plugins/auto-import.d.ts.map +1 -0
- package/dist/plugins/auto-import.js +69 -0
- package/dist/plugins/auto-import.js.map +1 -0
- package/dist/plugins/index.d.ts +25 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +21 -0
- package/dist/plugins/index.js.map +1 -0
- package/package.json +169 -0
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# FenixUI
|
|
2
|
+
|
|
3
|
+
Design System Web **nativo** — Web Components + Shadow DOM + Design Tokens.
|
|
4
|
+
Independente de framework: funciona em Vue, React, Angular, Svelte, HTML puro, Java/JSP, PHP, .NET.
|
|
5
|
+
|
|
6
|
+
## Arquitetura (por que tree-shaking de verdade)
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
src/
|
|
10
|
+
├── core/ # NÚCLEO compartilhado
|
|
11
|
+
│ ├── tokens.ts # Design Tokens (claro/escuro) → var(--fx-*)
|
|
12
|
+
│ ├── theme.ts # API global: FenixUI.configure/theme/setTokens/resetTheme
|
|
13
|
+
│ ├── base.ts # FxElement: classe-base (Shadow DOM + render)
|
|
14
|
+
│ ├── define.ts # registro seguro no CustomElementRegistry
|
|
15
|
+
│ └── css.ts # helpers CSS
|
|
16
|
+
└── components/
|
|
17
|
+
├── button/ # cada componente importa APENAS o core
|
|
18
|
+
├── badge/
|
|
19
|
+
└── spinner/
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
O build usa **Rollup `preserveModules`**: o `dist/` espelha o `src/`, um arquivo por módulo.
|
|
23
|
+
Quando o cliente importa apenas um componente, o bundler dele puxa **somente** esse módulo +
|
|
24
|
+
o core compartilhado — nunca a biblioteca inteira:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// O cliente compila apenas Button + core (~9 kB não-minificado).
|
|
28
|
+
import '@wrrdev/fenix-ui/button';
|
|
29
|
+
import { FenixUI } from '@wrrdev/fenix-ui/theme';
|
|
30
|
+
|
|
31
|
+
FenixUI.theme('dark');
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> Verificação real: bundle de consumidor contendo apenas `fx-button` e o core;
|
|
35
|
+
> `fx-badge`/`fx-spinner` ficaram **fora** do output do cliente.
|
|
36
|
+
|
|
37
|
+
## Consumo
|
|
38
|
+
|
|
39
|
+
### npm + bundler (recomendado — tree-shaking automático)
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import '@wrrdev/fenix-ui/button';
|
|
43
|
+
import '@wrrdev/fenix-ui/badge';
|
|
44
|
+
|
|
45
|
+
const el = document.createElement('fx-button');
|
|
46
|
+
el.setAttribute('variant', 'primary');
|
|
47
|
+
el.textContent = 'Salvar';
|
|
48
|
+
document.body.append(el);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### CDN / HTML puro / JSP / .NET
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<script src="https://cdn.exemplo.com/fenix-ui@0.1.0/dist/fenix-ui.umd.min.js"></script>
|
|
55
|
+
<script>
|
|
56
|
+
FenixUI.configure({ theme: 'dark' });
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<fx-button variant="danger" size="sm">Excluir</fx-button>
|
|
60
|
+
<fx-badge variant="success">Aprovado</fx-badge>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Temas em runtime (sem recompilar)
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
FenixUI.theme('dark'); // claro | escuro
|
|
67
|
+
FenixUI.setTokens({ color: { primary: '#0d9488' } }); // override parcial profundo
|
|
68
|
+
FenixUI.resetTheme();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Os tokens viram CSS Custom Properties (`--fx-color-primary`, `--fx-radius-md`, …) no `:root`,
|
|
72
|
+
atravessando o Shadow DOM. Todo componente reage automaticamente.
|
|
73
|
+
|
|
74
|
+
## Componentes (fase 1)
|
|
75
|
+
|
|
76
|
+
| Elemento | Atributos principais | Slots |
|
|
77
|
+
|--------------|-----------------------------------------------|--------------|
|
|
78
|
+
| `fx-button` | `variant` (primary/secondary/success/warning/danger/ghost/outline), `size`, `disabled`, `loading`, `type`, `full` | default, `icon` |
|
|
79
|
+
| `fx-badge` | `variant` (default/primary/success/warning/danger/info), `round` | default |
|
|
80
|
+
| `fx-input` | `type` (text/number/email/password/search/tel/url), `value`, `size`, `placeholder`, `disabled`, `readonly`, `min/max/step` | — |
|
|
81
|
+
| `fx-select` | `value`, `size` (sm/md/lg), `disabled`, `placeholder` — filhos `<option>` nativos | `(padrão)` |
|
|
82
|
+
| `fx-switch` | `checked`, `disabled`, `size` (sm/md/lg) | `(padrão)` |
|
|
83
|
+
| `fx-spinner` | `size` (sm/md/lg) | — |
|
|
84
|
+
|
|
85
|
+
Todos os componentes com tamanho usam **`md` como padrão** (valores inválidos caem para `md`).
|
|
86
|
+
Escala alinhada ao mercado (Material/Ant): **sm ≈ 32px · md ≈ 40px (padrão) · lg ≈ 48px**.
|
|
87
|
+
|
|
88
|
+
Eventos usam o nativo `click` no botão; `input`, `change` e o `change` do select são
|
|
89
|
+
`CustomEvent`s **composed** com `detail: { value }` (atravessam o Shadow DOM).
|
|
90
|
+
|
|
91
|
+
### Tokens de efeito (configuráveis por preset)
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
FenixUI.setTokens({
|
|
95
|
+
effect: {
|
|
96
|
+
ripple: '0', // desativa o efeito ripple do fx-button
|
|
97
|
+
'focus-ring': 'none', // campos sem anel de foco/sobra
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Presets sobrescrevem **apenas** os tokens informados — o restante herda do tema
|
|
103
|
+
base (claro/escuro) via deep merge (`deepMerge`).
|
|
104
|
+
|
|
105
|
+
## Scripts
|
|
106
|
+
|
|
107
|
+
| Comando | Ação |
|
|
108
|
+
|----------------------|-------------------------------------------------------------|
|
|
109
|
+
| `npm run dev` | Playground local (`index.html`) |
|
|
110
|
+
| `npm run test` | Testes unitários (Vitest + jsdom) |
|
|
111
|
+
| `npm run typecheck` | TypeScript estrito |
|
|
112
|
+
| `npm run build` | ESM modular + `.d.ts` + bundle CDN UMD |
|
|
113
|
+
|
|
114
|
+
## Convenções
|
|
115
|
+
|
|
116
|
+
- Elemento: `fx-{component}` · Token: `--fx-{grupo}-{chave}` · Tema: `light | dark`
|
|
117
|
+
- Sem dependência de Tailwind/Vue/React; reset interno mínimo; acessibilidade desde a primeira implementação.
|
package/dist/cdn.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,SAAS,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FxElement } from '../../core/base';
|
|
2
|
+
/**
|
|
3
|
+
* <fx-alert> — Aviso inline com variantes semânticas.
|
|
4
|
+
*
|
|
5
|
+
* Atributos: variant (info|success|warning|danger, padrão info), title, dismissible.
|
|
6
|
+
* Slot padrão: conteúdo da mensagem. Evento `dismiss`.
|
|
7
|
+
*/
|
|
8
|
+
export declare class FxAlert extends FxElement {
|
|
9
|
+
static styles: string;
|
|
10
|
+
static get observedAttributes(): string[];
|
|
11
|
+
protected render(): void;
|
|
12
|
+
}
|
|
13
|
+
export declare function defineFxAlert(): typeof FxAlert;
|
|
14
|
+
//# sourceMappingURL=alert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../../src/components/alert/alert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C;;;;;GAKG;AACH,qBAAa,OAAQ,SAAQ,SAAS;IACpC,OAAgB,MAAM,SAgCpB;IAEF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAEjD;cAEkB,MAAM,IAAI,IAAI;CAuBlC;AAED,wBAAgB,aAAa,IAAI,OAAO,OAAO,CAE9C"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { FxElement } from "../../core/base.js";
|
|
2
|
+
import { css } from "../../core/css.js";
|
|
3
|
+
import { defineElement } from "../../core/define.js";
|
|
4
|
+
const _FxAlert = class _FxAlert extends FxElement {
|
|
5
|
+
static get observedAttributes() {
|
|
6
|
+
return ["variant", "title", "dismissible"];
|
|
7
|
+
}
|
|
8
|
+
render() {
|
|
9
|
+
const variant = this.getAttr("variant", "info");
|
|
10
|
+
const title = this.getAttr("title");
|
|
11
|
+
const icons = {
|
|
12
|
+
info: "ℹ",
|
|
13
|
+
success: "✓",
|
|
14
|
+
warning: "⚠",
|
|
15
|
+
danger: "✕"
|
|
16
|
+
};
|
|
17
|
+
this.setTemplate(`
|
|
18
|
+
<div class="alert" part="alert" role="alert">
|
|
19
|
+
<span class="icon">${icons[variant] ?? "ℹ"}</span>
|
|
20
|
+
<div class="content">
|
|
21
|
+
${title ? `<div class="title">${title}</div>` : ""}
|
|
22
|
+
<div class="body"><slot></slot></div>
|
|
23
|
+
</div>
|
|
24
|
+
${this.hasAttr("dismissible") ? '<button type="button" class="close" aria-label="Fechar">×</button>' : ""}
|
|
25
|
+
</div>
|
|
26
|
+
`);
|
|
27
|
+
this.root.querySelector(".close")?.addEventListener("click", () => {
|
|
28
|
+
this.hidden = true;
|
|
29
|
+
this.dispatchEvent(new CustomEvent("dismiss", { bubbles: true, composed: true }));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
_FxAlert.styles = css`
|
|
34
|
+
:host {
|
|
35
|
+
display: block;
|
|
36
|
+
font-family: var(--fx-font-family);
|
|
37
|
+
--_color: var(--fx-color-primary);
|
|
38
|
+
--_bg: color-mix(in srgb, var(--fx-color-primary) 10%, var(--fx-surface-background));
|
|
39
|
+
}
|
|
40
|
+
:host([variant='success']) { --_color: var(--fx-color-success); --_bg: color-mix(in srgb, var(--fx-color-success) 10%, var(--fx-surface-background)); }
|
|
41
|
+
:host([variant='warning']) { --_color: var(--fx-color-warning); --_bg: color-mix(in srgb, var(--fx-color-warning) 12%, var(--fx-surface-background)); }
|
|
42
|
+
:host([variant='danger']) { --_color: var(--fx-color-danger); --_bg: color-mix(in srgb, var(--fx-color-danger) 10%, var(--fx-surface-background)); }
|
|
43
|
+
.alert {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: flex-start;
|
|
46
|
+
gap: var(--fx-space-md);
|
|
47
|
+
background: var(--_bg);
|
|
48
|
+
border: 1px solid color-mix(in srgb, var(--_color) 30%, transparent);
|
|
49
|
+
border-radius: var(--fx-radius-md);
|
|
50
|
+
padding: var(--fx-space-md) var(--fx-space-lg);
|
|
51
|
+
font-size: var(--fx-font-size);
|
|
52
|
+
color: var(--fx-text-default);
|
|
53
|
+
}
|
|
54
|
+
:host([hidden]) { display: none; }
|
|
55
|
+
.icon { color: var(--_color); font-weight: bold; line-height: 1.4; }
|
|
56
|
+
.content { flex: 1; }
|
|
57
|
+
.title { font-weight: 600; }
|
|
58
|
+
.body { margin-top: 2px; }
|
|
59
|
+
.close {
|
|
60
|
+
border: none; background: transparent; cursor: pointer;
|
|
61
|
+
color: var(--fx-text-muted); font-size: calc(var(--fx-font-size) + 2px);
|
|
62
|
+
line-height: 1; padding: 0; border-radius: var(--fx-radius-full);
|
|
63
|
+
}
|
|
64
|
+
.close:hover { color: var(--_color); }
|
|
65
|
+
`;
|
|
66
|
+
let FxAlert = _FxAlert;
|
|
67
|
+
function defineFxAlert() {
|
|
68
|
+
return defineElement("fx-alert", FxAlert);
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
FxAlert,
|
|
72
|
+
defineFxAlert
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert.js","sources":["../../../src/components/alert/alert.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\n\n/**\n * <fx-alert> — Aviso inline com variantes semânticas.\n *\n * Atributos: variant (info|success|warning|danger, padrão info), title, dismissible.\n * Slot padrão: conteúdo da mensagem. Evento `dismiss`.\n */\nexport class FxAlert extends FxElement {\n static override styles = css`\n :host {\n display: block;\n font-family: var(--fx-font-family);\n --_color: var(--fx-color-primary);\n --_bg: color-mix(in srgb, var(--fx-color-primary) 10%, var(--fx-surface-background));\n }\n :host([variant='success']) { --_color: var(--fx-color-success); --_bg: color-mix(in srgb, var(--fx-color-success) 10%, var(--fx-surface-background)); }\n :host([variant='warning']) { --_color: var(--fx-color-warning); --_bg: color-mix(in srgb, var(--fx-color-warning) 12%, var(--fx-surface-background)); }\n :host([variant='danger']) { --_color: var(--fx-color-danger); --_bg: color-mix(in srgb, var(--fx-color-danger) 10%, var(--fx-surface-background)); }\n .alert {\n display: flex;\n align-items: flex-start;\n gap: var(--fx-space-md);\n background: var(--_bg);\n border: 1px solid color-mix(in srgb, var(--_color) 30%, transparent);\n border-radius: var(--fx-radius-md);\n padding: var(--fx-space-md) var(--fx-space-lg);\n font-size: var(--fx-font-size);\n color: var(--fx-text-default);\n }\n :host([hidden]) { display: none; }\n .icon { color: var(--_color); font-weight: bold; line-height: 1.4; }\n .content { flex: 1; }\n .title { font-weight: 600; }\n .body { margin-top: 2px; }\n .close {\n border: none; background: transparent; cursor: pointer;\n color: var(--fx-text-muted); font-size: calc(var(--fx-font-size) + 2px);\n line-height: 1; padding: 0; border-radius: var(--fx-radius-full);\n }\n .close:hover { color: var(--_color); }\n `;\n\n static override get observedAttributes(): string[] {\n return ['variant', 'title', 'dismissible'];\n }\n\n protected override render(): void {\n const variant = this.getAttr('variant', 'info');\n const title = this.getAttr('title');\n const icons: Record<string, string> = {\n info: 'ℹ', success: '✓', warning: '⚠', danger: '✕',\n };\n\n this.setTemplate(`\n <div class=\"alert\" part=\"alert\" role=\"alert\">\n <span class=\"icon\">${icons[variant] ?? 'ℹ'}</span>\n <div class=\"content\">\n ${title ? `<div class=\"title\">${title}</div>` : ''}\n <div class=\"body\"><slot></slot></div>\n </div>\n ${this.hasAttr('dismissible') ? '<button type=\"button\" class=\"close\" aria-label=\"Fechar\">×</button>' : ''}\n </div>\n `);\n\n this.root.querySelector('.close')?.addEventListener('click', () => {\n this.hidden = true;\n this.dispatchEvent(new CustomEvent('dismiss', { bubbles: true, composed: true }));\n });\n }\n}\n\nexport function defineFxAlert(): typeof FxAlert {\n return defineElement('fx-alert', FxAlert);\n}\n"],"names":[],"mappings":";;;AAUO,MAAM,WAAN,MAAM,iBAAgB,UAAU;AAAA,EAmCrC,WAAoB,qBAA+B;AACjD,WAAO,CAAC,WAAW,SAAS,aAAa;AAAA,EAC3C;AAAA,EAEmB,SAAe;AAChC,UAAM,UAAU,KAAK,QAAQ,WAAW,MAAM;AAC9C,UAAM,QAAQ,KAAK,QAAQ,OAAO;AAClC,UAAM,QAAgC;AAAA,MACpC,MAAM;AAAA,MAAK,SAAS;AAAA,MAAK,SAAS;AAAA,MAAK,QAAQ;AAAA,IAAA;AAGjD,SAAK,YAAY;AAAA;AAAA,6BAEQ,MAAM,OAAO,KAAK,GAAG;AAAA;AAAA,YAEtC,QAAQ,sBAAsB,KAAK,WAAW,EAAE;AAAA;AAAA;AAAA,UAGlD,KAAK,QAAQ,aAAa,IAAI,uEAAuE,EAAE;AAAA;AAAA,KAE5G;AAED,SAAK,KAAK,cAAc,QAAQ,GAAG,iBAAiB,SAAS,MAAM;AACjE,WAAK,SAAS;AACd,WAAK,cAAc,IAAI,YAAY,WAAW,EAAE,SAAS,MAAM,UAAU,KAAA,CAAM,CAAC;AAAA,IAClF,CAAC;AAAA,EACH;AACF;AA7DE,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADpB,IAAM,UAAN;AAgEA,SAAS,gBAAgC;AAC9C,SAAO,cAAc,YAAY,OAAO;AAC1C;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/alert/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,SAAS,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,CAAC;AAKnB,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAC;KACrB;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/alert/index.ts"],"sourcesContent":["import { FxAlert, defineFxAlert } from './alert';\n\nexport { FxAlert };\n\n\ndefineFxAlert();\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'fx-alert': FxAlert;\n }\n}\n\r\n"],"names":[],"mappings":";;AAKA,cAAA;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FxElement } from '../../core/base';
|
|
2
|
+
/**
|
|
3
|
+
* <fx-autocomplete> — Campo de texto com sugestões filtradas.
|
|
4
|
+
*
|
|
5
|
+
* Atributos: value, size, placeholder, source (JSON array de strings),
|
|
6
|
+
* disabled, min-chars (padrão 1).
|
|
7
|
+
* Evento: `select` (composed, detail: { value }).
|
|
8
|
+
*/
|
|
9
|
+
export declare class FxAutocomplete extends FxElement {
|
|
10
|
+
static styles: string;
|
|
11
|
+
static get observedAttributes(): string[];
|
|
12
|
+
get size(): string;
|
|
13
|
+
set size(v: string);
|
|
14
|
+
get value(): string;
|
|
15
|
+
set value(v: string);
|
|
16
|
+
private get source();
|
|
17
|
+
protected render(): void;
|
|
18
|
+
}
|
|
19
|
+
export declare function defineFxAutocomplete(): typeof FxAutocomplete;
|
|
20
|
+
//# sourceMappingURL=autocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../../src/components/autocomplete/autocomplete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,SAAS;IAC3C,OAAgB,MAAM,SA8DpB;IAEF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAEjD;IAED,IAAI,IAAI,IAAI,MAAM,CAGjB;IACD,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,EAAmC;IACrD,IAAI,KAAK,IAAI,MAAM,CAAkC;IACrD,IAAI,KAAK,CAAC,CAAC,EAAE,MAAM,EAAoC;IAEvD,OAAO,KAAK,MAAM,GAOjB;cAEkB,MAAM,IAAI,IAAI;CAgDlC;AAED,wBAAgB,oBAAoB,IAAI,OAAO,cAAc,CAE5D"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { FxElement } from "../../core/base.js";
|
|
2
|
+
import { css } from "../../core/css.js";
|
|
3
|
+
import { defineElement } from "../../core/define.js";
|
|
4
|
+
const _FxAutocomplete = class _FxAutocomplete extends FxElement {
|
|
5
|
+
static get observedAttributes() {
|
|
6
|
+
return ["size", "placeholder", "source", "disabled", "min-chars"];
|
|
7
|
+
}
|
|
8
|
+
get size() {
|
|
9
|
+
const s = this.getAttr("size", "md");
|
|
10
|
+
return s === "sm" || s === "lg" ? s : "md";
|
|
11
|
+
}
|
|
12
|
+
set size(v) {
|
|
13
|
+
this.setAttribute("size", v);
|
|
14
|
+
}
|
|
15
|
+
get value() {
|
|
16
|
+
return this.getAttr("value");
|
|
17
|
+
}
|
|
18
|
+
set value(v) {
|
|
19
|
+
this.setAttribute("value", v);
|
|
20
|
+
}
|
|
21
|
+
get source() {
|
|
22
|
+
try {
|
|
23
|
+
const raw = JSON.parse(this.getAttr("source", "[]"));
|
|
24
|
+
return Array.isArray(raw) ? raw.map(String) : [];
|
|
25
|
+
} catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
render() {
|
|
30
|
+
const placeholder = this.getAttr("placeholder");
|
|
31
|
+
this.setTemplate(`
|
|
32
|
+
<input class="field" part="input" type="text"
|
|
33
|
+
${placeholder ? `placeholder="${placeholder}"` : ""} autocomplete="off"/>
|
|
34
|
+
<div class="list" part="list" role="listbox"></div>
|
|
35
|
+
`);
|
|
36
|
+
const field = this.root.querySelector(".field");
|
|
37
|
+
if (!field) return;
|
|
38
|
+
field.value = this.value;
|
|
39
|
+
if (this.hasAttr("disabled")) field.setAttribute("disabled", "");
|
|
40
|
+
const list = this.root.querySelector(".list");
|
|
41
|
+
const minChars = Number(this.getAttr("min-chars", "1")) || 1;
|
|
42
|
+
const openList = () => {
|
|
43
|
+
if (!list) return;
|
|
44
|
+
const q = field.value.toLowerCase();
|
|
45
|
+
const matches = this.source.filter((s) => s.toLowerCase().includes(q)).slice(0, 8);
|
|
46
|
+
list.innerHTML = matches.length ? matches.map((m) => `<button type="button" class="opt" role="option" data-v="${m}">${m}</button>`).join("") : '<div class="empty">Nenhum resultado</div>';
|
|
47
|
+
list.querySelectorAll(".opt").forEach((btn) => {
|
|
48
|
+
btn.addEventListener("click", () => {
|
|
49
|
+
field.value = btn.dataset.v ?? "";
|
|
50
|
+
this.value = field.value;
|
|
51
|
+
this.toggleAttr("open", false);
|
|
52
|
+
this.dispatchEvent(new CustomEvent("select", {
|
|
53
|
+
bubbles: true,
|
|
54
|
+
composed: true,
|
|
55
|
+
detail: { value: this.value }
|
|
56
|
+
}));
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
this.toggleAttr("open", true);
|
|
60
|
+
};
|
|
61
|
+
field.addEventListener("input", () => {
|
|
62
|
+
this.value = field.value;
|
|
63
|
+
openList();
|
|
64
|
+
});
|
|
65
|
+
field.addEventListener("focus", () => {
|
|
66
|
+
if (field.value.length >= minChars) openList();
|
|
67
|
+
});
|
|
68
|
+
document.addEventListener("click", (e) => {
|
|
69
|
+
if (!this.contains(e.target)) this.toggleAttr("open", false);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
_FxAutocomplete.styles = css`
|
|
74
|
+
:host {
|
|
75
|
+
position: relative;
|
|
76
|
+
display: inline-block;
|
|
77
|
+
font-family: var(--fx-font-family);
|
|
78
|
+
font-size: var(--fx-font-size);
|
|
79
|
+
}
|
|
80
|
+
input {
|
|
81
|
+
font-family: inherit;
|
|
82
|
+
font-size: inherit;
|
|
83
|
+
font-weight: var(--fx-font-weight);
|
|
84
|
+
color: var(--fx-text-default);
|
|
85
|
+
background-color: var(--fx-surface-background);
|
|
86
|
+
border: 1px solid var(--fx-border-default);
|
|
87
|
+
border-radius: var(--fx-radius-md);
|
|
88
|
+
padding: var(--fx-space-md) var(--fx-space-lg);
|
|
89
|
+
width: 260px;
|
|
90
|
+
min-height: var(--fx-size-md);
|
|
91
|
+
box-sizing: border-box;
|
|
92
|
+
transition:
|
|
93
|
+
border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),
|
|
94
|
+
box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing);
|
|
95
|
+
}
|
|
96
|
+
input::placeholder { color: var(--fx-text-muted); opacity: 1; }
|
|
97
|
+
input:hover { border-color: var(--fx-border-hover); }
|
|
98
|
+
input:focus-visible {
|
|
99
|
+
outline: none;
|
|
100
|
+
border-color: var(--fx-color-primary);
|
|
101
|
+
box-shadow: var(--fx-effect-focus-ring, none);
|
|
102
|
+
}
|
|
103
|
+
:host([size='sm']) input { width: 220px; min-height: var(--fx-size-sm); padding: var(--fx-space-sm) var(--fx-space-md); }
|
|
104
|
+
:host([size='lg']) input { width: 300px; min-height: var(--fx-size-lg); }
|
|
105
|
+
.list {
|
|
106
|
+
position: absolute;
|
|
107
|
+
top: calc(100% + 4px);
|
|
108
|
+
left: 0;
|
|
109
|
+
right: 0;
|
|
110
|
+
background: var(--fx-surface-background);
|
|
111
|
+
border: 1px solid var(--fx-border-default);
|
|
112
|
+
border-radius: var(--fx-radius-md);
|
|
113
|
+
box-shadow: var(--fx-shadow-lg);
|
|
114
|
+
z-index: var(--fx-z-dropdown, 1000);
|
|
115
|
+
max-height: 220px;
|
|
116
|
+
overflow-y: auto;
|
|
117
|
+
display: none;
|
|
118
|
+
}
|
|
119
|
+
:host([open]) .list { display: block; }
|
|
120
|
+
.opt {
|
|
121
|
+
display: block;
|
|
122
|
+
width: 100%;
|
|
123
|
+
text-align: left;
|
|
124
|
+
border: none;
|
|
125
|
+
background: transparent;
|
|
126
|
+
font-family: inherit;
|
|
127
|
+
font-size: inherit;
|
|
128
|
+
color: var(--fx-text-default);
|
|
129
|
+
padding: var(--fx-space-sm) var(--fx-space-md);
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing);
|
|
132
|
+
}
|
|
133
|
+
.opt:hover { background: color-mix(in srgb, var(--fx-color-primary) 12%, var(--fx-surface-background)); color: var(--fx-color-primary); }
|
|
134
|
+
.empty { color: var(--fx-text-muted); font-size: calc(var(--fx-font-size) - 2px); padding: var(--fx-space-sm) var(--fx-space-md); }
|
|
135
|
+
`;
|
|
136
|
+
let FxAutocomplete = _FxAutocomplete;
|
|
137
|
+
function defineFxAutocomplete() {
|
|
138
|
+
return defineElement("fx-autocomplete", FxAutocomplete);
|
|
139
|
+
}
|
|
140
|
+
export {
|
|
141
|
+
FxAutocomplete,
|
|
142
|
+
defineFxAutocomplete
|
|
143
|
+
};
|
|
144
|
+
//# sourceMappingURL=autocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autocomplete.js","sources":["../../../src/components/autocomplete/autocomplete.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\n\n/**\n * <fx-autocomplete> — Campo de texto com sugestões filtradas.\n *\n * Atributos: value, size, placeholder, source (JSON array de strings),\n * disabled, min-chars (padrão 1).\n * Evento: `select` (composed, detail: { value }).\n */\nexport class FxAutocomplete extends FxElement {\n static override styles = css`\n :host {\n position: relative;\n display: inline-block;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n }\n input {\n font-family: inherit;\n font-size: inherit;\n font-weight: var(--fx-font-weight);\n color: var(--fx-text-default);\n background-color: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n padding: var(--fx-space-md) var(--fx-space-lg);\n width: 260px;\n min-height: var(--fx-size-md);\n box-sizing: border-box;\n transition:\n border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),\n box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n input::placeholder { color: var(--fx-text-muted); opacity: 1; }\n input:hover { border-color: var(--fx-border-hover); }\n input:focus-visible {\n outline: none;\n border-color: var(--fx-color-primary);\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n :host([size='sm']) input { width: 220px; min-height: var(--fx-size-sm); padding: var(--fx-space-sm) var(--fx-space-md); }\n :host([size='lg']) input { width: 300px; min-height: var(--fx-size-lg); }\n .list {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n box-shadow: var(--fx-shadow-lg);\n z-index: var(--fx-z-dropdown, 1000);\n max-height: 220px;\n overflow-y: auto;\n display: none;\n }\n :host([open]) .list { display: block; }\n .opt {\n display: block;\n width: 100%;\n text-align: left;\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: inherit;\n color: var(--fx-text-default);\n padding: var(--fx-space-sm) var(--fx-space-md);\n cursor: pointer;\n transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing);\n }\n .opt:hover { background: color-mix(in srgb, var(--fx-color-primary) 12%, var(--fx-surface-background)); color: var(--fx-color-primary); }\n .empty { color: var(--fx-text-muted); font-size: calc(var(--fx-font-size) - 2px); padding: var(--fx-space-sm) var(--fx-space-md); }\n `;\n\n static override get observedAttributes(): string[] {\n return ['size', 'placeholder', 'source', 'disabled', 'min-chars'];\n }\n\n get size(): string {\n const s = this.getAttr('size', 'md');\n return s === 'sm' || s === 'lg' ? s : 'md';\n }\n set size(v: string) { this.setAttribute('size', v); }\n get value(): string { return this.getAttr('value'); }\n set value(v: string) { this.setAttribute('value', v); }\n\n private get source(): string[] {\n try {\n const raw = JSON.parse(this.getAttr('source', '[]'));\n return Array.isArray(raw) ? raw.map(String) : [];\n } catch {\n return [];\n }\n }\n\n protected override render(): void {\n const placeholder = this.getAttr('placeholder');\n\n this.setTemplate(`\n <input class=\"field\" part=\"input\" type=\"text\"\n ${placeholder ? `placeholder=\"${placeholder}\"` : ''} autocomplete=\"off\"/>\n <div class=\"list\" part=\"list\" role=\"listbox\"></div>\n `);\n\n const field = this.root.querySelector<HTMLInputElement>('.field');\n if (!field) return;\n field.value = this.value;\n if (this.hasAttr('disabled')) field.setAttribute('disabled', '');\n\n const list = this.root.querySelector<HTMLElement>('.list');\n const minChars = Number(this.getAttr('min-chars', '1')) || 1;\n\n const openList = (): void => {\n if (!list) return;\n const q = field.value.toLowerCase();\n const matches = this.source.filter((s) => s.toLowerCase().includes(q)).slice(0, 8);\n list.innerHTML = matches.length\n ? matches.map((m) => `<button type=\"button\" class=\"opt\" role=\"option\" data-v=\"${m}\">${m}</button>`).join('')\n : '<div class=\"empty\">Nenhum resultado</div>';\n list.querySelectorAll<HTMLButtonElement>('.opt').forEach((btn) => {\n btn.addEventListener('click', () => {\n field.value = btn.dataset.v ?? '';\n this.value = field.value;\n this.toggleAttr('open', false);\n this.dispatchEvent(new CustomEvent('select', {\n bubbles: true, composed: true, detail: { value: this.value },\n }));\n });\n });\n this.toggleAttr('open', true);\n };\n\n // Reabrir com foco sem re-render (evita perder digitação)\n field.addEventListener('input', () => {\n this.value = field.value;\n openList();\n });\n field.addEventListener('focus', () => { if (field.value.length >= minChars) openList(); });\n\n document.addEventListener('click', (e) => {\n if (!this.contains(e.target as Node)) this.toggleAttr('open', false);\n });\n }\n}\n\nexport function defineFxAutocomplete(): typeof FxAutocomplete {\n return defineElement('fx-autocomplete', FxAutocomplete);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/autocomplete/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAwB,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,CAAC;AAK1B,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,cAAc,CAAC;KACnC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/autocomplete/index.ts"],"sourcesContent":["import { FxAutocomplete, defineFxAutocomplete } from './autocomplete';\n\nexport { FxAutocomplete };\n\n\ndefineFxAutocomplete();\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'fx-autocomplete': FxAutocomplete;\n }\n}\n\r\n"],"names":[],"mappings":";;AAKA,qBAAA;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FxElement } from '../../core/base';
|
|
2
|
+
/**
|
|
3
|
+
* <fx-badge> — Rótulo/contador de status.
|
|
4
|
+
*
|
|
5
|
+
* Atributos: variant (default|primary|success|warning|danger|info), round.
|
|
6
|
+
* Slots: default (conteúdo).
|
|
7
|
+
*/
|
|
8
|
+
export declare class FxBadge extends FxElement {
|
|
9
|
+
static styles: string;
|
|
10
|
+
static get observedAttributes(): string[];
|
|
11
|
+
protected render(): void;
|
|
12
|
+
}
|
|
13
|
+
export declare function defineFxBadge(): typeof FxBadge;
|
|
14
|
+
//# sourceMappingURL=badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/components/badge/badge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C;;;;;GAKG;AACH,qBAAa,OAAQ,SAAQ,SAAS;IACpC,OAAgB,MAAM,SAyBpB;IAEF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAEjD;cAEkB,MAAM,IAAI,IAAI;CAGlC;AAED,wBAAgB,aAAa,IAAI,OAAO,OAAO,CAE9C"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FxElement } from "../../core/base.js";
|
|
2
|
+
import { css } from "../../core/css.js";
|
|
3
|
+
import { defineElement } from "../../core/define.js";
|
|
4
|
+
const _FxBadge = class _FxBadge extends FxElement {
|
|
5
|
+
static get observedAttributes() {
|
|
6
|
+
return ["variant", "round"];
|
|
7
|
+
}
|
|
8
|
+
render() {
|
|
9
|
+
this.setTemplate(`<span class="badge" part="badge"><slot></slot></span>`);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
_FxBadge.styles = css`
|
|
13
|
+
:host {
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
vertical-align: middle;
|
|
16
|
+
}
|
|
17
|
+
.badge {
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
font-family: var(--fx-font-family);
|
|
21
|
+
font-size: calc(var(--fx-font-size) - 2px);
|
|
22
|
+
font-weight: var(--fx-font-weight);
|
|
23
|
+
line-height: 1;
|
|
24
|
+
padding: var(--fx-space-xs) var(--fx-space-sm);
|
|
25
|
+
border-radius: var(--fx-radius-full);
|
|
26
|
+
border: 1px solid var(--fx-border-default);
|
|
27
|
+
background: var(--fx-surface-background);
|
|
28
|
+
color: var(--fx-text-muted);
|
|
29
|
+
white-space: nowrap;
|
|
30
|
+
}
|
|
31
|
+
:host([variant='primary']) .badge { background: var(--fx-color-primary); color: #fff; border-color: transparent; }
|
|
32
|
+
:host([variant='success']) .badge { background: var(--fx-color-success); color: #fff; border-color: transparent; }
|
|
33
|
+
:host([variant='warning']) .badge { background: var(--fx-color-warning); color: #fff; border-color: transparent; }
|
|
34
|
+
:host([variant='danger']) .badge { background: var(--fx-color-danger); color: #fff; border-color: transparent; }
|
|
35
|
+
:host([variant='info']) .badge { background: var(--fx-color-info); color: #fff; border-color: transparent; }
|
|
36
|
+
:host(:not([round])) .badge { border-radius: var(--fx-radius-sm); }
|
|
37
|
+
`;
|
|
38
|
+
let FxBadge = _FxBadge;
|
|
39
|
+
function defineFxBadge() {
|
|
40
|
+
return defineElement("fx-badge", FxBadge);
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
FxBadge,
|
|
44
|
+
defineFxBadge
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.js","sources":["../../../src/components/badge/badge.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\n\n/**\n * <fx-badge> — Rótulo/contador de status.\n *\n * Atributos: variant (default|primary|success|warning|danger|info), round.\n * Slots: default (conteúdo).\n */\nexport class FxBadge extends FxElement {\n static override styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n .badge {\n display: inline-flex;\n align-items: center;\n font-family: var(--fx-font-family);\n font-size: calc(var(--fx-font-size) - 2px);\n font-weight: var(--fx-font-weight);\n line-height: 1;\n padding: var(--fx-space-xs) var(--fx-space-sm);\n border-radius: var(--fx-radius-full);\n border: 1px solid var(--fx-border-default);\n background: var(--fx-surface-background);\n color: var(--fx-text-muted);\n white-space: nowrap;\n }\n :host([variant='primary']) .badge { background: var(--fx-color-primary); color: #fff; border-color: transparent; }\n :host([variant='success']) .badge { background: var(--fx-color-success); color: #fff; border-color: transparent; }\n :host([variant='warning']) .badge { background: var(--fx-color-warning); color: #fff; border-color: transparent; }\n :host([variant='danger']) .badge { background: var(--fx-color-danger); color: #fff; border-color: transparent; }\n :host([variant='info']) .badge { background: var(--fx-color-info); color: #fff; border-color: transparent; }\n :host(:not([round])) .badge { border-radius: var(--fx-radius-sm); }\n `;\n\n static override get observedAttributes(): string[] {\n return ['variant', 'round'];\n }\n\n protected override render(): void {\n this.setTemplate(`<span class=\"badge\" part=\"badge\"><slot></slot></span>`);\n }\n}\n\nexport function defineFxBadge(): typeof FxBadge {\n return defineElement('fx-badge', FxBadge);\n}"],"names":[],"mappings":";;;AAUO,MAAM,WAAN,MAAM,iBAAgB,UAAU;AAAA,EA4BrC,WAAoB,qBAA+B;AACjD,WAAO,CAAC,WAAW,OAAO;AAAA,EAC5B;AAAA,EAEmB,SAAe;AAChC,SAAK,YAAY,uDAAuD;AAAA,EAC1E;AACF;AAlCE,SAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADpB,IAAM,UAAN;AAqCA,SAAS,gBAAgC;AAC9C,SAAO,cAAc,YAAY,OAAO;AAC1C;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/badge/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/badge/index.ts"],"sourcesContent":["import { defineFxBadge } from './badge';\n\n// Reexporta a classe para uso programático (instanceof, herança).\nexport { FxBadge } from './badge';\n\n// Auto-registro ao importar o subpath `@wrrdev/fenix-ui/badge`.\ndefineFxBadge();"],"names":[],"mappings":";;AAMA,cAAA;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FxElement } from '../../core/base';
|
|
2
|
+
/**
|
|
3
|
+
* <fx-button> — Componente de ação (piloto).
|
|
4
|
+
*
|
|
5
|
+
* Atributos: variant, size, disabled, loading, type, full.
|
|
6
|
+
* Slots: default (rótulo), `icon` (ícone opcional).
|
|
7
|
+
* Evento: `click` nativo atravessa o Shadow DOM (composed) — ouça no host.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FxButton extends FxElement {
|
|
10
|
+
static styles: string;
|
|
11
|
+
static get observedAttributes(): string[];
|
|
12
|
+
/** Tamanho. Padrão: `'md'`. */
|
|
13
|
+
get size(): string;
|
|
14
|
+
set size(value: string);
|
|
15
|
+
get disabled(): boolean;
|
|
16
|
+
set disabled(value: boolean);
|
|
17
|
+
get loading(): boolean;
|
|
18
|
+
set loading(value: boolean);
|
|
19
|
+
protected render(): void;
|
|
20
|
+
protected connectedCallback(): void;
|
|
21
|
+
protected disconnectedCallback(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Efeito ripple : cria um círculo que expande do ponto
|
|
24
|
+
* de clique e desaparece. Respeita o token `effect.ripple` ('0' desativa)
|
|
25
|
+
* e `prefers-reduced-motion` (via CSS).
|
|
26
|
+
*/
|
|
27
|
+
private spawnRipple;
|
|
28
|
+
}
|
|
29
|
+
export declare function defineFxButton(): typeof FxButton;
|
|
30
|
+
//# sourceMappingURL=button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/button/button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C;;;;;;GAMG;AACH,qBAAa,QAAS,SAAQ,SAAS;IACrC,OAAgB,MAAM,SAoGpB;IAEF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAEjD;IAED,+BAA+B;IAC/B,IAAI,IAAI,IAAI,MAAM,CAGjB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAErB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;cAEkB,MAAM,IAAI,IAAI;cAmCd,iBAAiB,IAAI,IAAI;cAKzB,oBAAoB,IAAI,IAAI;IAK/C;;;;OAIG;IACH,OAAO,CAAC,WAAW,CAmBjB;CACH;AAED,wBAAgB,cAAc,IAAI,OAAO,QAAQ,CAEhD"}
|