@sapphire-caitlyn/schema-kit-ng 0.0.4 → 0.0.6

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.
Files changed (37) hide show
  1. package/README.md +2 -0
  2. package/docs/inputs/date/input-date/README.md +37 -0
  3. package/docs/inputs/date/input-date-span/README.md +36 -0
  4. package/docs/inputs/date/input-date-time/README.md +32 -0
  5. package/docs/inputs/date/input-date-time-span/README.md +32 -0
  6. package/docs/inputs/date/input-time/README.md +28 -0
  7. package/docs/inputs/date/input-time-span/README.md +29 -0
  8. package/docs/inputs/input-base/README.md +42 -0
  9. package/docs/inputs/input-bool/README.md +30 -0
  10. package/docs/inputs/input-color/README.md +24 -0
  11. package/docs/inputs/input-color/color-picker/README.md +25 -0
  12. package/docs/inputs/input-cpf-cnpj/README.md +34 -0
  13. package/docs/inputs/input-file/README.md +33 -0
  14. package/docs/inputs/input-icon/README.md +28 -0
  15. package/docs/inputs/input-json/README.md +36 -0
  16. package/docs/inputs/input-mask/README.md +39 -0
  17. package/docs/inputs/input-number/README.md +44 -0
  18. package/docs/inputs/input-phone/README.md +25 -0
  19. package/docs/inputs/input-select/README.md +42 -0
  20. package/docs/inputs/input-string/README.md +32 -0
  21. package/docs/inputs/input-text-area/README.md +27 -0
  22. package/docs/schema-table/README.md +444 -0
  23. package/docs/schema-view/README.md +439 -0
  24. package/docs/ui/blurry-text-reveal/README.md +49 -0
  25. package/docs/ui/breadcrumbs/README.md +62 -0
  26. package/docs/ui/file-preview/README.md +60 -0
  27. package/docs/ui/infinte-scroll/README.md +10 -0
  28. package/docs/ui/loading/README.md +62 -0
  29. package/docs/ui/save-button/README.md +68 -0
  30. package/docs/ui/schema-dialog/README.md +154 -0
  31. package/docs/ui/suspended-slider/README.md +95 -0
  32. package/docs/ui/tree-drag-drop/README.md +202 -0
  33. package/fesm2022/sapphire-caitlyn-schema-kit-ng-helm.mjs.map +1 -1
  34. package/fesm2022/sapphire-caitlyn-schema-kit-ng.mjs +106 -103
  35. package/fesm2022/sapphire-caitlyn-schema-kit-ng.mjs.map +1 -1
  36. package/package.json +1 -1
  37. package/types/sapphire-caitlyn-schema-kit-ng.d.ts +93 -17
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Lib de CRUD do backoffice: um `SchemaService` descreve a entidade, o `<schema-table>` faz a listagem e o
4
4
  `<schema-view>` faz o criar/editar. Cada componente tem um README ao lado do código, em `src/lib/components/`.
5
+ No pacote publicado eles ficam em `docs/`, com a mesma estrutura de pastas (ex.: `docs/schema-view/README.md`),
6
+ então os links entre eles continuam valendo. README novo em `src/lib/components/` entra no pacote sem configuração.
5
7
 
6
8
  ## Entry points
7
9
 
