@selectwin/kit 0.1.135 → 0.1.141

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 (39) hide show
  1. package/README.md +29 -29
  2. package/dist/SelectAssistant.d.ts +49 -0
  3. package/dist/SelectAvatar.d.ts +5 -0
  4. package/dist/SelectBreadcrumb.d.ts +16 -0
  5. package/dist/SelectBuilderWorkspace.d.ts +9 -2
  6. package/dist/SelectCard.d.ts +2 -0
  7. package/dist/SelectChannelPreview.d.ts +43 -0
  8. package/dist/SelectChoiceCard.d.ts +4 -2
  9. package/dist/SelectCombobox.d.ts +2 -1
  10. package/dist/SelectCopyRow.d.ts +2 -0
  11. package/dist/SelectDataTable.d.ts +16 -7
  12. package/dist/SelectDateField.d.ts +2 -0
  13. package/dist/SelectDetail.d.ts +7 -1
  14. package/dist/SelectField.d.ts +2 -1
  15. package/dist/SelectFileDropzone.d.ts +18 -0
  16. package/dist/SelectFilterChip.d.ts +4 -0
  17. package/dist/SelectIconPicker.d.ts +22 -0
  18. package/dist/SelectInsight.d.ts +142 -13
  19. package/dist/SelectModal.d.ts +3 -1
  20. package/dist/SelectNumberedList.d.ts +13 -0
  21. package/dist/SelectPage.d.ts +3 -0
  22. package/dist/SelectPasswordStrength.d.ts +4 -0
  23. package/dist/SelectRecordCard.d.ts +43 -2
  24. package/dist/SelectResendButton.d.ts +11 -1
  25. package/dist/SelectSearchMenu.d.ts +8 -1
  26. package/dist/SelectSegmented.d.ts +2 -0
  27. package/dist/SelectSortable.d.ts +28 -0
  28. package/dist/SelectSpotlight.d.ts +26 -2
  29. package/dist/SelectSteps.d.ts +14 -1
  30. package/dist/SelectTable.d.ts +2 -0
  31. package/dist/SelectTagSelect.d.ts +5 -0
  32. package/dist/SelectTokenTextarea.d.ts +31 -0
  33. package/dist/SelectUnitInput.d.ts +2 -0
  34. package/dist/chartUtils.d.ts +5 -0
  35. package/dist/icons.d.ts +30 -0
  36. package/dist/index.d.ts +21 -8
  37. package/dist/index.js +5933 -4471
  38. package/dist/style.css +1 -1
  39. package/package.json +64 -64
