@ffid-br/tailor-ui 0.7.1 → 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/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;
@@ -308,6 +309,44 @@ textarea.tailor-field__control { padding: 8px 13px; min-height: 89px; }
308
309
  @keyframes tailor-user-menu-out { from { clip-path: inset(0); } to { clip-path: inset(calc(100% - 8px) calc(100% - 8px) 0 0); } }
309
310
  @keyframes tailor-user-menu-dot { 0%, 61.8% { opacity: 1; } 100% { opacity: 0; } }
310
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
+
311
350
  /* PontoMalha e a malha da entrada: se desenham a partir do ponto e somem, em 2φ (3,236s). */
312
351
  .tailor-malha__linha {
313
352
  stroke-dasharray: 1;
@@ -435,7 +474,7 @@ textarea.tailor-field__control { padding: 8px 13px; min-height: 89px; }
435
474
  @media (prefers-reduced-motion: reduce) {
436
475
  .tailor-malha__linha { animation: none; stroke-dashoffset: 0; }
437
476
  .tailor-loader__rastro, .tailor-loader__check, .tailor-loader__ok-malha .tailor-malha__linha { animation: none; stroke-dashoffset: 0; opacity: 1; }
438
- .tailor-loader__corredor, .tailor-loader__volta, .tailor-loader__dot { animation: none; }
477
+ .tailor-loader__corredor, .tailor-loader__volta, .tailor-loader__dot, .tailor-btn__dot > span { animation: none; }
439
478
  .tailor-loader__ok-ponto { animation: none; opacity: 0; }
440
479
  .tailor-skeleton::after { animation: none; display: none; }
441
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>>;
@@ -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.7.1",
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",