@@ -0,0 +1,37 @@
1
+ # input-date
2
+
3
+ Data com calendário e digitação mascarada (`dd/MM/yyyy`).
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputDateComponent } from '@schema-kit';
9
+ import { DateTime } from 'luxon';
10
+
11
+ hoje = DateTime.now();
12
+ ```
13
+
14
+ ```html
15
+ <input-date label="Nascimento" [maxDate]="hoje" [formField]="form.nascimento" />
16
+ ```
17
+
18
+ ## Inputs
19
+
20
+ | Input | Tipo | Padrão | Descrição |
21
+ | -------------------- | ------------------ | ---------------- | --------------------------------- |
22
+ | `minDate` | `DateTime \| null` | `null` | Menor data selecionável |
23
+ | `maxDate` | `DateTime \| null` | `null` | Maior data selecionável |
24
+ | `defaultFocusedDate` | `DateTime` | `DateTime.now()` | Mês aberto no calendário sem valor |
25
+
26
+ Comuns (`label`, `loading`, `tooltipInfo`): [input-base](../../input-base/README.md).
27
+
28
+ **Valor:** `string | null`: ISO às 00:00 locais, com offset (ex.: `2026-11-03T00:00:00.000-03:00`).
29
+
30
+ ## Slots
31
+
32
+ - `[slot=input]`: dentro do date picker, depois do campo.
33
+
34
+ ## Atenção
35
+
36
+ - `placeholder` é ignorado (fixo `dd/MM/yyyy`).
37
+ - Não emite `touch`.
@@ -0,0 +1,36 @@
1
+ # input-date-span
2
+
3
+ Intervalo de datas com calendário de intervalo e digitação mascarada (`dd/MM/yyyy - dd/MM/yyyy`).
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputDateSpanComponent, Span } from '@schema-kit';
9
+
10
+ model = signal<{ periodo: Span | null }>({ periodo: null });
11
+ ```
12
+
13
+ ```html
14
+ <input-date-span label="Período" [formField]="form.periodo" />
15
+ ```
16
+
17
+ ## Inputs
18
+
19
+ | Input | Tipo | Padrão | Descrição |
20
+ | --------- | ------------------ | ------ | ----------------------- |
21
+ | `minDate` | `DateTime \| null` | `null` | Menor data selecionável |
22
+ | `maxDate` | `DateTime \| null` | `null` | Maior data selecionável |
23
+
24
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../../input-base/README.md).
25
+
26
+ **Valor:** `Span | null` = `[início, fim]` em ISO às 00:00 locais. `null` quando vazio.
27
+
28
+ ## Slots
29
+
30
+ - `[slot=input]`: dentro do date picker, depois do campo.
31
+
32
+ ## Atenção
33
+
34
+ - Digitar uma data só vira um intervalo de um dia. Datas invertidas são ordenadas.
35
+ - O fim é 00:00 do último dia, não o fim do dia.
36
+ - Com `[formField]`, as duas pontas são marcadas como dirty ao mudar, para o span entrar no `extractValue({ dirty: true })`.
@@ -0,0 +1,32 @@
1
+ # input-date-time
2
+
3
+ Data e hora: digitação mascarada (`dd/MM/yyyy HH:mm:ss`) ou calendário + campo de horário num popover.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputDateTimeComponent } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-date-time label="Agendado para" [enableSeconds]="false" [formField]="form.agendadoEm" />
13
+ ```
14
+
15
+ ## Inputs
16
+
17
+ | Input | Tipo | Padrão | Descrição |
18
+ | --------------- | ------------------ | ------ | ---------------------------------- |
19
+ | `minDate` | `DateTime \| null` | `null` | Menor data aceita |
20
+ | `maxDate` | `DateTime \| null` | `null` | Maior data aceita |
21
+ | `enableSeconds` | `boolean` | `true` | `HH:mm:ss` ou `HH:mm` na digitação |
22
+
23
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../../input-base/README.md).
24
+
25
+ **Valor:** `string | null`: ISO com offset (ex.: `2026-11-03T14:30:00.000-03:00`).
26
+
27
+ ## Atenção
28
+
29
+ - Escolher só o horário, sem data, usa o dia de hoje.
30
+ - Trocar a data no calendário mantém o horário atual.
31
+ - `defaultFocusedDate` não tem efeito aqui.
32
+ - Não emite `touch`.
@@ -0,0 +1,32 @@
1
+ # input-date-time-span
2
+
3
+ Intervalo de data e hora: dois campos mascarados (`dd/MM/yyyy HH:mm:ss`) ou calendário de intervalo + horários inicial e
4
+ final num popover.
5
+
6
+ ## Uso
7
+
8
+ ```ts
9
+ import { InputDateTimeSpanComponent, Span } from '@schema-kit';
10
+ ```
11
+
12
+ ```html
13
+ <input-date-time-span label="Vigência" [formField]="form.vigencia" />
14
+ ```
15
+
16
+ ## Inputs
17
+
18
+ | Input | Tipo | Padrão | Descrição |
19
+ | --------------- | ------------------ | ------ | ---------------------------------- |
20
+ | `minDate` | `DateTime \| null` | `null` | Menor data aceita |
21
+ | `maxDate` | `DateTime \| null` | `null` | Maior data aceita |
22
+ | `enableSeconds` | `boolean` | `true` | `HH:mm:ss` ou `HH:mm` na digitação |
23
+
24
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../../input-base/README.md).
25
+
26
+ **Valor:** `Span | null` = `[início, fim]` em ISO com offset (timestamptz). Cada ponta pode ser `null` (intervalo aberto);
27
+ `null` quando as duas estão vazias.
28
+
29
+ ## Atenção
30
+
31
+ - Escolher a data mantém o horário daquela ponta. Sem horário, usa 00:00.
32
+ - Com `[formField]`, as duas pontas são marcadas como dirty ao mudar, para o span entrar no `extractValue({ dirty: true })`.
@@ -0,0 +1,28 @@
1
+ # input-time
2
+
3
+ Horário com máscara (`HH:MM:SS` ou `HH:MM`).
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputTimeComponent } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-time label="Abertura" [enableSeconds]="false" [formField]="form.abertura" />
13
+ ```
14
+
15
+ ## Inputs
16
+
17
+ | Input | Tipo | Padrão | Descrição |
18
+ | --------------- | --------- | ------ | ---------------------------------- |
19
+ | `enableSeconds` | `boolean` | `true` | `HH:mm:ss` ou `HH:mm` na digitação |
20
+
21
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../../input-base/README.md).
22
+
23
+ **Valor:** `string | null`, sempre `HH:mm:ss` (coluna `time` do postgres). Sem segundos, grava `:00`.
24
+
25
+ ## Atenção
26
+
27
+ - Enquanto o horário digitado está incompleto, o valor é `null`.
28
+ - Aceita na entrada `HH:mm`, `HH:mm:ss` e `HH:mm:ss.SSS`.
@@ -0,0 +1,29 @@
1
+ # input-time-span
2
+
3
+ Intervalo de horários: dois campos mascarados (`HH:MM:SS` ou `HH:MM`).
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputTimeSpanComponent, Span } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-time-span label="Expediente" [enableSeconds]="false" [formField]="form.expediente" />
13
+ ```
14
+
15
+ ## Inputs
16
+
17
+ | Input | Tipo | Padrão | Descrição |
18
+ | --------------- | --------- | ------ | ---------------------------------- |
19
+ | `enableSeconds` | `boolean` | `true` | `HH:mm:ss` ou `HH:mm` na digitação |
20
+
21
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../../input-base/README.md).
22
+
23
+ **Valor:** `Span | null` = `[início, fim]` em `HH:mm:ss`. Cada ponta pode ser `null` (intervalo aberto); `null` quando as
24
+ duas estão vazias.
25
+
26
+ ## Atenção
27
+
28
+ - Enquanto um horário está incompleto, aquela ponta é `null`.
29
+ - Com `[formField]`, as duas pontas são marcadas como dirty ao mudar, para o span entrar no `extractValue({ dirty: true })`.
@@ -0,0 +1,42 @@
1
+ # input-base
2
+
3
+ Classe base de todos os `input-*`. Não é usada no template: define as props que todos os inputs têm.
4
+
5
+ ## Uso
6
+
7
+ Ligue o input ao formulário com `[formField]` (signal forms). Ele liga valor, erros e estados:
8
+
9
+ ```html
10
+ <input-string
11
+ label="Nome"
12
+ placeholder="Seu nome"
13
+ tooltipInfo="Como aparece no perfil"
14
+ [formField]="form.nome"
15
+ [loading]="carregando()"
16
+ />
17
+ ```
18
+
19
+ Também funciona com `[(ngModel)]`, sem erros nem estados do form (ex.: [schema-table-filter](../../schema-table/schema-table-filter/schema-table-filter.component.html)).
20
+
21
+ ## Inputs comuns
22
+
23
+ | Input | Tipo | Padrão | Descrição |
24
+ | ------------- | ---------------- | ------- | ----------------------------------------------- |
25
+ | `label` | `string` | `''` | Label acima do campo. Vazio: não renderiza |
26
+ | `placeholder` | `string \| null` | `null` | Placeholder |
27
+ | `loading` | `boolean` | `false` | Skeleton por cima do campo |
28
+ | `tooltipInfo` | `string \| null` | `null` | Ícone (?) com tooltip ao lado do label |
29
+
30
+ Vêm do `[formField]`: `value`, `errors`, `invalid`, `touched`, `readonly` e `disabled`. `readonly` e `disabled` têm o
31
+ mesmo efeito: bloqueiam a edição.
32
+
33
+ ## Outputs
34
+
35
+ | Output | Tipo | Descrição |
36
+ | ------- | ------ | ---------------------------------------------------------------------------- |
37
+ | `touch` | `void` | Fim da interação (blur, seleção, limpar). O `[formField]` marca como tocado |
38
+
39
+ ## Erros
40
+
41
+ As mensagens (`message` dos validators) aparecem abaixo do campo só com `invalid && touched`. Inputs que não emitem
42
+ `touch` (indicado no README de cada um) só mostram erro depois que o campo é marcado como tocado por outro caminho.
@@ -0,0 +1,30 @@
1
+ # input-bool
2
+
3
+ Campo booleano, exibido como switch ou checkbox.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputBoolComponent, InputBoolPresentation } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-bool label="Ativo" [formField]="form.ativo" />
13
+ <input-bool label="Aceito os termos" [presentation]="InputBoolPresentation.CHECKBOX" [formField]="form.termos" />
14
+ ```
15
+
16
+ ## Inputs
17
+
18
+ | Input | Tipo | Padrão | Descrição |
19
+ | -------------- | ------------------------ | ---------- | ------------------- |
20
+ | `presentation` | `InputBoolPresentation` (`SWITCH` \| `CHECKBOX`) | `SWITCH` | Controle exibido |
21
+
22
+ Comuns (`label`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
23
+
24
+ **Valor:** `boolean | null`. `null` aparece desligado.
25
+
26
+ ## Atenção
27
+
28
+ - O `label` aparece duas vezes: acima do campo e ao lado do controle.
29
+ - Clicar em qualquer parte do campo alterna o valor.
30
+ - Não emite `touch`.
@@ -0,0 +1,24 @@
1
+ # input-color
2
+
3
+ Campo de cor hexadecimal, com swatch e um [color-picker](color-picker/README.md) num popover.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputColorComponent } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-color label="Cor" [formField]="form.cor" />
13
+ ```
14
+
15
+ ## Inputs
16
+
17
+ Só os comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
18
+
19
+ **Valor:** `string | null` no formato `#rrggbb` (minúsculo). Aceita digitar `abc`, `#abc`, `aabbcc` ou `#AABBCC`.
20
+
21
+ ## Atenção
22
+
23
+ - Texto incompleto é descartado no blur e o campo volta para o último valor válido.
24
+ - Mudar a opacidade no seletor grava `#rrggbbaa`. O input não reconhece esse formato e o swatch fica vazio.
@@ -0,0 +1,25 @@
1
+ # color-picker
2
+
3
+ Seletor de cor: área de saturação/brilho, barras de matiz e opacidade, campos em HEX, RGB, CSS ou HSL e conta-gotas
4
+ (só em navegadores Chromium). Usado dentro do [input-color](../README.md), mas funciona sozinho.
5
+
6
+ ## Uso
7
+
8
+ ```ts
9
+ import { ColorPickerComponent } from '@schema-kit';
10
+ ```
11
+
12
+ ```html
13
+ <color-picker [(ngModel)]="cor" />
14
+ ```
15
+
16
+ ## Inputs
17
+
18
+ | Input | Tipo | Padrão | Descrição |
19
+ | -------------- | ------------------------------------ | ----------- | --------------------------------------------- |
20
+ | `defaultValue` | `string` | `'#000000'` | Cor exibida enquanto o valor está vazio |
21
+ | `disabled` | `boolean` | `false` | Bloqueia a edição |
22
+ | `mode` | `'hex' \| 'rgb' \| 'css' \| 'hsl'` | `'hex'` | Formato dos campos. Aceita `[(mode)]` |
23
+
24
+ **Valor:** `#rrggbb`, ou `#rrggbbaa` quando a opacidade é menor que 100%. Aceita também `#rgb`, `#rgba`, `rgb()` e
25
+ `rgba()` na entrada.
@@ -0,0 +1,34 @@
1
+ # input-cpf-cnpj
2
+
3
+ CPF e/ou CNPJ com máscara. Aceita o CNPJ alfanumérico (padrão 2026) e converte letras para maiúsculas.
4
+
5
+ | Seletor | Máscara |
6
+ | ---------------- | ------------------------------------------------------------------------ |
7
+ | `input-cpf` | `000.000.000-00` |
8
+ | `input-cnpj` | `AA.AAA.AAA/AAAA-00` |
9
+ | `input-cpf-cnpj` | CPF; vira CNPJ quando passa de 11 caracteres ou tem letra |
10
+
11
+ ## Uso
12
+
13
+ ```ts
14
+ import { cpfValidator, InputCpfCnpjComponent } from '@schema-kit';
15
+
16
+ form = form(this.model, (schema) => {
17
+ cpfValidator(schema.cpf);
18
+ });
19
+ ```
20
+
21
+ ```html
22
+ <input-cpf label="CPF" [formField]="form.cpf" />
23
+ ```
24
+
25
+ ## Inputs
26
+
27
+ Só os comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
28
+
29
+ **Valor:** `string | null`: sem pontuação, em maiúsculas (ex.: `12345678901`).
30
+
31
+ ## Atenção
32
+
33
+ - A máscara não valida os dígitos. Use `cpfValidator`, `cnpjValidator` ou `cpfCnpjValidator` no schema do form.
34
+ - Não emite `touch` no blur.
@@ -0,0 +1,33 @@
1
+ # input-file
2
+
3
+ Seleção de um ou vários arquivos, com pré-visualização de imagens ([file-preview](../../ui/file-preview/README.md)).
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputFileComponent } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-file label="Contrato" [clearable]="true" [formField]="form.contrato" />
13
+ <input-file label="Anexos" [multiple]="true" [formField]="form.anexos" />
14
+ ```
15
+
16
+ ## Inputs
17
+
18
+ | Input | Tipo | Padrão | Descrição |
19
+ | ----------- | --------- | ------- | ----------------------------------------------------------- |
20
+ | `multiple` | `boolean` | `false` | Vários arquivos. Cada um ganha um botão de remover |
21
+ | `clearable` | `boolean` | `false` | Botão de limpar (só sem `multiple`) |
22
+
23
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
24
+
25
+ **Valor (`InputFileValue`):** recebe `string` (URL de um arquivo já salvo), `File`, `File[]` ou `FileList`. Grava `File`
26
+ (ou `File[]` com `multiple`), ou `null` quando vazio.
27
+
28
+ ## Atenção
29
+
30
+ - O componente não faz upload. O `SchemaService` envia `FormData` quando algum campo tem arquivo (lista em `campo[]`).
31
+ - Com `multiple`, uma nova seleção soma aos arquivos atuais.
32
+ - Não há `accept` nem limite de tamanho: valide no schema do form.
33
+ - O input `type` (`dropzone`) ainda não tem efeito.
@@ -0,0 +1,28 @@
1
+ # input-icon
2
+
3
+ Select de ícones [Lucide](https://lucide.dev/icons), com busca e preview.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputIconComponent } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-icon label="Ícone" placeholder="Buscar ícone" [formField]="form.icone" />
13
+
14
+ <!-- Exibindo o ícone salvo -->
15
+ <ng-icon [name]="form.icone().value()" />
16
+ ```
17
+
18
+ ## Inputs
19
+
20
+ Só os comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
21
+
22
+ **Valor:** `string | null`: o nome do ícone no `ng-icons` (ex.: `lucideHouse`).
23
+
24
+ ## Atenção
25
+
26
+ - A busca casa cada palavra com o nome (`home smile`) e exibe no máximo 60 resultados.
27
+ - O componente registra os ícones só para ele. Para exibir o valor fora dele, os ícones Lucide precisam estar registrados no
28
+ app (o [app.config.ts](../../../../../../../src/app/app.config.ts) já faz isso).
@@ -0,0 +1,36 @@
1
+ # input-json
2
+
3
+ Visualizador/editor de JSON num code block, com botões de copiar, editar e formatar.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputJsonComponent } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-json label="Payload" [formField]="form.payload" />
13
+ ```
14
+
15
+ ## Inputs
16
+
17
+ | Input | Tipo | Padrão | Descrição |
18
+ | ------ | ------------------ | -------- | ------------------------------------------------ |
19
+ | `mode` | `'view' \| 'edit'` | `'view'` | Exibição com destaque ou textarea. Aceita `[(mode)]` |
20
+
21
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
22
+
23
+ **Valor:** `string` com o texto do JSON. Formatar grava com indentação de 2 espaços.
24
+
25
+ ## Slots
26
+
27
+ - `[slot=field]`: entre o label e o code block.
28
+ - `[slot=input]`: depois do code block.
29
+
30
+ ## Atenção
31
+
32
+ - Passe o JSON como string: um objeto aparece como `[object Object]` e não formata.
33
+ - `readonly`/`disabled` não bloqueiam a edição: o botão de editar continua ativo.
34
+ - Não valida o JSON. Formatar um JSON inválido não faz nada (só `console.error`).
35
+ - O `label` aparece duas vezes: acima do campo e no título do code block.
36
+ - Não emite `touch`.
@@ -0,0 +1,39 @@
1
+ # input-mask
2
+
3
+ Campo de texto com uma máscara [Maskito](https://maskito.dev) qualquer.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputMaskComponent } from '@schema-kit';
9
+ import { MaskitoOptions } from '@maskito/core';
10
+
11
+ export class ExemploComponent {
12
+ cepMask: MaskitoOptions = { mask: [/\d/, /\d/, /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/] };
13
+ unmaskCep = (masked: string) => masked.replace(/\D/g, '') || null;
14
+ }
15
+ ```
16
+
17
+ ```html
18
+ <input-mask label="CEP" [maskitoOptions]="cepMask" [unmaskHandler]="unmaskCep" [formField]="form.cep" />
19
+ ```
20
+
21
+ No [schema-view](../../schema-view/schema-view.component.html): `FieldType.Mask` com `options.maskitoOptions` e
22
+ `options.unmaskHandler`.
23
+
24
+ ## Inputs
25
+
26
+ | Input | Tipo | Padrão | Descrição |
27
+ | ---------------- | ------------------------------------ | ------------- | -------------------------------------- |
28
+ | `maskitoOptions` | `MaskitoOptions` | (obrigatório) | Máscara |
29
+ | `unmaskHandler` | `(masked: string) => string \| null` | `undefined` | Converte o texto mascarado para o valor |
30
+
31
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
32
+
33
+ **Valor:** `string | null`: o retorno do `unmaskHandler`. Sem ele, o próprio texto mascarado.
34
+
35
+ ## Atenção
36
+
37
+ - Um valor vindo do form passa pela máscara antes de aparecer (`maskitoTransform`).
38
+ - Máscaras prontas exportadas pela lib: `maskitoOptionsCPF`, `maskitoOptionsCNPJ`, `maskitoOptionsCPFOrCNPJ`, `maskitoOptionsPhone`.
39
+ - Não emite `touch` no blur.
@@ -0,0 +1,44 @@
1
+ # input-number
2
+
3
+ Campo numérico com máscara pt-BR (`1.234,56`). O seletor define o padrão de casas decimais e prefixo:
4
+
5
+ | Seletor | Decimais | Prefixo |
6
+ | ------------------ | -------- | ------- |
7
+ | `input-number` | 0 | |
8
+ | `input-decimal` | 2 | |
9
+ | `input-currency` | 2 | `R$ ` |
10
+ | `input-percentage` | 0 | |
11
+
12
+ ## Uso
13
+
14
+ ```ts
15
+ import { InputNumberComponent } from '@schema-kit';
16
+ ```
17
+
18
+ ```html
19
+ <input-number label="Quantidade" [min]="0" [formField]="form.quantidade" />
20
+ <input-currency label="Preço" [formField]="form.preco" />
21
+ <input-decimal label="Desconto" postfix=" %" [maximumFractionDigits]="1" [formField]="form.desconto" />
22
+ ```
23
+
24
+ ## Inputs
25
+
26
+ | Input | Tipo | Padrão | Descrição |
27
+ | ----------------------- | -------- | --------------- | ----------------------------- |
28
+ | `minimumFractionDigits` | `number` | pelo seletor | Mínimo de casas decimais |
29
+ | `maximumFractionDigits` | `number` | pelo seletor | Máximo de casas decimais |
30
+ | `prefix` | `string` | pelo seletor | Texto antes do número |
31
+ | `postfix` | `string` | `''` | Texto depois do número |
32
+ | `min` | `number` | `MIN_SAFE_INTEGER` | Menor valor aceito pela máscara |
33
+ | `max` | `number` | `MAX_SAFE_INTEGER` | Maior valor aceito pela máscara |
34
+
35
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
36
+
37
+ **Valor:** `number | null`
38
+
39
+ ## Atenção
40
+
41
+ - `input-percentage` não adiciona `%` nem casas decimais. Use `input-decimal` com `postfix=" %"`.
42
+ - `min`/`max` só limitam a digitação e não geram erro. Para mostrar mensagem, use `min()`/`max()` no schema do form.
43
+ - Não emite `touch` no blur e não destaca a borda quando inválido.
44
+ - O label é sempre renderizado, mesmo vazio.
@@ -0,0 +1,25 @@
1
+ # input-phone
2
+
3
+ Telefone com máscara internacional ([@maskito/phone](https://maskito.dev/addons/phone) + `libphonenumber-js`). O número é
4
+ digitado com o código do país (`+55 11 91234-5678`).
5
+
6
+ ## Uso
7
+
8
+ ```ts
9
+ import { InputPhoneComponent } from '@schema-kit';
10
+ ```
11
+
12
+ ```html
13
+ <input-phone label="Telefone" placeholder="+55 11 91234-5678" [formField]="form.telefone" />
14
+ ```
15
+
16
+ ## Inputs
17
+
18
+ Só os comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
19
+
20
+ **Valor:** `string | null`: só dígitos e `+` (ex.: `+5511912345678`).
21
+
22
+ ## Atenção
23
+
24
+ - Não valida se o número existe. Só aplica a máscara.
25
+ - Não emite `touch` no blur.
@@ -0,0 +1,42 @@
1
+ # input-select
2
+
3
+ Select com busca (`hlm-combobox`). Os itens vêm de uma lista local, de uma Promise/Observable ou de um `SchemaService`.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputSelectComponent } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <!-- Lista local -->
13
+ <input-select label="Status" [items]="status" bindLabel="nome" bindValue="id" [formField]="form.status" />
14
+
15
+ <!-- API: busca no servidor; bindLabel/bindValue vêm do service -->
16
+ <input-select label="Usuário" [schemaService]="usuarioService" [clearable]="true" [formField]="form.usuarioId" />
17
+ ```
18
+
19
+ ## Inputs
20
+
21
+ | Input | Tipo | Padrão | Descrição |
22
+ | --------------- | ------------------------------------------------------- | ------------- | ----------------------------------------------- |
23
+ | `items` | `T[]` | `[]` | Lista local |
24
+ | `loadFrom` | `Promise \| Observable<IPaginatedResult<T>> \| SchemaService` | `null` | Fonte dos itens. Tem prioridade sobre `schemaService` |
25
+ | `schemaService` | `SchemaService` | `null` | Busca na API e define `bindLabel`/`bindValue` padrão |
26
+ | `bindLabel` | `keyof T \| (item: T) => string \| TemplateRef` | do service | Texto (ou template) de cada item |
27
+ | `bindValue` | `keyof T \| (item: T) => V` | do service | Valor gravado no form |
28
+ | `lstFilter` | `IIndexFilter[]` | `null` | Filtros enviados ao `index` (só `SchemaService`) |
29
+ | `clearable` | `boolean` | `false` | Botão de limpar |
30
+
31
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
32
+
33
+ **Valor:** `V | null`
34
+
35
+ ## Atenção
36
+
37
+ - Com `SchemaService`, a busca vai para a API (`index`, página 1, 10 itens). Nas outras fontes, a busca filtra a lista
38
+ localmente pelo label.
39
+ - A lista só recarrega quando a busca muda: trocar `items` ou `loadFrom` depois do carregamento não atualiza.
40
+ - Valor fora da lista (ex.: ao editar um registro): com `SchemaService` e valor `string`, o item é carregado com `show()`.
41
+ - O valor é comparado com `===`: o tipo tem que bater com o `bindValue` (`1` ≠ `'1'`).
42
+ - Um Observable precisa completar (é lido com `lastValueFrom`).
@@ -0,0 +1,32 @@
1
+ # input-string
2
+
3
+ Campo de texto de uma linha.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { InputStringComponent } from '@schema-kit';
9
+ ```
10
+
11
+ ```html
12
+ <input-string label="E-mail" type="email" placeholder="email@exemplo.com" [formField]="form.email" />
13
+ ```
14
+
15
+ ## Inputs
16
+
17
+ | Input | Tipo | Padrão | Descrição |
18
+ | ------ | -------------------------- | -------- | -------------------------------------------------- |
19
+ | `type` | `HTMLInputElement['type']` | `'text'` | Tipo do `<input>` nativo (`email`, `password`...) |
20
+
21
+ Comuns (`label`, `placeholder`, `loading`, `tooltipInfo`): [input-base](../input-base/README.md).
22
+
23
+ **Valor:** `string | null`
24
+
25
+ ## Slots
26
+
27
+ - `[slot=field]`: entre o label e o campo.
28
+ - `[slot=input]`: dentro do wrapper `relative` do campo (ex.: um botão sobre o input).
29
+
30
+ ## Atenção
31
+
32
+ - `type="number"` continua gravando `string`. Para números use o [input-number](../input-number/README.md).