package/README.md CHANGED
@@ -1,29 +1,29 @@
1
- # @selectwin/kit
2
-
3
- Design system da Selectwin — primitivos React, charts SVG (sem dependência de biblioteca de
4
- gráficos) e tokens CSS, theme-aware (light/dark).
5
-
6
- Uso interno da Selectwin. Publicado no npm para facilitar a distribuição entre os apps da casa;
7
- não há suporte, documentação pública nem garantia de estabilidade de API para terceiros.
8
-
9
- ## Uso
10
-
11
- ```bash
12
- npm i @selectwin/kit
13
- ```
14
-
15
- ```tsx
16
- import '@selectwin/kit/styles.css'; // tokens + estilos (uma vez, no root)
17
- import { SelectButton, SelectSection } from '@selectwin/kit';
18
- ```
19
-
20
- Peer deps: **react**, **react-dom** (obrigatórios); **gsap** (opcional — só componentes animados),
21
- **react-router-dom** (opcional). Tematização = sobrescrever os tokens CSS `--select-*` / `--sw-*`.
22
-
23
- ## Build
24
-
25
- ```bash
26
- npm run build # → dist/index.js (ESM) + dist/style.css + dist/index.d.ts
27
- ```
28
-
29
- `npm publish` roda `prepublishOnly` (= build) e publica só `dist/` (sem sourcemaps).
1
+ # @selectwin/kit
2
+
3
+ Design system da Selectwin — primitivos React, charts SVG (sem dependência de biblioteca de
4
+ gráficos) e tokens CSS, theme-aware (light/dark).
5
+
6
+ Uso interno da Selectwin. Publicado no npm para facilitar a distribuição entre os apps da casa;
7
+ não há suporte, documentação pública nem garantia de estabilidade de API para terceiros.
8
+
9
+ ## Uso
10
+
11
+ ```bash
12
+ npm i @selectwin/kit
13
+ ```
14
+
15
+ ```tsx
16
+ import '@selectwin/kit/styles.css'; // tokens + estilos (uma vez, no root)
17
+ import { SelectButton, SelectSection } from '@selectwin/kit';
18
+ ```
19
+
20
+ Peer deps: **react**, **react-dom** (obrigatórios); **gsap** (opcional — só componentes animados),
21
+ **react-router-dom** (opcional). Tematização = sobrescrever os tokens CSS `--select-*` / `--sw-*`.
22
+
23
+ ## Build
24
+
25
+ ```bash
26
+ npm run build # → dist/index.js (ESM) + dist/style.css + dist/index.d.ts
27
+ ```
28
+
29
+ `npm publish` roda `prepublishOnly` (= build) e publica só `dist/` (sem sourcemaps).
@@ -0,0 +1,49 @@
1
+ import { ReactNode } from 'react';
2
+ export interface SelectAssistantSuggestion {
3
+ id: string;
4
+ label: string;
5
+ }
6
+ export interface SelectAssistantProps {
7
+ open: boolean;
8
+ onOpenChange: (open: boolean) => void;
9
+ /** O glifo do botão e do cabeçalho. */
10
+ icon: ReactNode;
11
+ title: ReactNode;
12
+ /** Linha de apoio sob o título ("Atualizado hoje às 06:00"). */
13
+ subtitle?: ReactNode;
14
+ /** Nome acessível do botão ("Perguntar ao Lince"). */
15
+ launcherLabel: string;
16
+ /** Novidades à espera: o selo do botão. `0`/ausente = sem selo. */
17
+ badge?: number;
18
+ /** As falas — `SelectChatMessage`. */
19
+ children: ReactNode;
20
+ /** Muda quando chega fala nova (o número de falas): a conversa rola até o fim. */
21
+ scrollKey?: string | number;
22
+ /** Perguntas prontas, acima do campo. */
23
+ suggestions?: ReadonlyArray<SelectAssistantSuggestion>;
24
+ onSuggestion?: (id: string) => void;
25
+ /** O texto digitado, já sem as pontas. Sem ele, a janela não tem campo. */
26
+ onSend?: (text: string) => void;
27
+ placeholder?: string;
28
+ /** Campo e sugestões desligados (lendo, sem acesso). */
29
+ disabled?: boolean;
30
+ /** Ação no cabeçalho, antes do fechar (um link para a tela cheia). */
31
+ headerAction?: ReactNode;
32
+ /** `viewport` (padrão) prende à janela do navegador; `container`, ao ancestral posicionado. */
33
+ anchor?: 'viewport' | 'container';
34
+ /** Nomes acessíveis — o padrão é pt-BR. */
35
+ closeLabel?: string;
36
+ sendLabel?: string;
37
+ inputLabel?: string;
38
+ className?: string;
39
+ }
40
+ export declare function SelectAssistant({ open, onOpenChange, icon, title, subtitle, launcherLabel, badge, children, scrollKey, suggestions, onSuggestion, onSend, placeholder, disabled, headerAction, anchor, closeLabel, sendLabel, inputLabel, className, }: SelectAssistantProps): import("react").JSX.Element;
41
+ export interface SelectChatMessageProps {
42
+ /** Quem fala: o assistente (à esquerda) ou a pessoa (à direita). */
43
+ from: 'assistant' | 'user';
44
+ /** Sem balão — a fala é um conteúdo rico que já tem a sua moldura (uma lista de achados, uma ficha). */
45
+ bare?: boolean;
46
+ children: ReactNode;
47
+ }
48
+ /** SelectChatMessage — uma fala. Texto simples vai num balão; `bare` entrega a largura toda a um conteúdo rico. */
49
+ export declare function SelectChatMessage({ from, bare, children }: SelectChatMessageProps): import("react").JSX.Element;
@@ -11,6 +11,11 @@ type SelectAvatarOwnProps = {
11
11
  size?: 'md' | 'lg';
12
12
  /** How many letters stand for the name: 1 (default) or 2 (first + last word). */
13
13
  initials?: 1 | 2;
14
+ /**
15
+ * A sigla pronta, até 3 letras ("GTM", "TikTok" → "TT") — vence o `name`. Com 3 letras a fonte encolhe para
16
+ * caber no quadrado (0.1.141).
17
+ */
18
+ monogram?: string;
14
19
  };
15
20
  export type SelectAvatarProps = SelectAvatarOwnProps & Omit<ComponentPropsWithoutRef<'span'>, keyof SelectAvatarOwnProps>;
16
21
  export declare const SelectAvatar: import('react').ForwardRefExoticComponent<SelectAvatarOwnProps & Omit<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref">, keyof SelectAvatarOwnProps> & import('react').RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1,16 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ export interface SelectBreadcrumbItem {
