@rendra-ui/web 2.8.0 → 2.9.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 +3 -3
- package/dist/base.css +1 -1
- package/dist/{button-CrSlVIsY.js → button-BcCBrlnt.js} +6 -6
- package/dist/{button-CrSlVIsY.js.map → button-BcCBrlnt.js.map} +1 -1
- package/dist/chart.js +7 -7
- package/dist/cli/auditar.js +1 -1
- package/dist/cli/codigos.js +2 -2
- package/dist/cli/executar-auditar.js +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/trocar.js +2 -2
- package/dist/cli/typescript-loader.js +1 -1
- package/dist/{cn-BlJHpkDs.js → cn-CpdCvlkP.js} +2 -2
- package/dist/{cn-BlJHpkDs.js.map → cn-CpdCvlkP.js.map} +1 -1
- package/dist/{components-6RpoJ2Od.js → components-Bus_Jh2R.js} +7 -4
- package/dist/components-Bus_Jh2R.js.map +1 -0
- package/dist/components.css +67 -26
- package/dist/document-viewer.js +4 -4
- package/dist/{dropdown-menu-BUGKtR6k.js → dropdown-menu-B3L1XSDf.js} +5 -5
- package/dist/{dropdown-menu-BUGKtR6k.js.map → dropdown-menu-B3L1XSDf.js.map} +1 -1
- package/dist/{brand-feedback-icon-CVux4pNh.js → empty-state-Bcx4M0Me.js} +64 -4
- package/dist/empty-state-Bcx4M0Me.js.map +1 -0
- package/dist/{features-max-BCIy1Ic-.js → features-max-CoyJ_kuK.js} +1 -1
- package/dist/flow.js +2818 -868
- package/dist/flow.js.map +1 -1
- package/dist/index.js +80 -465
- package/dist/index.js.map +1 -1
- package/dist/{motion-context-PJPj6X4g.js → motion-context-DWFl2xRr.js} +4 -4
- package/dist/{motion-context-PJPj6X4g.js.map → motion-context-DWFl2xRr.js.map} +1 -1
- package/dist/{motion-on-Bocf4Smc.js → motion-on-zwsBqYZL.js} +2 -2
- package/dist/{motion-on-Bocf4Smc.js.map → motion-on-zwsBqYZL.js.map} +1 -1
- package/dist/motion.js +2 -2
- package/dist/{rendra-provider-Do_qWjJC.js → rendra-provider-DuIhBatD.js} +3 -3
- package/dist/{rendra-provider-Do_qWjJC.js.map → rendra-provider-DuIhBatD.js.map} +1 -1
- package/dist/rich-text-editor.js +4 -4
- package/dist/router-bridge.js +2 -2
- package/dist/{timeline-xrMHeV92.js → toast-C7qYslCp.js} +464 -80
- package/dist/toast-C7qYslCp.js.map +1 -0
- package/dist/tokens.css +1 -1
- package/dist/{tooltip-to0h6aPe.js → tooltip-BSPO-bH4.js} +5 -5
- package/dist/{tooltip-to0h6aPe.js.map → tooltip-BSPO-bH4.js.map} +1 -1
- package/dist/types/components/ui/flow-config-panels.d.ts +10 -0
- package/dist/types/components/ui/flow-editor.d.ts +5 -0
- package/dist/types/components/ui/flow-sidebar.d.ts +21 -0
- package/dist/types/components/ui/flow-simulation-panel.d.ts +20 -0
- package/dist/types/components/ui/flow-viewer.d.ts +27 -10
- package/dist/types/flow.d.ts +1 -1
- package/dist/types/lib/flow-blocks.d.ts +122 -0
- package/dist/types/lib/flow-edit.d.ts +88 -0
- package/dist/types/lib/flow-layout.d.ts +3 -0
- package/dist/types/lib/flow-sim.d.ts +24 -0
- package/dist/types/lib/flow.d.ts +30 -80
- package/dist/{use-breakpoint-CM-yeDHJ.js → use-breakpoint-BGmY3ir-.js} +2 -2
- package/dist/{use-breakpoint-CM-yeDHJ.js.map → use-breakpoint-BGmY3ir-.js.map} +1 -1
- package/dist/{use-motion-presets-I4StrsCi.js → use-motion-presets-CmMLBQLI.js} +3 -3
- package/dist/{use-motion-presets-I4StrsCi.js.map → use-motion-presets-CmMLBQLI.js.map} +1 -1
- package/dist/widget-grid.js +2 -2
- package/package.json +2 -1
- package/dist/brand-feedback-icon-CVux4pNh.js.map +0 -1
- package/dist/components-6RpoJ2Od.js.map +0 -1
- package/dist/empty-state-i4e-LacG.js +0 -67
- package/dist/empty-state-i4e-LacG.js.map +0 -1
- package/dist/timeline-xrMHeV92.js.map +0 -1
|
@@ -10,39 +10,56 @@ export interface FlowBlockData extends Record<string, unknown> {
|
|
|
10
10
|
issues: string[];
|
|
11
11
|
/** Bloco que a simulação executa agora. */
|
|
12
12
|
active: boolean;
|
|
13
|
-
/** Alças grandes (montar com mouse ou toque) ou discretas (só ver). */
|
|
14
|
-
handles: 'lg' | 'sm';
|
|
15
|
-
/** Mostra o botão "Editar bloco" dentro do bloco. */
|
|
16
|
-
edit: boolean;
|
|
17
13
|
}
|
|
18
14
|
export type FlowRfNode = Node<FlowBlockData, 'bloco'>;
|
|
15
|
+
/** O que o card e a ligação podem pedir ao editor. No viewer não há nada (contexto nulo). */
|
|
16
|
+
export interface FlowActions {
|
|
17
|
+
play: (id: string) => void;
|
|
18
|
+
edit?: (id: string) => void;
|
|
19
|
+
remove?: (id: string) => void;
|
|
20
|
+
/** Só com montagem liberada: a lixeira da ligação selecionada. */
|
|
21
|
+
removeEdge?: (id: string) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare const FlowActionsContext: import("react").Context<FlowActions | null>;
|
|
24
|
+
/** Raio de atração das alças em px: menor que o padrão da biblioteca (20), para não ligar sozinho. */
|
|
25
|
+
export declare const CONNECTION_RADIUS = 12;
|
|
19
26
|
export declare const FLOW_ICON: Record<FlowNodeType, ComponentType<{
|
|
20
27
|
className?: string;
|
|
21
28
|
}>>;
|
|
29
|
+
/** Cor do ícone do bloco, por grupo (também usada na barra de blocos). */
|
|
30
|
+
export declare const flowTone: (type: FlowNodeType) => string;
|
|
22
31
|
/** Os textos que a biblioteca escreve no DOM (leitor de tela), em português. */
|
|
23
32
|
export declare const FLOW_ARIA: Partial<AriaLabelConfig>;
|
|
24
33
|
interface RfNodeOptions {
|
|
25
34
|
activeId?: string | null;
|
|
26
35
|
issues?: FlowIssue[];
|
|
27
|
-
handles: 'lg' | 'sm';
|
|
28
|
-
edit: boolean;
|
|
29
36
|
}
|
|
30
37
|
/** Os blocos do Rendra como nós do React Flow (a biblioteca só vê isto). */
|
|
31
|
-
export declare function toRfNodes(flow: Flow, opts
|
|
38
|
+
export declare function toRfNodes(flow: Flow, opts?: RfNodeOptions): FlowRfNode[];
|
|
39
|
+
export interface FlowEdgeData extends Record<string, unknown> {
|
|
40
|
+
/** Rótulo da regra na ligação ("> 500", "Senão"); `null` fora da condição. */
|
|
41
|
+
label: string | null;
|
|
42
|
+
from: string;
|
|
43
|
+
to: string;
|
|
44
|
+
}
|
|
32
45
|
/** As ligações do Rendra como arestas do React Flow, com a descrição em português. */
|
|
33
|
-
export declare function toRfEdges(flow: Flow): Edge[];
|
|
46
|
+
export declare function toRfEdges(flow: Flow): Edge<FlowEdgeData>[];
|
|
34
47
|
/** Aproximar, afastar e enquadrar, com 44 px de toque (os botões da biblioteca têm 26 px). */
|
|
35
48
|
export declare function FlowZoomControls(): import("react").JSX.Element;
|
|
49
|
+
/** Zoom mínimo do enquadramento inicial: abaixo disso os cards e as alças ficam ilegíveis e pequenos demais. */
|
|
50
|
+
export declare const MIN_FIT_ZOOM = 0.5;
|
|
36
51
|
export interface FlowSurfaceProps extends ReactFlowProps<FlowRfNode, Edge> {
|
|
37
52
|
children?: ReactNode;
|
|
53
|
+
/** Falso quando o contêiner de fora já dá a altura (o FlowEditor): o canvas só o preenche. */
|
|
54
|
+
fill?: boolean;
|
|
38
55
|
}
|
|
39
56
|
/**
|
|
40
57
|
* O canvas: contêiner com a altura que sobra na tela (`h-board`), tema pelos tokens e a
|
|
41
58
|
* biblioteca por dentro. A rolagem horizontal é do canvas (`data-allow-overflow`), nunca da página.
|
|
42
59
|
*/
|
|
43
|
-
export declare function FlowSurface({ className, children, ...props }: FlowSurfaceProps): import("react").JSX.Element;
|
|
60
|
+
export declare function FlowSurface({ className, children, fill, ...props }: FlowSurfaceProps): import("react").JSX.Element;
|
|
44
61
|
export interface FlowViewerProps {
|
|
45
|
-
/** O fluxo a mostrar (o mesmo JSON do FlowEditor). */
|
|
62
|
+
/** O fluxo a mostrar (o mesmo JSON do FlowEditor; o da 2.7.0 também abre). */
|
|
46
63
|
value: Flow;
|
|
47
64
|
/** Bloco destacado (por exemplo, o passo que a simulação está executando). */
|
|
48
65
|
activeId?: string | null;
|
package/dist/types/flow.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { FlowEditor, type FlowEditorProps } from './components/ui/flow-editor';
|
|
2
2
|
export { FlowViewer, type FlowViewerProps } from './components/ui/flow-viewer';
|
|
3
|
-
export { parseFlow, serializeFlow, validateFlow, type Flow, type FlowBranch, type FlowEdge, type FlowIssue, type FlowNode, type FlowNodeType, type ParseResult, } from './lib/flow';
|
|
3
|
+
export { parseFlow, serializeFlow, validateFlow, type Flow, type FlowBranch, type FlowEdge, type FlowIssue, type FlowNode, type FlowNodeType, type FlowRule, type FlowRuleOperator, type ParseResult, } from './lib/flow';
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { Flow, FlowEdge, FlowNode, FlowNodeType, FlowRule, FlowRuleOperator, FlowWaitUnit } from './flow';
|
|
2
|
+
/** Largura do card do bloco em px (igual a `w-flow-node`, 21rem). */
|
|
3
|
+
export declare const FLOW_CARD_W = 336;
|
|
4
|
+
export declare const FLOW_GAP_X = 96;
|
|
5
|
+
export declare const FLOW_GAP_Y = 32;
|
|
6
|
+
export declare const FLOW_WAIT_UNITS: readonly FlowWaitUnit[];
|
|
7
|
+
/** A duração do bloco de espera ("5 minutos"), ou `null` se o config não a define. */
|
|
8
|
+
export declare function formatWait(config: Record<string, unknown> | undefined): string | null;
|
|
9
|
+
/** Texto da espera simulada: nunca espera de verdade. */
|
|
10
|
+
export declare function describeWait(config: Record<string, unknown> | undefined): string;
|
|
11
|
+
export type FlowBlockGroupId = 'gatilhos' | 'mensagens' | 'condicionais' | 'integracoes' | 'acoes';
|
|
12
|
+
export interface FlowBlockDef {
|
|
13
|
+
type: FlowNodeType;
|
|
14
|
+
group: FlowBlockGroupId;
|
|
15
|
+
name: string;
|
|
16
|
+
/** Texto curto do card. */
|
|
17
|
+
description: string;
|
|
18
|
+
/** Dica usada na busca da barra de blocos. */
|
|
19
|
+
hint: string;
|
|
20
|
+
defaultConfig: () => Record<string, unknown>;
|
|
21
|
+
/** Campos de `config` que não podem ficar vazios. */
|
|
22
|
+
required: {
|
|
23
|
+
key: string;
|
|
24
|
+
label: string;
|
|
25
|
+
}[];
|
|
26
|
+
/** Fora da barra de blocos (tipos legados). */
|
|
27
|
+
hidden?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare const FLOW_BLOCKS: Record<FlowNodeType, FlowBlockDef>;
|
|
30
|
+
export declare const FLOW_BLOCK_GROUPS: {
|
|
31
|
+
id: FlowBlockGroupId;
|
|
32
|
+
name: string;
|
|
33
|
+
types: FlowNodeType[];
|
|
34
|
+
}[];
|
|
35
|
+
/** Nome do tipo de bloco, como aparece na interface. */
|
|
36
|
+
export declare const FLOW_TYPE_NAME: Record<FlowNodeType, string>;
|
|
37
|
+
/** Gatilho é todo bloco do grupo Gatilhos (inclui o legado `gatilho`). */
|
|
38
|
+
export declare const isTrigger: (type: FlowNodeType) => boolean;
|
|
39
|
+
export declare const FLOW_SYSTEM_FIELDS: {
|
|
40
|
+
value: string;
|
|
41
|
+
label: string;
|
|
42
|
+
}[];
|
|
43
|
+
/** O JSON de exemplo que "chega" no Receber webhook (simulado). */
|
|
44
|
+
export declare const FLOW_SAMPLE_PAYLOAD: {
|
|
45
|
+
cliente: {
|
|
46
|
+
nome: string;
|
|
47
|
+
email: string;
|
|
48
|
+
telefone: string;
|
|
49
|
+
plano: string;
|
|
50
|
+
};
|
|
51
|
+
pedido: {
|
|
52
|
+
id: string;
|
|
53
|
+
valor: number;
|
|
54
|
+
criado_em: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
/** Resposta de exemplo do Enviar webhook (simulado). */
|
|
58
|
+
export declare const FLOW_SAMPLE_RESPONSE = "200 OK { \"id\": \"crm-88\" }";
|
|
59
|
+
/** Achata o JSON em caminhos (`cliente.nome`) e valores em texto, na ordem de leitura. */
|
|
60
|
+
export declare function flattenPayload(payload: unknown, prefix?: string): {
|
|
61
|
+
path: string;
|
|
62
|
+
value: string;
|
|
63
|
+
}[];
|
|
64
|
+
export interface FlowVariable {
|
|
65
|
+
/** O que vai entre chaves: `{{id}}`. */
|
|
66
|
+
id: string;
|
|
67
|
+
label: string;
|
|
68
|
+
}
|
|
69
|
+
export declare const asList: (v: unknown) => Record<string, unknown>[];
|
|
70
|
+
/** Variáveis que os blocos podem usar: as do gatilho do fluxo (sem escopo por caminho). */
|
|
71
|
+
export declare function flowVariables(flow: Flow): FlowVariable[];
|
|
72
|
+
/** Valores de exemplo de cada variável do fluxo (usados no teste e na simulação). */
|
|
73
|
+
export declare function flowSampleData(flow: Flow): Record<string, string>;
|
|
74
|
+
export interface TemplatePart {
|
|
75
|
+
kind: 'text' | 'var';
|
|
76
|
+
value: string;
|
|
77
|
+
}
|
|
78
|
+
/** Parte o texto em trechos e variáveis `{{x}}` (as variáveis viram chips no card). */
|
|
79
|
+
export declare function splitVariables(text: string): TemplatePart[];
|
|
80
|
+
/** Troca cada `{{x}}` pelo valor de exemplo; variável sem valor fica como está. */
|
|
81
|
+
export declare function renderTemplate(text: string, data: Record<string, string>): string;
|
|
82
|
+
export declare const FLOW_RULE_OPERATORS: {
|
|
83
|
+
value: FlowRuleOperator;
|
|
84
|
+
label: string;
|
|
85
|
+
symbol: string;
|
|
86
|
+
}[];
|
|
87
|
+
/** Operadores que dispensam o valor. */
|
|
88
|
+
export declare const operatorHasValue: (op: FlowRuleOperator) => op is "igual" | "diferente" | "maior" | "menor" | "contem";
|
|
89
|
+
export declare const isRuleComplete: (rule: FlowRule) => boolean;
|
|
90
|
+
/** "pedido.valor é maior que 500". */
|
|
91
|
+
export declare function ruleSummary(rule: FlowRule): string;
|
|
92
|
+
/** As regras do bloco condição (lista vazia se o config não as traz). */
|
|
93
|
+
export declare function rulesOf(node: Pick<FlowNode, 'data'>): FlowRule[];
|
|
94
|
+
/** Nome da saída: o rótulo da regra (ou "Regra N") e "Senão". */
|
|
95
|
+
export declare function branchName(node: Pick<FlowNode, 'data'>, branch: string): string;
|
|
96
|
+
/** Menor `rN` livre para uma regra nova. */
|
|
97
|
+
export declare function nextRuleId(rules: {
|
|
98
|
+
id: string;
|
|
99
|
+
}[]): string;
|
|
100
|
+
/** Texto curto na ligação que sai de uma condição ("> 500", "= pro", "Senão"). */
|
|
101
|
+
export declare function edgeLabel(flow: Flow, edge: FlowEdge): string | null;
|
|
102
|
+
/** Saídas de um bloco: as regras e "Senão" na condição; uma só nos demais. */
|
|
103
|
+
export declare function outputIds(node: Pick<FlowNode, 'type' | 'data'>): (string | undefined)[];
|
|
104
|
+
export declare const RECORD_LABEL: Record<string, string>;
|
|
105
|
+
/** O texto, ou vazio quando o valor não é texto. */
|
|
106
|
+
export declare const str: (v: unknown) => string;
|
|
107
|
+
/** Linhas "rótulo e valor" do resumo no card (variáveis `{{x}}` viram chips). */
|
|
108
|
+
export declare function summarizeConfig(node: Pick<FlowNode, 'type' | 'data'>): {
|
|
109
|
+
label: string;
|
|
110
|
+
value: string;
|
|
111
|
+
}[];
|
|
112
|
+
/** Requisição simulada do Enviar webhook, com os valores de exemplo no corpo. */
|
|
113
|
+
export declare function buildWebhookRequest(config: Record<string, unknown> | undefined, data: Record<string, string>): {
|
|
114
|
+
method: string;
|
|
115
|
+
url: string;
|
|
116
|
+
body: Record<string, string>;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Altura estimada do card em px (medida no navegador e arredondada para cima), usada enquanto o
|
|
120
|
+
* React Flow ainda não mediu o bloco: na arrumação automática e ao procurar espaço livre.
|
|
121
|
+
*/
|
|
122
|
+
export declare function estimateNodeHeight(node: Pick<FlowNode, 'type' | 'data'>): number;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type Flow, type FlowBranch, type FlowNode, type FlowNodeType } from './flow';
|
|
2
|
+
export interface AddNodeOptions {
|
|
3
|
+
label?: string;
|
|
4
|
+
/** Ids que já existiram neste fluxo (mesmo apagados): não voltam a ser usados. */
|
|
5
|
+
reservedIds?: Iterable<string>;
|
|
6
|
+
}
|
|
7
|
+
/** Acrescenta um bloco com id único e determinístico (`tipo-N`) e a configuração padrão do tipo. */
|
|
8
|
+
export declare function addNode(input: Flow, type: FlowNodeType, position: {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
}, options?: AddNodeOptions): {
|
|
12
|
+
flow: Flow;
|
|
13
|
+
id: string;
|
|
14
|
+
};
|
|
15
|
+
export type RemoveMode = 'so-este' | 'daqui-para-frente';
|
|
16
|
+
/**
|
|
17
|
+
* Apaga o bloco. `so-este`: religa o anterior ao posterior quando o bloco tem uma entrada e uma
|
|
18
|
+
* saída e não é condição. `daqui-para-frente`: apaga também tudo o que só existe por causa dele.
|
|
19
|
+
*/
|
|
20
|
+
export declare function removeNode(input: Flow, id: string, mode?: RemoveMode): Flow;
|
|
21
|
+
export declare function removeEdge(flow: Flow, id: string): Flow;
|
|
22
|
+
/** Tira a ligação da saída `branch` de `source` (a única saída, nos blocos comuns). */
|
|
23
|
+
export declare function clearOutput(flow: Flow, source: string, branch?: FlowBranch): Flow;
|
|
24
|
+
export declare function moveNode(flow: Flow, id: string, position: {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
}): Flow;
|
|
28
|
+
/** Troca o rótulo e/ou o config do bloco (o config informado substitui o anterior). */
|
|
29
|
+
export declare function updateNodeData(flow: Flow, id: string, patch: {
|
|
30
|
+
label?: string;
|
|
31
|
+
config?: Record<string, unknown>;
|
|
32
|
+
}): Flow;
|
|
33
|
+
export type ConnectResult = {
|
|
34
|
+
ok: true;
|
|
35
|
+
flow: Flow;
|
|
36
|
+
replaced?: {
|
|
37
|
+
source: string;
|
|
38
|
+
target: string;
|
|
39
|
+
branch?: FlowBranch;
|
|
40
|
+
};
|
|
41
|
+
} | {
|
|
42
|
+
ok: false;
|
|
43
|
+
reason: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Liga dois blocos. A segunda ligação numa saída substitui a primeira e devolve a trocada em
|
|
47
|
+
* `replaced`, para o editor avisar. Recusa, com o motivo, o que o fluxo nunca aceita.
|
|
48
|
+
*/
|
|
49
|
+
export declare function connectNodes(flow: Flow, source: string, target: string, branch?: FlowBranch): ConnectResult;
|
|
50
|
+
/** Blocos que `id` pode ter como próximo: nunca ele mesmo nem um gatilho. */
|
|
51
|
+
export declare function nextCandidates(flow: Flow, id: string): FlowNode[];
|
|
52
|
+
export interface NodeLinks {
|
|
53
|
+
anteriores: {
|
|
54
|
+
node: FlowNode;
|
|
55
|
+
saida?: string;
|
|
56
|
+
}[];
|
|
57
|
+
posteriores: {
|
|
58
|
+
node: FlowNode;
|
|
59
|
+
saida?: string;
|
|
60
|
+
}[];
|
|
61
|
+
/** Blocos que o modo `daqui-para-frente` apaga além do próprio. */
|
|
62
|
+
descendentes: number;
|
|
63
|
+
}
|
|
64
|
+
/** Onde o bloco está ligado: quem vem antes, quem vem depois e quantos cairiam junto. */
|
|
65
|
+
export declare function describeNodeLinks(flow: Flow, id: string): NodeLinks;
|
|
66
|
+
/**
|
|
67
|
+
* Primeira posição livre a partir de `from`: desce em passos de `FLOW_GAP_Y` e, se a coluna
|
|
68
|
+
* estiver cheia, passa à coluna da direita. Usa o tamanho medido dos blocos quando há, senão
|
|
69
|
+
* a estimativa. Determinística: o mesmo fluxo e o mesmo ponto dão sempre a mesma posição.
|
|
70
|
+
*/
|
|
71
|
+
export declare function findFreePosition(flow: Flow, size: {
|
|
72
|
+
w: number;
|
|
73
|
+
h: number;
|
|
74
|
+
}, from: {
|
|
75
|
+
x: number;
|
|
76
|
+
y: number;
|
|
77
|
+
}, measured?: Record<string, {
|
|
78
|
+
w: number;
|
|
79
|
+
h: number;
|
|
80
|
+
}>): {
|
|
81
|
+
x: number;
|
|
82
|
+
y: number;
|
|
83
|
+
};
|
|
84
|
+
/** Aviso de troca: "A ligação anterior de "X" para "Y" foi trocada." */
|
|
85
|
+
export declare function replacedMessage(flow: Flow, replaced: {
|
|
86
|
+
source: string;
|
|
87
|
+
target: string;
|
|
88
|
+
}): string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Flow, type FlowIssue, type FlowNodeType, type FlowRule } from './flow';
|
|
2
|
+
export interface SimulationStep {
|
|
3
|
+
nodeId: string;
|
|
4
|
+
type: FlowNodeType;
|
|
5
|
+
label: string;
|
|
6
|
+
status: 'succeeded' | 'failed' | 'skipped';
|
|
7
|
+
detail?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SimulationState {
|
|
10
|
+
status: 'idle' | 'running' | 'finished' | 'error';
|
|
11
|
+
steps: SimulationStep[];
|
|
12
|
+
/** Bloco que o próximo avanço executa (o bloco ativo); `null` fora da simulação. */
|
|
13
|
+
currentId: string | null;
|
|
14
|
+
issues: FlowIssue[];
|
|
15
|
+
}
|
|
16
|
+
export declare function resetSimulation(): SimulationState;
|
|
17
|
+
/** Começa no gatilho. Fluxo inválido não inicia: devolve `error` com os problemas. */
|
|
18
|
+
export declare function startSimulation(input: Flow): SimulationState;
|
|
19
|
+
/** Avalia uma regra contra os dados de exemplo; campo que não existe conta como vazio. */
|
|
20
|
+
export declare function evaluateRule(rule: FlowRule, data: Record<string, string>): boolean;
|
|
21
|
+
/** Roda só um bloco, com os mesmos dados de exemplo, e devolve o passo (o play do card). */
|
|
22
|
+
export declare function simulateBlock(input: Flow, nodeId: string): SimulationStep | null;
|
|
23
|
+
/** Executa o bloco ativo (um passo) e passa ao próximo. A condição escolhe sozinha a saída. */
|
|
24
|
+
export declare function advanceSimulation(input: Flow, state: SimulationState): SimulationState;
|
package/dist/types/lib/flow.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
export type FlowNodeType = '
|
|
2
|
-
|
|
1
|
+
export type FlowNodeType = 'webhook-entrada' | 'agendamento' | 'registro-criado' | 'whatsapp' | 'email' | 'condicao' | 'espera' | 'webhook-saida' | 'tarefa' | 'gatilho' | 'acao' | 'fim';
|
|
2
|
+
/** Id da regra da condição, ou `'senao'`. */
|
|
3
|
+
export type FlowBranch = string;
|
|
3
4
|
export type FlowWaitUnit = 'segundos' | 'minutos' | 'horas' | 'dias';
|
|
5
|
+
export type FlowRuleOperator = 'igual' | 'diferente' | 'maior' | 'menor' | 'contem' | 'vazio' | 'nao-vazio';
|
|
6
|
+
export interface FlowRule {
|
|
7
|
+
id: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
field: string;
|
|
10
|
+
operator: FlowRuleOperator;
|
|
11
|
+
/** Vazio nos operadores `vazio` e `nao-vazio`. */
|
|
12
|
+
value: string;
|
|
13
|
+
}
|
|
4
14
|
export interface FlowNode {
|
|
5
15
|
id: string;
|
|
6
16
|
type: FlowNodeType;
|
|
@@ -17,10 +27,12 @@ export interface FlowEdge {
|
|
|
17
27
|
id: string;
|
|
18
28
|
source: string;
|
|
19
29
|
target: string;
|
|
20
|
-
/** Só a saída de uma condição usa o ramo
|
|
30
|
+
/** Só a saída de uma condição usa o ramo: o id da regra ou `senao`. */
|
|
21
31
|
branch?: FlowBranch;
|
|
22
32
|
}
|
|
23
33
|
export interface Flow {
|
|
34
|
+
/** Ausente = formato da 2.7.0 (convertido ao ler). */
|
|
35
|
+
version?: 2;
|
|
24
36
|
nodes: FlowNode[];
|
|
25
37
|
edges: FlowEdge[];
|
|
26
38
|
}
|
|
@@ -30,34 +42,21 @@ export interface FlowIssue {
|
|
|
30
42
|
nodeId?: string;
|
|
31
43
|
edgeId?: string;
|
|
32
44
|
}
|
|
33
|
-
export interface SimulationStep {
|
|
34
|
-
nodeId: string;
|
|
35
|
-
type: FlowNodeType;
|
|
36
|
-
label: string;
|
|
37
|
-
status: 'succeeded' | 'failed' | 'skipped';
|
|
38
|
-
detail?: string;
|
|
39
|
-
}
|
|
40
|
-
export interface SimulationState {
|
|
41
|
-
status: 'idle' | 'running' | 'waiting-choice' | 'finished' | 'error';
|
|
42
|
-
steps: SimulationStep[];
|
|
43
|
-
/** Bloco que o próximo avanço executa (o bloco ativo); `null` fora da simulação. */
|
|
44
|
-
currentId: string | null;
|
|
45
|
-
issues: FlowIssue[];
|
|
46
|
-
}
|
|
47
|
-
export declare const FLOW_NODE_TYPES: readonly FlowNodeType[];
|
|
48
|
-
export declare const FLOW_WAIT_UNITS: readonly FlowWaitUnit[];
|
|
49
|
-
/** Nome do tipo de bloco, como aparece na interface. */
|
|
50
|
-
export declare const FLOW_TYPE_NAME: Record<FlowNodeType, string>;
|
|
51
|
-
/** A duração do bloco de espera ("5 minutos"), ou `null` se o config não a define. */
|
|
52
|
-
export declare function formatWait(config: Record<string, unknown> | undefined): string | null;
|
|
53
|
-
/** Texto da espera simulada: nunca espera de verdade. */
|
|
54
|
-
export declare function describeWait(config: Record<string, unknown> | undefined): string;
|
|
55
45
|
/** Nome do bloco para mensagens e rótulos: o rótulo, ou o tipo quando ele está vazio. */
|
|
56
46
|
export declare const nodeName: (n: Pick<FlowNode, "type" | "data">) => string;
|
|
47
|
+
/**
|
|
48
|
+
* Leva um fluxo da 2.7.0 (sem `version`) ao formato v2: tira os blocos Fim, a condição vira uma
|
|
49
|
+
* regra "Sim" mais "Senão", e os blocos são arrumados da esquerda para a direita. Quem já é v2
|
|
50
|
+
* volta igual.
|
|
51
|
+
*/
|
|
52
|
+
export declare function migrateFlow(flow: Flow): Flow;
|
|
57
53
|
/** Problemas do fluxo, em ordem estável: a mesma entrada dá sempre a mesma lista. */
|
|
58
|
-
export declare function validateFlow(
|
|
59
|
-
/**
|
|
60
|
-
|
|
54
|
+
export declare function validateFlow(input: Flow): FlowIssue[];
|
|
55
|
+
/**
|
|
56
|
+
* JSON do fluxo (sempre no formato v2, com `version` na primeira chave) e a ordem das chaves
|
|
57
|
+
* fixa: o mesmo fluxo dá sempre o mesmo texto. Um fluxo da 2.7.0 é convertido antes.
|
|
58
|
+
*/
|
|
59
|
+
export declare function serializeFlow(input: Flow): string;
|
|
61
60
|
export type ParseResult = {
|
|
62
61
|
ok: true;
|
|
63
62
|
flow: Flow;
|
|
@@ -65,57 +64,8 @@ export type ParseResult = {
|
|
|
65
64
|
ok: false;
|
|
66
65
|
errors: string[];
|
|
67
66
|
};
|
|
68
|
-
/** Lê o JSON de um fluxo. Nunca lança; campos que o contrato não conhece são ignorados. */
|
|
69
|
-
export declare function parseFlow(text: string): ParseResult;
|
|
70
|
-
export interface AddNodeOptions {
|
|
71
|
-
label?: string;
|
|
72
|
-
/** Ids que já existiram neste fluxo (mesmo apagados): não voltam a ser usados. */
|
|
73
|
-
reservedIds?: Iterable<string>;
|
|
74
|
-
}
|
|
75
|
-
/** Acrescenta um bloco com id único e determinístico (`tipo-N`). */
|
|
76
|
-
export declare function addNode(flow: Flow, type: FlowNodeType, position: {
|
|
77
|
-
x: number;
|
|
78
|
-
y: number;
|
|
79
|
-
}, options?: AddNodeOptions): {
|
|
80
|
-
flow: Flow;
|
|
81
|
-
id: string;
|
|
82
|
-
};
|
|
83
|
-
/** Apaga o bloco e as ligações que chegam ou saem dele. */
|
|
84
|
-
export declare function removeNode(flow: Flow, id: string): Flow;
|
|
85
|
-
export declare function removeEdge(flow: Flow, id: string): Flow;
|
|
86
|
-
export declare function moveNode(flow: Flow, id: string, position: {
|
|
87
|
-
x: number;
|
|
88
|
-
y: number;
|
|
89
|
-
}): Flow;
|
|
90
|
-
/** Troca o rótulo e/ou o config do bloco (o config informado substitui o anterior). */
|
|
91
|
-
export declare function updateNodeData(flow: Flow, id: string, patch: {
|
|
92
|
-
label?: string;
|
|
93
|
-
config?: Record<string, unknown>;
|
|
94
|
-
}): Flow;
|
|
95
|
-
export type ConnectResult = {
|
|
96
|
-
ok: true;
|
|
97
|
-
flow: Flow;
|
|
98
|
-
} | {
|
|
99
|
-
ok: false;
|
|
100
|
-
reason: string;
|
|
101
|
-
};
|
|
102
|
-
/**
|
|
103
|
-
* Liga dois blocos. A segunda saída de um bloco comum (ou do mesmo ramo da condição) substitui
|
|
104
|
-
* a primeira. Recusa, com o motivo, o que o fluxo nunca aceita.
|
|
105
|
-
*/
|
|
106
|
-
export declare function connectNodes(flow: Flow, source: string, target: string, branch?: FlowBranch): ConnectResult;
|
|
107
67
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
68
|
+
* Lê o JSON de um fluxo. Nunca lança; campos que o contrato não conhece são ignorados. Texto sem
|
|
69
|
+
* `version` é lido pelas regras da 2.7.0 e convertido; `version: 2` segue as regras do formato novo.
|
|
110
70
|
*/
|
|
111
|
-
export declare function
|
|
112
|
-
/** Blocos que `id` pode ter como próximo: nunca ele mesmo nem o gatilho. */
|
|
113
|
-
export declare function nextCandidates(flow: Flow, id: string): FlowNode[];
|
|
114
|
-
export declare function resetSimulation(): SimulationState;
|
|
115
|
-
/** Começa no gatilho. Fluxo inválido não inicia: devolve `error` com os problemas. */
|
|
116
|
-
export declare function startSimulation(flow: Flow): SimulationState;
|
|
117
|
-
/**
|
|
118
|
-
* Executa o bloco ativo (um passo) e passa ao próximo. Na condição é preciso escolher o ramo:
|
|
119
|
-
* sem escolha válida nada anda. A espera é instantânea; só o texto diz quanto aguardaria.
|
|
120
|
-
*/
|
|
121
|
-
export declare function advanceSimulation(flow: Flow, state: SimulationState, choice?: FlowBranch): SimulationState;
|
|
71
|
+
export declare function parseFlow(text: string): ParseResult;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
2
|
import { useSyncExternalStore } from "react";
|
|
3
3
|
//#region src/hooks/use-breakpoint.ts
|
|
4
4
|
/**
|
|
@@ -46,4 +46,4 @@ function useBreakpoint() {
|
|
|
46
46
|
//#endregion
|
|
47
47
|
export { useBreakpoint as n, breakpoints as t };
|
|
48
48
|
|
|
49
|
-
//# sourceMappingURL=use-breakpoint-
|
|
49
|
+
//# sourceMappingURL=use-breakpoint-BGmY3ir-.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-breakpoint-
|
|
1
|
+
{"version":3,"file":"use-breakpoint-BGmY3ir-.js","names":[],"sources":["../src/hooks/use-breakpoint.ts"],"sourcesContent":["import { useSyncExternalStore } from 'react'\n\n/**\n * Pontos de quebra, espelhando os padrões do Tailwind (sm 40rem, md 48rem, lg 64rem...).\n * Único hook de detecção de tela do sistema. Para adaptação ao espaço disponível\n * dentro de um bloco (e não à tela), use container queries (@container) no CSS.\n */\nexport const breakpoints = { sm: 640, md: 768, lg: 1024, xl: 1280, '2xl': 1536 } as const\nexport type Breakpoint = keyof typeof breakpoints\n\nconst order: Breakpoint[] = ['sm', 'md', 'lg', 'xl', '2xl']\n\nfunction subscribe(cb: () => void) {\n const lists = order.map((bp) => matchMedia(`(min-width: ${breakpoints[bp]}px)`))\n lists.forEach((mq) => mq.addEventListener('change', cb))\n return () => lists.forEach((mq) => mq.removeEventListener('change', cb))\n}\n\nfunction getCurrent(): Breakpoint | 'base' {\n let current: Breakpoint | 'base' = 'base'\n for (const bp of order) if (matchMedia(`(min-width: ${breakpoints[bp]}px)`).matches) current = bp\n return current\n}\n\nexport function useBreakpoint() {\n const current = useSyncExternalStore(subscribe, getCurrent, () => 'lg' as const)\n const rank = current === 'base' ? -1 : order.indexOf(current)\n const up = (bp: Breakpoint) => rank >= order.indexOf(bp)\n return {\n current,\n up,\n /** Abaixo de 768px: componentes se reconstroem no formato mobile. */\n isMobile: !up('md'),\n isTablet: up('md') && !up('lg'),\n isDesktop: up('lg'),\n }\n}\n"],"mappings":";;;;;;;;AAOA,IAAa,cAAc;CAAE,IAAI;CAAK,IAAI;CAAK,IAAI;CAAM,IAAI;CAAM,OAAO;AAAK;AAG/E,IAAM,QAAsB;CAAC;CAAM;CAAM;CAAM;CAAM;AAAK;AAE1D,SAAS,UAAU,IAAgB;CACjC,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,eAAe,YAAY,IAAI,IAAI,CAAC;CAC/E,MAAM,SAAS,OAAO,GAAG,iBAAiB,UAAU,EAAE,CAAC;CACvD,aAAa,MAAM,SAAS,OAAO,GAAG,oBAAoB,UAAU,EAAE,CAAC;AACzE;AAEA,SAAS,aAAkC;CACzC,IAAI,UAA+B;CACnC,KAAK,MAAM,MAAM,OAAO,IAAI,WAAW,eAAe,YAAY,IAAI,IAAI,CAAC,CAAC,SAAS,UAAU;CAC/F,OAAO;AACT;AAEA,SAAgB,gBAAgB;CAC9B,MAAM,UAAU,qBAAqB,WAAW,kBAAkB,IAAa;CAC/E,MAAM,OAAO,YAAY,SAAS,KAAK,MAAM,QAAQ,OAAO;CAC5D,MAAM,MAAM,OAAmB,QAAQ,MAAM,QAAQ,EAAE;CACvD,OAAO;EACL;EACA;;EAEA,UAAU,CAAC,GAAG,IAAI;EAClB,UAAU,GAAG,IAAI,KAAK,CAAC,GAAG,IAAI;EAC9B,WAAW,GAAG,IAAI;CACpB;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { a as useMotionMode, c as getReducedMotion, l as subscribeReducedMotion } from "./motion-context-
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { a as useMotionMode, c as getReducedMotion, l as subscribeReducedMotion } from "./motion-context-DWFl2xRr.js";
|
|
3
3
|
import { useMemo, useSyncExternalStore } from "react";
|
|
4
4
|
//#region src/lib/motion/tokens.ts
|
|
5
5
|
/**
|
|
@@ -398,4 +398,4 @@ function useMotionPresets() {
|
|
|
398
398
|
//#endregion
|
|
399
399
|
export { toCubicBezier as n, useMotionPresets as t };
|
|
400
400
|
|
|
401
|
-
//# sourceMappingURL=use-motion-presets-
|
|
401
|
+
//# sourceMappingURL=use-motion-presets-CmMLBQLI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-motion-presets-I4StrsCi.js","names":[],"sources":["../src/lib/motion/tokens.ts","../src/lib/motion/presets.ts","../src/lib/motion/use-motion-presets.ts"],"sourcesContent":["/*\n * Durações e curvas do motion (linguagem única, web e app). A fonte é o globals.css:\n * --rendra-duration-* bloco :root fora de camada (vai para o dist/tokens.css do pacote);\n * --rendra-ease-* no mesmo bloco, então o host as sobrescreve; o @theme guarda os nomes\n * do Tailwind (--ease-out, --ease-move...) como alias delas.\n * As constantes daqui são a reserva em tempo de execução (SSR, variável ausente ou inválida), e\n * tokens.test.ts confere que elas batem com o globals.css. Valores em segundos e vetores de 4\n * números, o formato que o Motion aceita.\n */\n\nexport type Bezier = [number, number, number, number]\n\n/**\n * Reserva das durações, em segundos (SSR, ou variável ausente).\n * `press` e `fast` valem o mesmo (120 ms) com propósitos diferentes: o toque e a saída de overlay.\n */\nexport const DURATION = {\n press: 0.12,\n hover: 0.15,\n fast: 0.12,\n base: 0.2,\n move: 0.25,\n slow: 0.32,\n draw: 0.42,\n pulse: 1,\n}\nexport type DurationName = keyof typeof DURATION\n\n/**\n * Reveal: entrada de uso único (dashboard: bloco, cascata, contador e desenho do gráfico), mais\n * lenta que as interações do dia a dia. Reserva em segundos (SSR, ou variável ausente).\n */\nexport const REVEAL = { enter: 0.6, stagger: 0.12, count: 1.2, draw: 0.9 }\nexport type RevealName = keyof typeof REVEAL\n\n/**\n * Curvas do globals.css (`--rendra-ease-*`). `spring` é a curva \"back\" (quique): só para a cota\n * rara de encanto. `move` desloca na tela; `drawer` é a curva de gaveta e folha.\n */\nexport const EASE: Record<'out' | 'inOut' | 'spring' | 'move' | 'drawer', Bezier> = {\n out: [0.22, 1, 0.36, 1],\n inOut: [0.65, 0, 0.35, 1],\n spring: [0.34, 1.56, 0.64, 1],\n move: [0.77, 0, 0.175, 1],\n drawer: [0.32, 0.72, 0, 1],\n}\nexport type EaseName = keyof typeof EASE\n\n/** Nome da variável CSS de cada curva (`inOut` vira `in-out`). */\nconst EASE_VAR: Record<EaseName, string> = {\n out: 'out',\n inOut: 'in-out',\n spring: 'spring',\n move: 'move',\n drawer: 'drawer',\n}\n\n/**\n * Molas no formato \"duração e quique\" (Motion). `settle` assenta sem passar do ponto (layout,\n * overlay que entra, soltura do arraste); `sheet` é a folha depois do gesto, com quique mínimo.\n * Mola não é variável CSS: mora aqui, e o app a espelha em `dampingRatio`.\n */\nexport const SPRING = {\n settle: { duration: 0.4, bounce: 0 },\n sheet: { duration: 0.3, bounce: 0.2 },\n}\n\n/** Escalas da linguagem: entrada de overlay, tooltip, ponto pequeno, toque, pop e salto curto. */\nexport const SCALE = { enter: 0.95, tooltip: 0.97, small: 0.9, press: 0.97, pop: 0.8, bump: 1.08 }\n\n/** Desfoque (px) que disfarça o cruzamento entre dois estados (troca de passo). Abaixo de 20. */\nexport const BLUR = 2\n\nexport interface MotionTokens {\n duration: Record<DurationName, number>\n reveal: Record<RevealName, number>\n ease: Record<EaseName, Bezier>\n}\n\nfunction toSeconds(value: string): number | null {\n const v = value.trim()\n const n = parseFloat(v)\n if (!Number.isFinite(n)) return null\n if (v.endsWith('ms')) return n / 1000\n if (v.endsWith('s')) return n\n return null\n}\n\n/** `cubic-bezier(a, b, c, d)` em vetor; qualquer outra coisa (`ease-in`, vazio) vira `null`. */\nfunction toBezier(value: string): Bezier | null {\n const m = /^cubic-bezier\\(([^)]+)\\)$/.exec(value.trim())\n if (!m) return null\n const parts = m[1]!.split(',').map((n) => parseFloat(n))\n if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n))) return null\n return parts as Bezier\n}\n\n/** Lê as durações e as curvas do documento; o que faltar (ou sem window) vem da reserva. */\nexport function readMotionTokens(): MotionTokens {\n const duration = { ...DURATION }\n const reveal = { ...REVEAL }\n const ease = { ...EASE }\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n const style = getComputedStyle(document.documentElement)\n for (const name of Object.keys(DURATION) as DurationName[]) {\n const read = toSeconds(style.getPropertyValue(`--rendra-duration-${name}`))\n if (read !== null) duration[name] = read\n }\n for (const name of Object.keys(REVEAL) as RevealName[]) {\n const read = toSeconds(style.getPropertyValue(`--rendra-reveal-${name}`))\n if (read !== null) reveal[name] = read\n }\n for (const name of Object.keys(EASE) as EaseName[]) {\n const read = toBezier(style.getPropertyValue(`--rendra-ease-${EASE_VAR[name]}`))\n if (read !== null) ease[name] = read\n }\n }\n return { duration, reveal, ease }\n}\n","import type { Target, TargetAndTransition, Transition } from 'motion/react'\nimport { BLUR, readMotionTokens, SCALE, SPRING, type Bezier, type MotionTokens } from './tokens'\n\n/*\n * Presets do caminho `on` (linguagem única de movimento): fade, scale/open, sheet, tooltip,\n * indicator, pop, slide, reveal, press, move, settle e stagger. Toda duração e toda curva vêm de\n * readMotionTokens (globals.css); nenhum número de duração mora neste arquivo (o presets.test.ts\n * varre o código-fonte atrás de literal). As molas e as escalas vêm de tokens.ts.\n *\n * Duas regras moram aqui:\n * - Assimetria: o que o usuário decidiu (abrir) entra no tempo `base`, e o que o sistema\n * responde ao fechar sai em `fast`, só em opacidade. Gaveta e folha saem em `base`, de volta\n * pelo lado de onde vieram.\n * - Reduzido: sem deslocamento, escala, filtro nem cascata; a opacidade usa `base` (não zero),\n * porque o esmaecimento é o que explica a mudança de estado.\n */\n\nexport interface MotionPreset {\n initial: Target\n animate: TargetAndTransition\n exit: TargetAndTransition\n transition: Transition\n}\n\n/** Toque: o alvo do `whileTap` (`undefined` no reduzido) e a transição de ida e de volta. */\nexport interface PressPreset {\n whileTap: TargetAndTransition | undefined\n transition: Transition\n}\n\nexport type SlideFrom = 'left' | 'right' | 'top' | 'bottom'\n\n/** Distância do slide: `full` (painel que entra da borda) ou `short` (conteúdo que assenta). */\nexport type SlideDistance = 'full' | 'short'\n\nconst SHORT_PX = 8\n\nexport interface Presets {\n reduced: boolean\n /** Toque do botão, do polegar e dos controles: 120 ms, `ease.out`, escala 0,97. */\n press: PressPreset\n /** Alias de `press.whileTap`, o nome antigo. Sem movimento reduzido vem `undefined`. */\n tap: TargetAndTransition | undefined\n /**\n * Salto curto de escala (célula do OTP), com a transição dentro do alvo. Estável entre\n * renders; `undefined` se reduzido.\n */\n bump: TargetAndTransition | undefined\n tokens: MotionTokens\n fade: MotionPreset\n /** Alias de `open()`: escala 0,95 com mola a partir da origem, saída rápida só em opacidade. */\n scale: MotionPreset\n /**\n * Cota rara de encanto (check do passo concluído): 0,8 -> 1 com a curva back, em `slow`. Nunca\n * em controle de uso frequente.\n */\n pop: MotionPreset\n /**\n * Indicador de controle frequente (check do Checkbox, ponto do Radio): 0,9 -> 1 com opacidade\n * em `fast`, sem quique e sem partir de zero.\n */\n indicator: MotionPreset\n slide: (from: SlideFrom, distance?: SlideDistance) => MotionPreset\n /**\n * Overlay ancorado (popover, menu, modal, painel do select). Número = escala de partida\n * (padrão 0,95); `{ y }` = entrada plana, sem escala, para a superfície em tela cheia.\n * Entra em mola criticamente amortecida (sem quique) em `base` e sai em `fast`, em opacidade.\n */\n open: (from?: number | { y: number }) => MotionPreset\n /** Gaveta e folha: entram de `from` em `slow` com `ease.drawer`, saem em `fast` pelo mesmo lado. */\n sheet: (from: SlideFrom) => MotionPreset\n /** Tooltip: escala 0,97 em `fast`; aberto em `instant-open` não anima. */\n tooltip: (instant: boolean) => MotionPreset\n /**\n * Troca de conteúdo no lugar (passo do wizard), sem esperar a saída: o que sai esmaece com\n * `blur` de 2 px em `fast`; o que entra vem de `direction` (1 avança, -1 volta), 8 px, em\n * `base`. O desfoque disfarça o cruzamento: sem ele o olho vê dois objetos trocando de lugar.\n */\n swap: (direction: 1 | -1) => MotionPreset\n /**\n * Entrada de uso único (reveal do dashboard): desloca 8 px e dura `reveal.enter`, mais lenta\n * que `slide`. Não serve a interação repetida (overlay, tab, botão).\n */\n reveal: (from: SlideFrom) => MotionPreset\n /** Deslocamento na tela (indicador, reordenação): `move` em `ease.move`. */\n move: Transition\n /** Nome antigo de `move`. */\n layout: Transition\n /** Mola sem quique: onde há gesto ou soltura (drop do kanban, folha que volta). */\n settle: Transition\n /** Mola da folha depois do arraste (quique mínimo). */\n springSheet: Transition\n /**\n * A mesma mola da folha em rigidez e amortecimento (massa 1), que é o que o arraste do Motion\n * (`dragTransition`) pede para a volta à origem: rigidez = (2π / duração)², amortecimento =\n * 2 (1 - quique) raiz(rigidez).\n */\n sheetBounce: { bounceStiffness: number; bounceDamping: number }\n /** Atraso de entrada do item `index`, limitado a `limit` itens (padrão 8: 480 ms). */\n stagger: (index: number, limit?: number) => Transition\n /** Atraso do bloco `index` no reveal (passo `reveal.stagger`), limitado a `limit` blocos. */\n staggerReveal: (index: number, limit?: number) => Transition\n}\n\n/** Mola em \"duração e quique\" para rigidez e amortecimento (massa 1). */\nfunction springToBounce({ duration, bounce }: { duration: number; bounce: number }) {\n const stiffness = ((2 * Math.PI) / duration) ** 2\n return {\n bounceStiffness: Math.round(stiffness),\n bounceDamping: Math.round(2 * (1 - bounce) * Math.sqrt(stiffness)),\n }\n}\n\nexport function createPresets(tokens: MotionTokens, reduced: boolean): Presets {\n const { duration, reveal, ease } = tokens\n const base: Transition = { duration: duration.base, ease: ease.out }\n const fastOut: Transition = { duration: duration.fast, ease: ease.out }\n const settle: Transition = { type: 'spring', ...SPRING.settle }\n const enter: Transition = {\n type: 'spring',\n duration: duration.base,\n bounce: SPRING.settle.bounce,\n }\n\n /** O que sobra sob \"reduzir movimento\": só opacidade, em `base`. */\n const flat = (): MotionPreset => ({\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: base,\n })\n const make = (initial: Target, animate: Target, time: number, curve = ease.out): MotionPreset =>\n reduced\n ? flat()\n : {\n initial,\n animate,\n exit: initial,\n transition: { duration: time, ease: curve },\n }\n\n const offset = (from: SlideFrom, distance: SlideDistance): Target => {\n const far = distance === 'full' ? '100%' : SHORT_PX\n const sign = from === 'left' || from === 'top' ? -1 : 1\n const value = typeof far === 'string' ? `${sign * 100}%` : sign * far\n return from === 'left' || from === 'right' ? { x: value, opacity: 0 } : { y: value, opacity: 0 }\n }\n const settled = (initial: Target): Target => ({\n opacity: 1,\n ...(initial.x !== undefined ? { x: 0 } : {}),\n ...(initial.y !== undefined ? { y: 0 } : {}),\n })\n\n const fade: MotionPreset = reduced\n ? flat()\n : {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0, transition: fastOut },\n transition: base,\n }\n\n const open = (from: number | { y: number } = SCALE.enter): MotionPreset => {\n if (reduced) return flat()\n const initial: Target =\n typeof from === 'number' ? { opacity: 0, scale: from } : { opacity: 0, y: from.y }\n const to: Target = typeof from === 'number' ? { opacity: 1, scale: 1 } : { opacity: 1, y: 0 }\n return {\n initial,\n animate: { ...to, transition: enter },\n exit: { opacity: 0, transition: fastOut },\n transition: enter,\n }\n }\n\n const sheet = (from: SlideFrom): MotionPreset => {\n if (reduced) return flat()\n const sign = from === 'left' || from === 'top' ? -1 : 1\n const axis = from === 'left' || from === 'right' ? 'x' : 'y'\n const away = { [axis]: `${sign * 100}%` }\n return {\n initial: away,\n animate: { [axis]: 0 },\n exit: { ...away, transition: { duration: duration.fast, ease: ease.drawer } },\n transition: { duration: duration.slow, ease: ease.drawer },\n }\n }\n\n const tooltip = (instant: boolean): MotionPreset => {\n if (reduced) return instant ? { ...flat(), transition: { duration: 0 } } : flat()\n return {\n initial: { opacity: 0, scale: SCALE.tooltip },\n animate: { opacity: 1, scale: 1 },\n exit: { opacity: 0, transition: fastOut },\n transition: instant ? { duration: 0 } : fastOut,\n }\n }\n\n const blurred = `blur(${BLUR}px)`\n const swap = (direction: 1 | -1): MotionPreset => {\n if (reduced) return flat()\n return {\n initial: { opacity: 0, x: direction * SHORT_PX, filter: blurred },\n animate: { opacity: 1, x: 0, filter: 'blur(0px)', transition: base },\n exit: { opacity: 0, filter: blurred, transition: fastOut },\n transition: base,\n }\n }\n\n const indicatorInitial: Target = { opacity: 0, scale: SCALE.small }\n const press: PressPreset = {\n whileTap: reduced ? undefined : { scale: SCALE.press },\n transition: { duration: duration.press, ease: ease.out },\n }\n const move: Transition = reduced ? { duration: 0 } : { duration: duration.move, ease: ease.move }\n\n return {\n reduced,\n press,\n tap: press.whileTap,\n bump: reduced ? undefined : { scale: [SCALE.bump, 1], transition: fastOut },\n tokens,\n fade,\n scale: open(),\n pop: make(\n { opacity: 0, scale: SCALE.pop },\n { opacity: 1, scale: 1 },\n duration.slow,\n ease.spring,\n ),\n indicator: reduced\n ? flat()\n : {\n initial: indicatorInitial,\n animate: { opacity: 1, scale: 1 },\n exit: indicatorInitial,\n transition: fastOut,\n },\n slide: (from, distance = 'full') => {\n const initial = offset(from, distance)\n return make(initial, settled(initial), distance === 'full' ? duration.slow : duration.base)\n },\n open,\n sheet,\n tooltip,\n swap,\n reveal: (from) => {\n const initial = offset(from, 'short')\n return make(initial, settled(initial), reveal.enter)\n },\n move,\n layout: move,\n settle: reduced ? { duration: 0 } : settle,\n springSheet: reduced ? { duration: 0 } : { type: 'spring', ...SPRING.sheet },\n sheetBounce: springToBounce(SPRING.sheet),\n stagger: (index, limit = 8) => ({\n delay: reduced ? 0 : Math.min(index, limit) * (duration.fast / 2),\n }),\n staggerReveal: (index, limit = 8) => ({\n delay: reduced ? 0 : Math.min(index, limit) * reveal.stagger,\n }),\n }\n}\n\n/** Curva no formato do recharts: `cubic-bezier(a,b,c,d)`, sem espaços. */\nexport function toCubicBezier([\n a,\n b,\n c,\n d,\n]: Bezier): `cubic-bezier(${number},${number},${number},${number})` {\n return `cubic-bezier(${a},${b},${c},${d})`\n}\n\n/** Presets com os tokens lidos agora do documento. */\nexport function presetsFromDocument(reduced: boolean): Presets {\n return createPresets(readMotionTokens(), reduced)\n}\n","import { useMemo, useSyncExternalStore } from 'react'\nimport { getReducedMotion, subscribeReducedMotion } from '@/hooks/use-reduced-motion'\nimport { useMotionMode } from './motion-context'\nimport { createPresets, presetsFromDocument, type Presets } from './presets'\nimport { DURATION, EASE, REVEAL } from './tokens'\n\n/** Em `off` ninguém lê o documento nem assina o matchMedia: um objeto único e inerte. */\nconst OFF_PRESETS = createPresets({ duration: DURATION, reveal: REVEAL, ease: EASE }, false)\nconst noSubscribe = () => () => {}\nconst never = () => false\n\n/**\n * Presets do motion para o componente. A preferência \"reduzir movimento\" vem do mesmo\n * `matchMedia` do hook do projeto (`use-reduced-motion.ts`: Spinner, Progress), a fonte única,\n * reativa e testável, sem `MotionConfig reducedMotion` somando por cima. Só em `on` a\n * preferência é assinada e os tokens lidos do documento; em `off` o custo é zero.\n */\nexport function useMotionPresets(): Presets {\n const on = useMotionMode() === 'on'\n const reduced = useSyncExternalStore(\n on ? subscribeReducedMotion : noSubscribe,\n on ? getReducedMotion : never,\n never,\n )\n return useMemo(() => (on ? presetsFromDocument(reduced) : OFF_PRESETS), [on, reduced])\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-motion-presets-CmMLBQLI.js","names":[],"sources":["../src/lib/motion/tokens.ts","../src/lib/motion/presets.ts","../src/lib/motion/use-motion-presets.ts"],"sourcesContent":["/*\n * Durações e curvas do motion (linguagem única, web e app). A fonte é o globals.css:\n * --rendra-duration-* bloco :root fora de camada (vai para o dist/tokens.css do pacote);\n * --rendra-ease-* no mesmo bloco, então o host as sobrescreve; o @theme guarda os nomes\n * do Tailwind (--ease-out, --ease-move...) como alias delas.\n * As constantes daqui são a reserva em tempo de execução (SSR, variável ausente ou inválida), e\n * tokens.test.ts confere que elas batem com o globals.css. Valores em segundos e vetores de 4\n * números, o formato que o Motion aceita.\n */\n\nexport type Bezier = [number, number, number, number]\n\n/**\n * Reserva das durações, em segundos (SSR, ou variável ausente).\n * `press` e `fast` valem o mesmo (120 ms) com propósitos diferentes: o toque e a saída de overlay.\n */\nexport const DURATION = {\n press: 0.12,\n hover: 0.15,\n fast: 0.12,\n base: 0.2,\n move: 0.25,\n slow: 0.32,\n draw: 0.42,\n pulse: 1,\n}\nexport type DurationName = keyof typeof DURATION\n\n/**\n * Reveal: entrada de uso único (dashboard: bloco, cascata, contador e desenho do gráfico), mais\n * lenta que as interações do dia a dia. Reserva em segundos (SSR, ou variável ausente).\n */\nexport const REVEAL = { enter: 0.6, stagger: 0.12, count: 1.2, draw: 0.9 }\nexport type RevealName = keyof typeof REVEAL\n\n/**\n * Curvas do globals.css (`--rendra-ease-*`). `spring` é a curva \"back\" (quique): só para a cota\n * rara de encanto. `move` desloca na tela; `drawer` é a curva de gaveta e folha.\n */\nexport const EASE: Record<'out' | 'inOut' | 'spring' | 'move' | 'drawer', Bezier> = {\n out: [0.22, 1, 0.36, 1],\n inOut: [0.65, 0, 0.35, 1],\n spring: [0.34, 1.56, 0.64, 1],\n move: [0.77, 0, 0.175, 1],\n drawer: [0.32, 0.72, 0, 1],\n}\nexport type EaseName = keyof typeof EASE\n\n/** Nome da variável CSS de cada curva (`inOut` vira `in-out`). */\nconst EASE_VAR: Record<EaseName, string> = {\n out: 'out',\n inOut: 'in-out',\n spring: 'spring',\n move: 'move',\n drawer: 'drawer',\n}\n\n/**\n * Molas no formato \"duração e quique\" (Motion). `settle` assenta sem passar do ponto (layout,\n * overlay que entra, soltura do arraste); `sheet` é a folha depois do gesto, com quique mínimo.\n * Mola não é variável CSS: mora aqui, e o app a espelha em `dampingRatio`.\n */\nexport const SPRING = {\n settle: { duration: 0.4, bounce: 0 },\n sheet: { duration: 0.3, bounce: 0.2 },\n}\n\n/** Escalas da linguagem: entrada de overlay, tooltip, ponto pequeno, toque, pop e salto curto. */\nexport const SCALE = { enter: 0.95, tooltip: 0.97, small: 0.9, press: 0.97, pop: 0.8, bump: 1.08 }\n\n/** Desfoque (px) que disfarça o cruzamento entre dois estados (troca de passo). Abaixo de 20. */\nexport const BLUR = 2\n\nexport interface MotionTokens {\n duration: Record<DurationName, number>\n reveal: Record<RevealName, number>\n ease: Record<EaseName, Bezier>\n}\n\nfunction toSeconds(value: string): number | null {\n const v = value.trim()\n const n = parseFloat(v)\n if (!Number.isFinite(n)) return null\n if (v.endsWith('ms')) return n / 1000\n if (v.endsWith('s')) return n\n return null\n}\n\n/** `cubic-bezier(a, b, c, d)` em vetor; qualquer outra coisa (`ease-in`, vazio) vira `null`. */\nfunction toBezier(value: string): Bezier | null {\n const m = /^cubic-bezier\\(([^)]+)\\)$/.exec(value.trim())\n if (!m) return null\n const parts = m[1]!.split(',').map((n) => parseFloat(n))\n if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n))) return null\n return parts as Bezier\n}\n\n/** Lê as durações e as curvas do documento; o que faltar (ou sem window) vem da reserva. */\nexport function readMotionTokens(): MotionTokens {\n const duration = { ...DURATION }\n const reveal = { ...REVEAL }\n const ease = { ...EASE }\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n const style = getComputedStyle(document.documentElement)\n for (const name of Object.keys(DURATION) as DurationName[]) {\n const read = toSeconds(style.getPropertyValue(`--rendra-duration-${name}`))\n if (read !== null) duration[name] = read\n }\n for (const name of Object.keys(REVEAL) as RevealName[]) {\n const read = toSeconds(style.getPropertyValue(`--rendra-reveal-${name}`))\n if (read !== null) reveal[name] = read\n }\n for (const name of Object.keys(EASE) as EaseName[]) {\n const read = toBezier(style.getPropertyValue(`--rendra-ease-${EASE_VAR[name]}`))\n if (read !== null) ease[name] = read\n }\n }\n return { duration, reveal, ease }\n}\n","import type { Target, TargetAndTransition, Transition } from 'motion/react'\nimport { BLUR, readMotionTokens, SCALE, SPRING, type Bezier, type MotionTokens } from './tokens'\n\n/*\n * Presets do caminho `on` (linguagem única de movimento): fade, scale/open, sheet, tooltip,\n * indicator, pop, slide, reveal, press, move, settle e stagger. Toda duração e toda curva vêm de\n * readMotionTokens (globals.css); nenhum número de duração mora neste arquivo (o presets.test.ts\n * varre o código-fonte atrás de literal). As molas e as escalas vêm de tokens.ts.\n *\n * Duas regras moram aqui:\n * - Assimetria: o que o usuário decidiu (abrir) entra no tempo `base`, e o que o sistema\n * responde ao fechar sai em `fast`, só em opacidade. Gaveta e folha saem em `base`, de volta\n * pelo lado de onde vieram.\n * - Reduzido: sem deslocamento, escala, filtro nem cascata; a opacidade usa `base` (não zero),\n * porque o esmaecimento é o que explica a mudança de estado.\n */\n\nexport interface MotionPreset {\n initial: Target\n animate: TargetAndTransition\n exit: TargetAndTransition\n transition: Transition\n}\n\n/** Toque: o alvo do `whileTap` (`undefined` no reduzido) e a transição de ida e de volta. */\nexport interface PressPreset {\n whileTap: TargetAndTransition | undefined\n transition: Transition\n}\n\nexport type SlideFrom = 'left' | 'right' | 'top' | 'bottom'\n\n/** Distância do slide: `full` (painel que entra da borda) ou `short` (conteúdo que assenta). */\nexport type SlideDistance = 'full' | 'short'\n\nconst SHORT_PX = 8\n\nexport interface Presets {\n reduced: boolean\n /** Toque do botão, do polegar e dos controles: 120 ms, `ease.out`, escala 0,97. */\n press: PressPreset\n /** Alias de `press.whileTap`, o nome antigo. Sem movimento reduzido vem `undefined`. */\n tap: TargetAndTransition | undefined\n /**\n * Salto curto de escala (célula do OTP), com a transição dentro do alvo. Estável entre\n * renders; `undefined` se reduzido.\n */\n bump: TargetAndTransition | undefined\n tokens: MotionTokens\n fade: MotionPreset\n /** Alias de `open()`: escala 0,95 com mola a partir da origem, saída rápida só em opacidade. */\n scale: MotionPreset\n /**\n * Cota rara de encanto (check do passo concluído): 0,8 -> 1 com a curva back, em `slow`. Nunca\n * em controle de uso frequente.\n */\n pop: MotionPreset\n /**\n * Indicador de controle frequente (check do Checkbox, ponto do Radio): 0,9 -> 1 com opacidade\n * em `fast`, sem quique e sem partir de zero.\n */\n indicator: MotionPreset\n slide: (from: SlideFrom, distance?: SlideDistance) => MotionPreset\n /**\n * Overlay ancorado (popover, menu, modal, painel do select). Número = escala de partida\n * (padrão 0,95); `{ y }` = entrada plana, sem escala, para a superfície em tela cheia.\n * Entra em mola criticamente amortecida (sem quique) em `base` e sai em `fast`, em opacidade.\n */\n open: (from?: number | { y: number }) => MotionPreset\n /** Gaveta e folha: entram de `from` em `slow` com `ease.drawer`, saem em `fast` pelo mesmo lado. */\n sheet: (from: SlideFrom) => MotionPreset\n /** Tooltip: escala 0,97 em `fast`; aberto em `instant-open` não anima. */\n tooltip: (instant: boolean) => MotionPreset\n /**\n * Troca de conteúdo no lugar (passo do wizard), sem esperar a saída: o que sai esmaece com\n * `blur` de 2 px em `fast`; o que entra vem de `direction` (1 avança, -1 volta), 8 px, em\n * `base`. O desfoque disfarça o cruzamento: sem ele o olho vê dois objetos trocando de lugar.\n */\n swap: (direction: 1 | -1) => MotionPreset\n /**\n * Entrada de uso único (reveal do dashboard): desloca 8 px e dura `reveal.enter`, mais lenta\n * que `slide`. Não serve a interação repetida (overlay, tab, botão).\n */\n reveal: (from: SlideFrom) => MotionPreset\n /** Deslocamento na tela (indicador, reordenação): `move` em `ease.move`. */\n move: Transition\n /** Nome antigo de `move`. */\n layout: Transition\n /** Mola sem quique: onde há gesto ou soltura (drop do kanban, folha que volta). */\n settle: Transition\n /** Mola da folha depois do arraste (quique mínimo). */\n springSheet: Transition\n /**\n * A mesma mola da folha em rigidez e amortecimento (massa 1), que é o que o arraste do Motion\n * (`dragTransition`) pede para a volta à origem: rigidez = (2π / duração)², amortecimento =\n * 2 (1 - quique) raiz(rigidez).\n */\n sheetBounce: { bounceStiffness: number; bounceDamping: number }\n /** Atraso de entrada do item `index`, limitado a `limit` itens (padrão 8: 480 ms). */\n stagger: (index: number, limit?: number) => Transition\n /** Atraso do bloco `index` no reveal (passo `reveal.stagger`), limitado a `limit` blocos. */\n staggerReveal: (index: number, limit?: number) => Transition\n}\n\n/** Mola em \"duração e quique\" para rigidez e amortecimento (massa 1). */\nfunction springToBounce({ duration, bounce }: { duration: number; bounce: number }) {\n const stiffness = ((2 * Math.PI) / duration) ** 2\n return {\n bounceStiffness: Math.round(stiffness),\n bounceDamping: Math.round(2 * (1 - bounce) * Math.sqrt(stiffness)),\n }\n}\n\nexport function createPresets(tokens: MotionTokens, reduced: boolean): Presets {\n const { duration, reveal, ease } = tokens\n const base: Transition = { duration: duration.base, ease: ease.out }\n const fastOut: Transition = { duration: duration.fast, ease: ease.out }\n const settle: Transition = { type: 'spring', ...SPRING.settle }\n const enter: Transition = {\n type: 'spring',\n duration: duration.base,\n bounce: SPRING.settle.bounce,\n }\n\n /** O que sobra sob \"reduzir movimento\": só opacidade, em `base`. */\n const flat = (): MotionPreset => ({\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: base,\n })\n const make = (initial: Target, animate: Target, time: number, curve = ease.out): MotionPreset =>\n reduced\n ? flat()\n : {\n initial,\n animate,\n exit: initial,\n transition: { duration: time, ease: curve },\n }\n\n const offset = (from: SlideFrom, distance: SlideDistance): Target => {\n const far = distance === 'full' ? '100%' : SHORT_PX\n const sign = from === 'left' || from === 'top' ? -1 : 1\n const value = typeof far === 'string' ? `${sign * 100}%` : sign * far\n return from === 'left' || from === 'right' ? { x: value, opacity: 0 } : { y: value, opacity: 0 }\n }\n const settled = (initial: Target): Target => ({\n opacity: 1,\n ...(initial.x !== undefined ? { x: 0 } : {}),\n ...(initial.y !== undefined ? { y: 0 } : {}),\n })\n\n const fade: MotionPreset = reduced\n ? flat()\n : {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0, transition: fastOut },\n transition: base,\n }\n\n const open = (from: number | { y: number } = SCALE.enter): MotionPreset => {\n if (reduced) return flat()\n const initial: Target =\n typeof from === 'number' ? { opacity: 0, scale: from } : { opacity: 0, y: from.y }\n const to: Target = typeof from === 'number' ? { opacity: 1, scale: 1 } : { opacity: 1, y: 0 }\n return {\n initial,\n animate: { ...to, transition: enter },\n exit: { opacity: 0, transition: fastOut },\n transition: enter,\n }\n }\n\n const sheet = (from: SlideFrom): MotionPreset => {\n if (reduced) return flat()\n const sign = from === 'left' || from === 'top' ? -1 : 1\n const axis = from === 'left' || from === 'right' ? 'x' : 'y'\n const away = { [axis]: `${sign * 100}%` }\n return {\n initial: away,\n animate: { [axis]: 0 },\n exit: { ...away, transition: { duration: duration.fast, ease: ease.drawer } },\n transition: { duration: duration.slow, ease: ease.drawer },\n }\n }\n\n const tooltip = (instant: boolean): MotionPreset => {\n if (reduced) return instant ? { ...flat(), transition: { duration: 0 } } : flat()\n return {\n initial: { opacity: 0, scale: SCALE.tooltip },\n animate: { opacity: 1, scale: 1 },\n exit: { opacity: 0, transition: fastOut },\n transition: instant ? { duration: 0 } : fastOut,\n }\n }\n\n const blurred = `blur(${BLUR}px)`\n const swap = (direction: 1 | -1): MotionPreset => {\n if (reduced) return flat()\n return {\n initial: { opacity: 0, x: direction * SHORT_PX, filter: blurred },\n animate: { opacity: 1, x: 0, filter: 'blur(0px)', transition: base },\n exit: { opacity: 0, filter: blurred, transition: fastOut },\n transition: base,\n }\n }\n\n const indicatorInitial: Target = { opacity: 0, scale: SCALE.small }\n const press: PressPreset = {\n whileTap: reduced ? undefined : { scale: SCALE.press },\n transition: { duration: duration.press, ease: ease.out },\n }\n const move: Transition = reduced ? { duration: 0 } : { duration: duration.move, ease: ease.move }\n\n return {\n reduced,\n press,\n tap: press.whileTap,\n bump: reduced ? undefined : { scale: [SCALE.bump, 1], transition: fastOut },\n tokens,\n fade,\n scale: open(),\n pop: make(\n { opacity: 0, scale: SCALE.pop },\n { opacity: 1, scale: 1 },\n duration.slow,\n ease.spring,\n ),\n indicator: reduced\n ? flat()\n : {\n initial: indicatorInitial,\n animate: { opacity: 1, scale: 1 },\n exit: indicatorInitial,\n transition: fastOut,\n },\n slide: (from, distance = 'full') => {\n const initial = offset(from, distance)\n return make(initial, settled(initial), distance === 'full' ? duration.slow : duration.base)\n },\n open,\n sheet,\n tooltip,\n swap,\n reveal: (from) => {\n const initial = offset(from, 'short')\n return make(initial, settled(initial), reveal.enter)\n },\n move,\n layout: move,\n settle: reduced ? { duration: 0 } : settle,\n springSheet: reduced ? { duration: 0 } : { type: 'spring', ...SPRING.sheet },\n sheetBounce: springToBounce(SPRING.sheet),\n stagger: (index, limit = 8) => ({\n delay: reduced ? 0 : Math.min(index, limit) * (duration.fast / 2),\n }),\n staggerReveal: (index, limit = 8) => ({\n delay: reduced ? 0 : Math.min(index, limit) * reveal.stagger,\n }),\n }\n}\n\n/** Curva no formato do recharts: `cubic-bezier(a,b,c,d)`, sem espaços. */\nexport function toCubicBezier([\n a,\n b,\n c,\n d,\n]: Bezier): `cubic-bezier(${number},${number},${number},${number})` {\n return `cubic-bezier(${a},${b},${c},${d})`\n}\n\n/** Presets com os tokens lidos agora do documento. */\nexport function presetsFromDocument(reduced: boolean): Presets {\n return createPresets(readMotionTokens(), reduced)\n}\n","import { useMemo, useSyncExternalStore } from 'react'\nimport { getReducedMotion, subscribeReducedMotion } from '@/hooks/use-reduced-motion'\nimport { useMotionMode } from './motion-context'\nimport { createPresets, presetsFromDocument, type Presets } from './presets'\nimport { DURATION, EASE, REVEAL } from './tokens'\n\n/** Em `off` ninguém lê o documento nem assina o matchMedia: um objeto único e inerte. */\nconst OFF_PRESETS = createPresets({ duration: DURATION, reveal: REVEAL, ease: EASE }, false)\nconst noSubscribe = () => () => {}\nconst never = () => false\n\n/**\n * Presets do motion para o componente. A preferência \"reduzir movimento\" vem do mesmo\n * `matchMedia` do hook do projeto (`use-reduced-motion.ts`: Spinner, Progress), a fonte única,\n * reativa e testável, sem `MotionConfig reducedMotion` somando por cima. Só em `on` a\n * preferência é assinada e os tokens lidos do documento; em `off` o custo é zero.\n */\nexport function useMotionPresets(): Presets {\n const on = useMotionMode() === 'on'\n const reduced = useSyncExternalStore(\n on ? subscribeReducedMotion : noSubscribe,\n on ? getReducedMotion : never,\n never,\n )\n return useMemo(() => (on ? presetsFromDocument(reduced) : OFF_PRESETS), [on, reduced])\n}\n"],"mappings":"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"}
|
package/dist/widget-grid.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { t as cn } from "./cn-
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { t as cn } from "./cn-CpdCvlkP.js";
|
|
3
3
|
import { GripVertical } from "lucide-react";
|
|
4
4
|
import { useMemo, useState } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rendra-ui/web",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Rendra, design system e boilerplate React (Vite, TypeScript, Tailwind v4, Radix), com CLI de catálogo, auditoria e troca de variante.",
|
|
6
6
|
"author": {
|
|
@@ -128,6 +128,7 @@
|
|
|
128
128
|
"test:lazy": "playwright test --project=lazy",
|
|
129
129
|
"test:flow": "playwright test --project=flow",
|
|
130
130
|
"test:kanban": "playwright test --project=kanban",
|
|
131
|
+
"test:automacoes": "playwright test --project=automacoes",
|
|
131
132
|
"test:css-layers": "playwright test --project=css-layers",
|
|
132
133
|
"test:site": "playwright test -c playwright.site.config.ts",
|
|
133
134
|
"registry:build": "node scripts/build-registry.mjs",
|