@ffid-br/tailor-ui 0.7.0 → 0.8.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 +8 -0
- package/dist/index.es.js +509 -477
- package/dist/index.umd.js +1 -1
- package/dist/style.css +48 -1
- package/dist/types/components/TailorBrand.d.ts +2 -0
- package/dist/types/components/TailorButton.d.ts +37 -0
- package/dist/types/components/TailorLoader.d.ts +2 -1
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
package/dist/style.css
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
cor do cliente (accounts, brandTheme) leva o cabeçalho junto. */
|
|
29
29
|
--tailor-brand-primary: var(--color-tailor-green, var(--tailor-green));
|
|
30
30
|
--tailor-brand-primary-text: var(--color-tailor-ink, var(--tailor-ink));
|
|
31
|
+
--tailor-brand-on-primary: #000000;
|
|
31
32
|
--tailor-brand-text: var(--tailor-black);
|
|
32
33
|
--tailor-brand-text-muted: #666666;
|
|
33
34
|
--tailor-brand-border: #E5E5E5;
|
|
@@ -162,6 +163,14 @@
|
|
|
162
163
|
50% { transform: translate(8px, 8px); }
|
|
163
164
|
75% { transform: translate(0, 8px); }
|
|
164
165
|
}
|
|
166
|
+
/* dot: o mesmo quadrado, em % para caber em qualquer tamanho de ícone (1em). */
|
|
167
|
+
.tailor-loader__dot { background: var(--tailor-loader-dot, var(--tailor-brand-primary)); animation: tailor-loader-dot 1.236s steps(1, end) infinite; }
|
|
168
|
+
@keyframes tailor-loader-dot {
|
|
169
|
+
0% { transform: translate(0, 0); }
|
|
170
|
+
25% { transform: translate(161.8%, 0); }
|
|
171
|
+
50% { transform: translate(161.8%, 161.8%); }
|
|
172
|
+
75% { transform: translate(0, 161.8%); }
|
|
173
|
+
}
|
|
165
174
|
/* Sucesso: a malha nasce verde do ponto, o ponto estoura e o check se desenha. Uma vez só. */
|
|
166
175
|
.tailor-loader__ok-malha .tailor-malha__linha { animation: tailor-ok-malha 0.618s var(--tailor-ease-in-out) both; }
|
|
167
176
|
@keyframes tailor-ok-malha { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; opacity: 0.5; } }
|
|
@@ -300,6 +309,44 @@ textarea.tailor-field__control { padding: 8px 13px; min-height: 89px; }
|
|
|
300
309
|
@keyframes tailor-user-menu-out { from { clip-path: inset(0); } to { clip-path: inset(calc(100% - 8px) calc(100% - 8px) 0 0); } }
|
|
301
310
|
@keyframes tailor-user-menu-dot { 0%, 61.8% { opacity: 1; } 100% { opacity: 0; } }
|
|
302
311
|
|
|
312
|
+
/* TailorButton — cantos retos; carregando, o ícone vira o ponto correndo; feito, vira o check. */
|
|
313
|
+
.tailor-btn {
|
|
314
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 8px; flex-shrink: 0;
|
|
315
|
+
height: 40px; padding: 0 21px; border: 1px solid transparent; border-radius: var(--tailor-brand-radius, 0);
|
|
316
|
+
font-family: var(--tailor-brand-body-font, var(--tailor-font)); font-size: 14px; font-weight: 500; line-height: 1; white-space: nowrap;
|
|
317
|
+
cursor: pointer; transition: background-color 0.15s var(--tailor-ease-out), color 0.15s var(--tailor-ease-out), border-color 0.15s var(--tailor-ease-out);
|
|
318
|
+
}
|
|
319
|
+
.tailor-btn:focus-visible { outline: 2px solid var(--tailor-brand-text); outline-offset: 2px; }
|
|
320
|
+
.tailor-btn:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
321
|
+
.tailor-btn--loading { cursor: wait; }
|
|
322
|
+
.tailor-btn--sm { height: 32px; padding: 0 13px; font-size: 13px; }
|
|
323
|
+
.tailor-btn--lg { height: 48px; padding: 0 34px; font-size: 16px; }
|
|
324
|
+
.tailor-btn--icon-only { padding: 0; width: 40px; }
|
|
325
|
+
.tailor-btn--icon-only.tailor-btn--sm { width: 32px; }
|
|
326
|
+
.tailor-btn--icon-only.tailor-btn--lg { width: 48px; }
|
|
327
|
+
.tailor-btn--full { width: 100%; }
|
|
328
|
+
.tailor-btn--primary { background: var(--tailor-brand-primary); color: var(--tailor-brand-on-primary); }
|
|
329
|
+
.tailor-btn--primary:not(:disabled):hover { background: color-mix(in srgb, var(--tailor-brand-primary) 88%, #000); }
|
|
330
|
+
.tailor-btn--secondary { background: transparent; color: var(--tailor-brand-text); border-color: currentColor; }
|
|
331
|
+
.tailor-btn--ghost { background: transparent; color: var(--tailor-brand-text); }
|
|
332
|
+
.tailor-btn--secondary:not(:disabled):hover, .tailor-btn--ghost:not(:disabled):hover { background: color-mix(in srgb, var(--tailor-brand-text) 6%, transparent); }
|
|
333
|
+
.tailor-btn--dark { background: #000; color: #fff; }
|
|
334
|
+
.tailor-btn--dark:not(:disabled):hover { background: #333; }
|
|
335
|
+
:where(.dark, [data-theme="dark"]) .tailor-btn--dark { background: #fff; color: #000; }
|
|
336
|
+
:where(.dark, [data-theme="dark"]) .tailor-btn--dark:not(:disabled):hover { background: #E5E5E5; }
|
|
337
|
+
.tailor-btn--danger { background: #FF0040; color: #fff; }
|
|
338
|
+
.tailor-btn--danger:not(:disabled):hover { background: #D6003A; }
|
|
339
|
+
.tailor-btn__icon { display: inline-flex; width: 1.15em; height: 1.15em; }
|
|
340
|
+
.tailor-btn__icon > svg { width: 100%; height: 100%; }
|
|
341
|
+
.tailor-btn__dot { position: relative; display: inline-block; width: 1em; height: 1em; }
|
|
342
|
+
.tailor-btn__dot > span {
|
|
343
|
+
position: absolute; left: 0; top: 0; width: 38.2%; height: 38.2%; background: currentColor;
|
|
344
|
+
animation: tailor-loader-dot 1.236s steps(1, end) infinite;
|
|
345
|
+
}
|
|
346
|
+
.tailor-btn--secondary .tailor-btn__dot > span, .tailor-btn--ghost .tailor-btn__dot > span { background: var(--tailor-brand-primary); }
|
|
347
|
+
.tailor-btn__check { width: 1.15em; height: 1.15em; overflow: visible; stroke: currentColor; }
|
|
348
|
+
.tailor-btn__sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
|
349
|
+
|
|
303
350
|
/* PontoMalha e a malha da entrada: se desenham a partir do ponto e somem, em 2φ (3,236s). */
|
|
304
351
|
.tailor-malha__linha {
|
|
305
352
|
stroke-dasharray: 1;
|
|
@@ -427,7 +474,7 @@ textarea.tailor-field__control { padding: 8px 13px; min-height: 89px; }
|
|
|
427
474
|
@media (prefers-reduced-motion: reduce) {
|
|
428
475
|
.tailor-malha__linha { animation: none; stroke-dashoffset: 0; }
|
|
429
476
|
.tailor-loader__rastro, .tailor-loader__check, .tailor-loader__ok-malha .tailor-malha__linha { animation: none; stroke-dashoffset: 0; opacity: 1; }
|
|
430
|
-
.tailor-loader__corredor, .tailor-loader__volta { animation: none; }
|
|
477
|
+
.tailor-loader__corredor, .tailor-loader__volta, .tailor-loader__dot, .tailor-btn__dot > span { animation: none; }
|
|
431
478
|
.tailor-loader__ok-ponto { animation: none; opacity: 0; }
|
|
432
479
|
.tailor-skeleton::after { animation: none; display: none; }
|
|
433
480
|
.tailor-field--error .tailor-field__control { animation: none; }
|
|
@@ -9,6 +9,8 @@ export type TailorTheme = {
|
|
|
9
9
|
primary?: string;
|
|
10
10
|
/** Destaque como texto sobre o fundo (precisa de contraste; no Tailor é o verde-ink). */
|
|
11
11
|
primaryText?: string;
|
|
12
|
+
/** Texto sobre a primária (botão primário). Do whitelabel: preto ou branco, o que tiver mais contraste. */
|
|
13
|
+
onPrimary?: string;
|
|
12
14
|
text?: string;
|
|
13
15
|
textMuted?: string;
|
|
14
16
|
border?: string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type TailorButtonProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> & {
|
|
3
|
+
/** `primary`: a ação da vista (uma por tela). `secondary`: contorno. `ghost`: sem borda. `dark`: preto. `danger`: excluir. */
|
|
4
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'dark' | 'danger';
|
|
5
|
+
size?: 'sm' | 'md' | 'lg';
|
|
6
|
+
/** Ícone à esquerda. Sem `children`, o botão vira quadrado (passe `aria-label`). */
|
|
7
|
+
icon?: React.ReactNode;
|
|
8
|
+
/** Trocando o ícone pelo ponto correndo; o botão fica ocupado (`aria-busy`) e não aceita clique. */
|
|
9
|
+
loading?: boolean;
|
|
10
|
+
/** Texto enquanto carrega ("Salvando"). Sem ele, o texto não muda. */
|
|
11
|
+
loadingText?: React.ReactNode;
|
|
12
|
+
/** Mostra o check no lugar do ícone (ex.: "Salvo" por um instante). */
|
|
13
|
+
done?: boolean;
|
|
14
|
+
fullWidth?: boolean;
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Botão da marca: cantos retos, um primário por vista. Carregando, o ícone vira
|
|
19
|
+
* o ponto correndo (o mesmo do `TailorLoader`); concluído, vira o check. Use o
|
|
20
|
+
* `ref` como `origin` do `TailorResult` para o resultado nascer do botão.
|
|
21
|
+
* A cor do primário segue `--tailor-brand-primary` (a marca do cliente).
|
|
22
|
+
*/
|
|
23
|
+
export declare const TailorButton: React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
|
|
24
|
+
/** `primary`: a ação da vista (uma por tela). `secondary`: contorno. `ghost`: sem borda. `dark`: preto. `danger`: excluir. */
|
|
25
|
+
variant?: "primary" | "secondary" | "ghost" | "dark" | "danger";
|
|
26
|
+
size?: "sm" | "md" | "lg";
|
|
27
|
+
/** Ícone à esquerda. Sem `children`, o botão vira quadrado (passe `aria-label`). */
|
|
28
|
+
icon?: React.ReactNode;
|
|
29
|
+
/** Trocando o ícone pelo ponto correndo; o botão fica ocupado (`aria-busy`) e não aceita clique. */
|
|
30
|
+
loading?: boolean;
|
|
31
|
+
/** Texto enquanto carrega ("Salvando"). Sem ele, o texto não muda. */
|
|
32
|
+
loadingText?: React.ReactNode;
|
|
33
|
+
/** Mostra o check no lugar do ícone (ex.: "Salvo" por um instante). */
|
|
34
|
+
done?: boolean;
|
|
35
|
+
fullWidth?: boolean;
|
|
36
|
+
children?: React.ReactNode;
|
|
37
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -20,11 +20,12 @@ export type TailorLoaderProps = {
|
|
|
20
20
|
/**
|
|
21
21
|
* `inline`: no lugar do conteúdo. `overlay`: tela inteira, bloqueia.
|
|
22
22
|
* `compact`: uma linha (ponto + rótulo), para botões e listas.
|
|
23
|
+
* `dot`: só o ponto, do tamanho da fonte (1em), no lugar de um ícone; o rótulo vai para o leitor de tela.
|
|
23
24
|
* `box`: numa caixa própria de 377px, com fundo e borda — para painéis
|
|
24
25
|
* estreitos e fundos com estampa (chat), onde o inline ficaria transparente.
|
|
25
26
|
*/
|
|
26
27
|
/** `caixa` é o nome antigo de `box` (obsoleto). */
|
|
27
|
-
variant?: 'inline' | 'overlay' | 'compact' | 'box' | 'caixa';
|
|
28
|
+
variant?: 'inline' | 'overlay' | 'compact' | 'box' | 'dot' | 'caixa';
|
|
28
29
|
/** Troca a corrida pelo sucesso animado (a malha nasce verde e o ponto vira check). Rótulo padrão: o texto `done` do idioma. */
|
|
29
30
|
success?: boolean;
|
|
30
31
|
/** Tira o respiro externo do `inline`/`box` (quem chama já tem espaçamento). */
|
package/dist/types/index.d.ts
CHANGED
|
@@ -34,3 +34,5 @@ export { TailorLocaleProvider, useTailorLocale, TAILOR_MESSAGES } from './i18n';
|
|
|
34
34
|
export type { TailorLocaleProviderProps, TailorLocale, TailorMessages } from './i18n';
|
|
35
35
|
export { TailorField } from './components/TailorField';
|
|
36
36
|
export type { TailorFieldProps } from './components/TailorField';
|
|
37
|
+
export { TailorButton } from './components/TailorButton';
|
|
38
|
+
export type { TailorButtonProps } from './components/TailorButton';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ffid-br/tailor-ui",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"description": "Primitivos de marca Tailor.ia em React: loader, intro, transição de login, lockup e barra lateral.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.umd.js",
|