3
+ label: ReactNode;
4
+ /** Rota do nível (react-router). */
5
+ to?: string;
6
+ /** Alternativa ao `to` para quem navega por código. */
7
+ onAction?: () => void;
8
+ }
9
+ type SelectBreadcrumbOwnProps = {
10
+ items: SelectBreadcrumbItem[];
11
+ /** O último item é a página atual (padrão). `false` quando a trilha só tem os níveis de cima. */
12
+ lastIsCurrent?: boolean;
13
+ };
14
+ export type SelectBreadcrumbProps = SelectBreadcrumbOwnProps & Omit<ComponentPropsWithoutRef<'nav'>, keyof SelectBreadcrumbOwnProps>;
15
+ export declare const SelectBreadcrumb: import('react').ForwardRefExoticComponent<SelectBreadcrumbOwnProps & Omit<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLElement>, HTMLElement>, "ref">, keyof SelectBreadcrumbOwnProps> & import('react').RefAttributes<HTMLElement>>;
16
+ export {};
@@ -69,8 +69,15 @@ export interface SelectBuilderWorkspaceProps {
69
69
  layout?: 'rail' | 'drill' | 'single';
70
70
  /** Conteúdo da coluna da esquerda no layout `single`. */
71
71
  panel?: ReactNode;
72
- /** Largura da coluna da esquerda nos layouts `drill`/`single` (padrão 26rem). */
73
- panelWidth?: string;
72
+ /**
73
+ * Largura da coluna da esquerda nos layouts `drill`/`single` (padrão 26rem). Por faixa de tela (0.1.141):
74
+ * `{ narrow, wide }` — `narrow` de 64em a 80em (o notebook de 1024–1280px, onde um painel largo espreme o
75
+ * palco), `wide` de 80em para cima.
76
+ */
77
+ panelWidth?: string | {
78
+ narrow: string;
79
+ wide: string;
80
+ };
74
81
  /**
75
82
  * No estreito (< 64em), duas abas no topo em vez da pilha (0.1.134): [ajustes, palco] — ex.:
76
83
  * `['Ajustes', 'Prévia']`. Sem isto, a prévia fica embaixo do formulário inteiro.
@@ -4,6 +4,8 @@ type SelectCardOwnProps = {
4
4
  subtitle?: ReactNode;
5
5
  logo?: ReactNode;
6
6
  mark?: ReactNode;
7
+ /** Faixa acima do logo, no fundo do rodapé (o convite: empresa, papel, validade). */
8
+ banner?: ReactNode;
7
9
  children: ReactNode;
8
10
  footer?: ReactNode;
9
11
  };
@@ -0,0 +1,43 @@
1
+ import { ReactNode } from 'react';
2
+ /** O centro do palco: a peça no meio, com a respiração de uma folha. */
3
+ export declare function SelectPreviewStage({ children }: {
4
+ children: ReactNode;
5
+ }): import("react").JSX.Element;
6
+ /** O celular: o cabeçalho do app (o do WhatsApp verde, o do SMS com o contato no meio) e a conversa. */
7
+ export declare function SelectDeviceFrame({ variant, title, subtitle, children, }: {
8
+ variant: 'whatsapp' | 'sms';
9
+ /** Quem manda (o nome da loja; no SMS, o número ou o remetente). */
10
+ title?: string;
11
+ subtitle?: string;
12
+ children: ReactNode;
13
+ }): import("react").JSX.Element;
14
+ /**
15
+ * O balão da mensagem. `media` é o rótulo do anexo ("Imagem", "nota.pdf"); `buttons`, os botões do modelo aprovado,
16
+ * colados embaixo como o WhatsApp desenha; `empty` mostra o texto apagado (a caixa ainda vazia). `backdrop` põe o fundo
17
+ * do chat em volta — para o balão solto, fora do `SelectDeviceFrame`.
18
+ */
19
+ export declare function SelectMessageBubble({ variant, media, buttons, empty, backdrop, children, }: {
20
+ variant: 'whatsapp' | 'sms';
21
+ media?: ReactNode;
22
+ buttons?: string[];
23
+ empty?: boolean;
24
+ backdrop?: boolean;
25
+ children: ReactNode;
26
+ }): import("react").JSX.Element;
27
+ /**
28
+ * O e-mail como chega na caixa de entrada: o remetente e o assunto em cima, o corpo (`srcDoc`) num iframe da altura
29
+ * do próprio conteúdo. `loading` segura o lugar do corpo; `srcDoc` nulo não desenha o corpo (o render ainda não veio).
30
+ */
31
+ export declare function SelectMailPreview({ from, subject, emptySubject, device, srcDoc, loading, frameTitle, }: {
32
+ from?: {
33
+ name?: string;
34
+ email?: string;
35
+ };
36
+ /** O assunto — texto ou nós (o assunto com as fichas de dado). Vazio mostra `emptySubject`. */
37
+ subject?: ReactNode;
38
+ emptySubject?: string;
39
+ device?: 'desktop' | 'mobile';
40
+ srcDoc?: string | null;
41
+ loading?: boolean;
42
+ frameTitle?: string;
43
+ }): import("react").JSX.Element;
@@ -1,7 +1,9 @@
1
1
  import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
2
  export interface SelectChoiceCardProps {
3
- /** O glifo (um ícone do kit). */
4
- icon: ReactNode;
3
+ /** O glifo (um ícone do kit). Opcional com `media`. */
4
+ icon?: ReactNode;
5
+ /** Miniatura larga no topo no lugar do quadrado do ícone (o desenho da opção). */
6
+ media?: ReactNode;
5
7
  /** Cor do quadrado do ícone (hex/var). Padrão: a primária da casa. */
6
8
  accent?: string;
7
9
  title: ReactNode;
@@ -17,7 +17,8 @@ type SelectComboboxOwnProps = {
17
17
  /** Ajuda contextual: vira o "!" (SelectInfoTip) ao lado do rotulo. Use para o que
18
18
  * explica a plataforma; `hint` e so restricao/estado do proprio campo. */
19
19
  help?: ReactNode;
20
- hint?: string;
20
+ /** Embaixo do campo. Aceita nós (um link). */
21
+ hint?: ReactNode;
21
22
  error?: string;
22
23
  emptyText?: string;
23
24
  /** Disables the trigger (e.g. a field that's immutable on edit). */
@@ -8,6 +8,8 @@ type SelectCopyRowOwnProps = {
8
8
  /** Aviso ao consumidor DEPOIS da cópia (um toast, por exemplo) — a cópia em si é do
9
9
  * componente; o handler não precisa (nem deve) escrever no clipboard. */
10
10
  onCopy?: (value: string) => void;
11
+ /** Texto corrido (uma mensagem): aparece inteiro, numa caixa, com o botão "Copiar". */
12
+ prose?: boolean;
11
13
  };
12
14
  export type SelectCopyRowProps = SelectCopyRowOwnProps & Omit<ComponentPropsWithoutRef<'div'>, keyof SelectCopyRowOwnProps>;
13
15
  export declare const SelectCopyRow: import('react').ForwardRefExoticComponent<SelectCopyRowOwnProps & Omit<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof SelectCopyRowOwnProps> & import('react').RefAttributes<HTMLDivElement>>;
@@ -57,6 +57,8 @@ export interface SelectDataColumn<T> {
57
57
  /** Deixa o conteúdo QUEBRAR linha em vez de cortar com reticências — para um título com a
58
58
  * descrição embaixo (uma matriz de preferências), não para ids e valores. */
59
59
  wrap?: boolean;
60
+ /** Destaca a coluna inteira — a que está em conflito (o GTM e o pixel direto contando duas vezes). */
61
+ tone?: 'critical' | 'caution' | 'info';
60
62
  }
61
63
  /**
62
64
  * Page size the user picked for a given table (pair with `pagination.pageSizeOptions`/
@@ -65,8 +67,9 @@ export interface SelectDataColumn<T> {
65
67
  * guards mirror SelectMoney — storage unavailable = in-memory only.
66
68
  */
67
69
  export declare function useSelectPageSize(key: string, fallback: number, options?: number[]): [number, (size: number) => void];
68
- export declare function SelectDataTable<T>({ columns, items, getId, loading, empty, pagination, onRowClick, title, help, description, action, filters, columnsKey, getChildren, defaultExpanded, compactRow, compactQuery, onCompactRowClick, }: {
69
- columns: SelectDataColumn<T>[];
70
+ export declare function SelectDataTable<T>({ columns, items, getId, loading, empty, pagination, onRowClick, title, help, description, action, filters, columnsKey, getChildren, defaultExpanded, compactRow, compactQuery, onCompactRowClick, listRow, footer, }: {
71
+ /** As colunas da grade. Dispensável com `listRow` (a lista não tem colunas). */
72
+ columns?: SelectDataColumn<T>[];
70
73
  items: T[];
71
74
  getId: (item: T) => string;
72
75
  loading?: boolean;
@@ -112,9 +115,8 @@ export declare function SelectDataTable<T>({ columns, items, getId, loading, emp
112
115
  * recuadas e num fundo afundado, na MESMA grade de colunas — o `nested` da SelectTable. As
113
116
  * linhas sem filhas reservam o espaço do chevron, para a primeira coluna seguir alinhada.
114
117
  *
115
- * A linha-mãe é um <button>: as colunas não podem desenhar controle interativo nela — devolva
116
- * `null` na coluna de ações para o item-grupo. `onRowClick` vale para as outras linhas; na mãe,
117
- * o clique é o abrir/fechar. A ordenação reordena as mães entre si e as filhas dentro de cada
118
+ * Na linha-mãe o clique é o abrir/fechar (`onRowClick` vale para as outras linhas); um controle
119
+ * numa célula dela (o menu de ações) continua sendo só dele. A ordenação reordena as mães entre si e as filhas dentro de cada
118
120
  * mãe: uma filha nunca sai de baixo da sua. As filhas não têm filhas (um nível só).
119
121
  */
120
122
  getChildren?: (item: T) => T[] | null | undefined;
@@ -130,7 +132,14 @@ export declare function SelectDataTable<T>({ columns, items, getId, loading, emp
130
132
  compactRow?: (item: T) => ReactNode;
131
133
  /** Media query do modo compacto. Padrão `(max-width: 40rem)`. */
132
134
  compactQuery?: string;
133
- /** Clique na linha COMPACTA (padrão: `onRowClick`). Existe porque a linha larga costuma ter
134
- * controles nas células (copiar id, menu) e por isso não é clicável — a compacta, sem eles, é. */
135
+ /** Clique na linha COMPACTA (padrão: `onRowClick`) — para quando só a compacta é clicável. */
135
136
  onCompactRowClick?: (item: T) => void;
137
+ /**
138
+ * Lista de LINHAS RICAS em toda largura (0.1.141): cada item é o bloco que esta função desenhar (o comentário com
139
+ * as ações embaixo), na MESMA casca — título, faixa de filtros, paginação —, sem cabeçalho de colunas. Dispensa
140
+ * `columns`; o texto quebra linha. É o "modo lista" da tabela: dado com um bloco por item, não uma grade.
141
+ */
142
+ listRow?: (item: T) => ReactNode;
143
+ /** Uma linha discreta embaixo das linhas, antes da paginação ("Os 20 mais recentes de 300"). */
144
+ footer?: ReactNode;
136
145
  }): import("react").JSX.Element;
@@ -14,6 +14,8 @@ export interface SelectDateFieldProps {
14
14
  maxDate?: Date | null;
15
15
  /** Offer a "Limpar" action that empties the field (default true). */
16
16
  clearable?: boolean;
17
+ /** Em que grade o calendário abre quando o campo está vazio: `year` para data longe (nascimento). */
18
+ openTo?: 'day' | 'year';
17
19
  id?: string;
18
20
  }
19
21
  export declare const SelectDateField: import('react').ForwardRefExoticComponent<SelectDateFieldProps & Omit<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof SelectDateFieldProps> & import('react').RefAttributes<HTMLDivElement>>;
@@ -1,7 +1,13 @@
1
1
  import { ReactNode, ComponentPropsWithoutRef } from 'react';
2
- export declare function SelectDetailList({ children, stacked, loading, }: {
2
+ export declare function SelectDetailList({ children, stacked, compact, loading, }: {
3
3
  children: ReactNode;
4
4
  stacked?: boolean;
5
+ /**
6
+ * A tabelinha do CORPO de um card ("Pix 0,99% · Boleto R$ 2,89"): rótulo apagado à esquerda,
7
+ * valor à direita em números tabulares, linhas mais baixas — sem a coluna fixa de 9rem, que num
8
+ * card estreito espreme o valor.
9
+ */
10
+ compact?: boolean;
5
11
  /** Shimmer every row's value. The labels stay — only the values are unknown. */
6
12
  loading?: boolean;
7
13
  }): import("react").JSX.Element;
@@ -31,7 +31,8 @@ export interface SelectFieldProps {
31
31
  /** Helper text shown under the label, ABOVE the input (Clerk "Key" pattern). */
32
32
  description?: ReactNode;
33
33
  /** Helper text below the field (hidden when `error` is set). */
34
- hint?: string;
34
+ /** Restrição/estado do campo, embaixo dele. Aceita nós (um link: "abrir no fluxograma"). */
35
+ hint?: ReactNode;
35
36
  /** Validation message below the field; also flips the input to its error style. */
36
37
  error?: string;
37
38
  /** Static text/icon inside the field, left of the value (e.g. "R$", "https://"). */
@@ -9,5 +9,23 @@ export interface SelectFileDropzoneProps {
9
9
  /** Optional cap on the number of files; hides the add tile once reached. */
10
10
  maxFiles?: number;
11
11
  hint?: string;
12
+ /**
13
+ * Câmera direta num aparelho de toque: `user` (a da frente — a selfie) ou `environment` (a de trás —
14
+ * o documento). A zona vazia vira dois botões: a câmera e o seletor de arquivos. No computador, nada muda.
15
+ */
16
+ capture?: 'user' | 'environment';
17
+ /** O botão da câmera (padrão "Fotografar"). */
18
+ captureLabel?: string;
19
+ /** O botão do arquivo ao lado da câmera (padrão "Escolher arquivo"). */
20
+ pickLabel?: string;
21
+ /**
22
+ * Prepara cada arquivo ANTES do teto e do `accept` (reduzir a foto grande no navegador, converter o
23
+ * HEIC). Lançar um `Error` recusa o arquivo, e a mensagem dele é a frase que aparece.
24
+ */
25
+ prepare?: (file: File) => Promise<File>;
26
+ /** `vertical`: glifo em cima, texto embaixo, numa zona mais alta. Padrão `inline`. */
27
+ layout?: 'inline' | 'vertical';
28
+ /** Na zona vertical, a linha principal (padrão "Arraste o arquivo ou clique para escolher"); o `hint` vem embaixo. */
29
+ label?: string;
12
30
  }
13
31
  export declare const SelectFileDropzone: import('react').ForwardRefExoticComponent<SelectFileDropzoneProps & Omit<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof SelectFileDropzoneProps> & import('react').RefAttributes<HTMLDivElement>>;
@@ -3,6 +3,10 @@ type SelectFilterChipOwnProps = {
3
3
  children: ReactNode;
4
4
  onClick?: () => void;
5
5
  active?: boolean;
6
+ /** Chip de escolha: um filtro entre irmãos, sem o "+" de "adicionar filtro". */
7
+ toggle?: boolean;
8
+ /** Quantos itens o filtro tem — ao lado do rótulo, mais discreto. */
9
+ count?: number;
6
10
  };
7
11
  export type SelectFilterChipProps = SelectFilterChipOwnProps & Omit<ComponentPropsWithoutRef<'button'>, keyof SelectFilterChipOwnProps>;
8
12
  export declare const SelectFilterChip: import('react').ForwardRefExoticComponent<SelectFilterChipOwnProps & Omit<Omit<import('react').DetailedHTMLProps<import('react').ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, keyof SelectFilterChipOwnProps> & import('react').RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,22 @@
1
+ import { ReactNode } from 'react';
2
+ export interface SelectIconOption {
3
+ value: string;
4
+ label: string;
5
+ /** O glifo, como elemento (`<TruckIcon />`). */
6
+ icon: ReactNode;
7
+ }
8
+ export declare function SelectIconPicker({ label, options, value, onChange, help, hint, error, disabled, unknownLabel, placeholder, columns, }: {
9
+ label?: string;
10
+ options: SelectIconOption[];
11
+ value: string;
12
+ onChange: (value: string) => void;
13
+ help?: ReactNode;
14
+ hint?: string;
15
+ error?: string;
16
+ disabled?: boolean;
17
+ /** O nome do valor gravado que não está nas opções. */
18
+ unknownLabel?: string;
19
+ placeholder?: string;
20
+ /** Ícones por linha na grade. Padrão 6. */
21
+ columns?: number;
22
+ }): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
- import { ReactNode } from 'react';
2
- /** Um valor do achado: `display` para ler, `raw` para gráfico/ordenação (percentual em fração, dinheiro em centavos). */
1
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ /** Um valor do ponto: `display` para ler, `raw` para desenhar/ordenar (percentual em fração, dinheiro em centavos). */
3
3
  export interface SelectInsightValue {
4
4
  type: string;
5
5
  raw: number | string | readonly string[];
@@ -26,6 +26,8 @@ export type SelectInsightBlock = {
26
26
  baseline: SelectInsightValue;
27
27
  baselineLabel: string;
28
28
  hint: string | null;
29
+ /** De quem é o `value` ("Sua empresa", "Este anúncio"). Sem ele, a linha do valor leva o próprio `label`. */
30
+ valueLabel?: string | null;
29
31
  } | {
30
32
  type: 'table';
31
33
  title: string;
@@ -47,13 +49,28 @@ export interface SelectInsightAction {
47
49
  /** Destino estável (`guide:utm`, `product:prd_…`) ou `null` — conselho sem tela. */
48
50
  target: string | null;
49
51
  }
50
- /** O achado como o node o entrega. Campos a mais (id, status, score…) passam sem atrapalhar. */
52
+ /** Para onde uma ação leva: vira o botão da ação ("Ver o passo a passo ›", "Criar cupom ›"). */
53
+ export interface SelectInsightActionLink {
54
+ /** O verbo do botão ("Ver o passo a passo", "Criar cupom"). */
55
+ label: string;
56
+ /** O que acontece ao seguir a ação — uma frase, sob o título dela em "O que fazer agora". */
57
+ description?: string;
58
+ href?: string;
59
+ /** Navegação do próprio app (router): o clique comum é interceptado; o do meio segue o `href`. */
60
+ onClick?: () => void;
61
+ /** Abre em outra aba (suporte, documentação). */
62
+ external?: boolean;
63
+ }
64
+ /** O ponto como o node o entrega. Campos a mais (id, status, score…) passam sem atrapalhar. */
51
65
  export interface SelectInsightData {
52
66
  title: string;
53
67
  summary: string;
54
68
  severity: string;
55
69
  confidence?: string | null;
56
70
  sampleSize?: number | null;
71
+ /** A amostra com o que ela conta, já traduzida pelo node ("136 compras no cartão analisadas"). Vence o
72
+ * "amostra de N" montado aqui com o `sampleSize`. */
73
+ sampleLabel?: string | null;
57
74
  kind?: string | null;
58
75
  domain?: string | null;
59
76
  impact?: {
@@ -77,43 +94,155 @@ export interface SelectInsightLabels {
77
94
  severity: Record<string, string>;
78
95
  kind: Record<string, string>;
79
96
  domain: Record<string, string>;
97
+ /** A frase inteira ("Confiança alta") — a primeira parte da linha de "como o Lince chegou a esse número". */
80
98
  confidence: Record<string, string>;
81
99
  sample: (n: string) => string;
100
+ /** As duas pontas já formatadas ("12/09", "10/10") → "de 12/09 a 10/10". */
101
+ periodRange: (start: string, end: string) => string;
102
+ /** Período de horas dentro de um dia (um alerta: "as últimas 6 h") → "em 03/10, das 08:00 às 14:00". */
103
+ periodSameDay: (day: string, from: string, to: string) => string;
82
104
  /** A faixa já formatada ("R$ 2.038 a R$ 3.962") → a frase do impacto. */
83
105
  impact: (range: string) => string;
84
106
  /** Impacto com mínimo = máximo — ainda é estimativa, então nunca um número seco. */
85
107
  impactAbout: (value: string) => string;
108
+ /** O mesmo "cerca de", sem o resto da frase — o número do bloco de impacto. */
109
+ about: (value: string) => string;
86
110
  rangeJoin: string;
111
+ /** "até" — antes do teto da faixa, na linha da fila. */
112
+ upTo: string;
113
+ /** "para recuperar" — depois do teto, no card do celular. */
114
+ toRecover: string;
115
+ impactLabel: string;
116
+ impactNote: string;
117
+ /** O rótulo do destaque da primeira ação. */
118
+ actionsNow: string;
119
+ /** O título das outras ações, sob a primeira. */
120
+ actionsMore: string;
121
+ /** O título da evidência. */
122
+ evidence: string;
123
+ /** O título do histórico do número, em "Entenda os números". */
124
+ trend: string;
87
125
  methodology: string;
88
- actions: string;
126
+ /** O selo do ponto travado ("Lince Pro" no painel; aqui, o genérico). */
89
127
  locked: string;
128
+ lockedImpactLabel: string;
129
+ lockedImpactNote: string;
130
+ unread: string;
90
131
  }
91
- /** "R$ 2.038 a R$ 3.962" — em reais inteiros: é estimativa, centavo seria falsa precisão. */
92
- export declare function formatInsightImpact(impact: {
132
+ type Impact = {
93
133
  currency: string;
94
134
  minCents: number;
95
135
  maxCents: number;
96
- }, locale?: string, labels?: Pick<SelectInsightLabels, 'impact' | 'impactAbout' | 'rangeJoin'>): string;
136
+ };
137
+ type ImpactLabels = Pick<SelectInsightLabels, 'impact' | 'impactAbout' | 'rangeJoin'>;
138
+ /** "R$ 2.038 a R$ 3.962 para recuperar" — a frase inteira do impacto, para quem a escreve num texto. */
139
+ export declare function formatInsightImpact(impact: Impact, locale?: string, labels?: ImpactLabels): string;
140
+ /**
141
+ * O retorno de quem marcou o ponto como feito (0.1.139): o antes e o depois que o Lince mede depois do "feito". O
142
+ * consumidor escreve as palavras (o veredito, a data); o card desenha o quadro no tom do veredito.
143
+ */
144
+ export interface SelectInsightOutcome {
145
+ /** `success` melhorou · `warning` piorou · `neutral` sem conclusão, ou ainda a medir. */
146
+ tone: 'success' | 'warning' | 'neutral';
147
+ /** A linha de cima ("O resultado · Melhorou", "A medir em 29/09"). */
148
+ label: ReactNode;
149
+ /** A frase que resume ("Pix pagos: 58% antes, 72% depois."). */
150
+ summary?: ReactNode;
151
+ /** Os dois lados, já formatados. Sem `after`, ainda não há o depois. */
152
+ before?: {
153
+ label: ReactNode;
154
+ value: ReactNode;
155
+ } | null;
156
+ after?: {
157
+ label: ReactNode;
158
+ value: ReactNode;
159
+ } | null;
160
+ /** A ressalva ("Antes e depois não provam a causa…"). */
161
+ note?: ReactNode;
162
+ }
97
163
  export interface SelectInsightProps {
98
164
  insight: SelectInsightData;
99
- /** Os rótulos do card. O TEXTO do achado já vem traduzido pelo node — passe a mesma língua que pediu a ele. */
165
+ /** Os rótulos do card. O TEXTO do ponto já vem traduzido pelo node — passe a mesma língua que pediu a ele. */
100
166
  locale?: string;
101
167
  labels?: Partial<SelectInsightLabels>;
102
168
  /** Fuso do período (o calendário do Lince é o de São Paulo). */
103
169
  timeZone?: string;
104
- /** A isca do plano: só título, resumo e impacto, esmaecidos, com o `lockedCta`. */
170
+ /** A isca do plano: título, resumo e o impacto em destaque, a evidência como silhueta, e o `lockedCta`. */
105
171
  locked?: boolean;
106
172
  lockedCta?: ReactNode;
107
- /** Selos a mais no cabeçalho (no console: o estado do achado, o "o lojista vê travado"). */
173
+ /** Onde o ponto está na fila ("1 de 5") — uma pílula antes da severidade. */
174
+ position?: ReactNode;
175
+ /** O leitor ainda não abriu este ponto: o marcador "Novo" ao lado do domínio. */
176
+ unread?: boolean;
177
+ /** Selos a mais no cabeçalho (no console: o estado do ponto, o "o lojista vê travado"). */
108
178
  badges?: ReactNode;
179
+ /** Controles à direita do cabeçalho — "Anterior" e "Próximo", na ficha ao lado da fila. */
180
+ nav?: ReactNode;
181
+ /**
182
+ * O que o leitor faz com o ponto ("Já resolvi", "Agora não"). No largo mora ao lado do botão da ação, em "O que
183
+ * fazer agora"; no estreito desce para o pé do card, na largura toda.
184
+ */
185
+ triage?: ReactNode;
186
+ /** A frase que explica a triagem ("'Agora não' tira este ponto da lista por 30 dias."). */
187
+ triageNote?: ReactNode;
109
188
  /** Linha a mais no pé do card (no console: o `subjectKey`). */
110
189
  footer?: ReactNode;
190
+ /**
191
+ * Como o número principal evoluiu (o histórico do ponto): o gráfico desenhado pelo consumidor (`content`) e uma
192
+ * linha que o resume (`caption`: "De 58% em 01/10 para 62% em 03/10."). Vai em "Entenda os números", depois dos
193
+ * quadros. Sem ele, nada aparece.
194
+ */
195
+ trend?: {
196
+ content: ReactNode;
197
+ caption?: ReactNode;
198
+ };
199
+ /** O resultado do "feito" (o antes e o depois) — logo depois do resumo, porque é o retorno que o leitor esperava. */
200
+ outcome?: SelectInsightOutcome;
111
201
  /** O rótulo de um item virado link quando houver tela (`product` + `prd_…`). `undefined` = só o texto. */
112
202
  renderItem?: (item: SelectInsightItem) => ReactNode | undefined;
113
- /** Uma ação virada link/botão pelo `target`. `undefined` = só o texto. */
203
+ /** O destino de uma ação: vira o botão dela. `undefined` = conselho, sem botão. */
204
+ actionLink?: (action: SelectInsightAction) => SelectInsightActionLink | undefined;
205
+ /** Uma ação desenhada pelo consumidor (anterior ao `actionLink`, que é o caminho da casa). */
114
206
  renderAction?: (action: SelectInsightAction) => ReactNode | undefined;
115
- /** "Como calculamos" aberto de saída. */
207
+ /** "Como o Lince chegou a esse número" aberto de saída. */
116
208
  methodologyOpen?: boolean;
209
+ /** Sem a casca de card (borda, fundo, respiro) — o ponto dentro de outro card ou de uma conversa. */
210
+ bare?: boolean;
117
211
  className?: string;
118
212
  }
119
- export declare function SelectInsight({ insight, locale, labels: labelsOverride, timeZone, locked, lockedCta, badges, footer, renderItem, renderAction, methodologyOpen, className, }: SelectInsightProps): import("react").JSX.Element;
213
+ export declare function SelectInsight({ insight, locale, labels: labelsOverride, timeZone, locked, lockedCta, position, unread, badges, nav, triage, triageNote, footer, trend, outcome, renderItem, actionLink, renderAction, methodologyOpen, bare, className, }: SelectInsightProps): import("react").JSX.Element;
214
+ type SelectInsightListOwnProps = {
215
+ /** `rows` (padrão): as linhas da fila; `cards`: os cartões do celular, com mais ar entre eles. */
216
+ layout?: 'rows' | 'cards';
217
+ children: ReactNode;
218
+ };
219
+ export type SelectInsightListProps = SelectInsightListOwnProps & Omit<ComponentPropsWithoutRef<'div'>, keyof SelectInsightListOwnProps>;
220
+ /** SelectInsightList — a fila de `SelectInsightRow`. Dentro de uma `SelectSection`, as linhas encostam na borda do corpo. */
221
+ export declare function SelectInsightList({ layout, children, className, ...rest }: SelectInsightListProps): import("react").JSX.Element;
222
+ type SelectInsightRowOwnProps = {
223
+ insight: Pick<SelectInsightData, 'title' | 'severity' | 'kind' | 'domain' | 'impact'>;
224
+ locale?: string;
225
+ labels?: Partial<SelectInsightLabels>;
226
+ /** A posição na fila (1, 2, 3…): o número que diz por onde começar. */
227
+ index?: number;
228
+ /** A isca do plano: cadeado no lugar do número. */
229
+ locked?: boolean;
230
+ /** O marcador "Novo" — o leitor ainda não abriu. */
231
+ unread?: boolean;
232
+ /** A linha aberta na ficha ao lado. */
233
+ selected?: boolean;
234
+ /** `row` (padrão) é a linha da fila; `card` é o cartão do celular, com o impacto e a chamada no pé. */
235
+ layout?: 'row' | 'card';
236
+ /** A chamada do cartão ("Resolver", "Ver o que fazer"). */
237
+ cta?: ReactNode;
238
+ /** Um selo a mais na linha de baixo (o veredito do "feito", na lista dos resolvidos). */
239
+ badge?: ReactNode;
240
+ };
241
+ export type SelectInsightRowProps = SelectInsightRowOwnProps & Omit<ComponentPropsWithoutRef<'a'>, keyof SelectInsightRowOwnProps | 'title'>;
242
+ /**
243
+ * SelectInsightRow — um ponto numa linha: o número da fila, o título, a severidade com o domínio e o teto do
244
+ * impacto ("até R$ 4.360"). É um link (`href` + `onClick` do router de quem usa); sem os dois, é só a linha.
245
+ * `selected` marca a que está aberta ao lado.
246
+ */
247
+ export declare function SelectInsightRow({ insight, locale, labels: labelsOverride, index, locked, unread, selected, layout, cta, badge, href, onClick, className, ...rest }: SelectInsightRowProps): import("react").JSX.Element;
248
+ export {};
@@ -1,7 +1,9 @@
1
1
  import { ReactNode } from 'react';
2
- export declare function SelectModal({ open, onClose, title, subtitle, children, footer, aside, size, showClose, noise, dividedHeader, backdrop, theme, placement, }: {
2
+ export declare function SelectModal({ open, onClose, eyebrow, title, subtitle, children, footer, aside, size, showClose, noise, dividedHeader, backdrop, theme, placement, }: {
3
3
  open: boolean;
4
4
  onClose: () => void;
5
+ /** Uma linha de contexto acima do título ("Passo a passo · ponto 1 de 5"). */
6
+ eyebrow?: ReactNode;
5
7
  title?: ReactNode;
6
8
  subtitle?: ReactNode;
7
9
  children?: ReactNode;
@@ -0,0 +1,13 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ export type SelectNumberedListProps = Omit<ComponentPropsWithoutRef<'ol'>, 'children'> & {
3
+ children: ReactNode;
4
+ };
5
+ export declare function SelectNumberedList({ children, className, ...rest }: SelectNumberedListProps): import("react").JSX.Element;
6
+ type SelectNumberedItemOwnProps = {
7
+ /** Uma linha em destaque ("Analisa todo dia às 06:00"). */
8
+ title?: ReactNode;
9
+ children?: ReactNode;
10
+ };
11
+ export type SelectNumberedItemProps = SelectNumberedItemOwnProps & Omit<ComponentPropsWithoutRef<'li'>, keyof SelectNumberedItemOwnProps>;
12
+ export declare function SelectNumberedItem({ title, children, className, ...rest }: SelectNumberedItemProps): import("react").JSX.Element;
13
+ export {};