@sbkbs/ui 2.0.0-beta.0 → 2.0.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/CHANGELOG.md +57 -57
- package/dist/assets/favicon/site.webmanifest +21 -21
- package/dist/base.css +38 -38
- package/dist/components/Accordion/Accordion.js.map +1 -1
- package/dist/components/Alert/Alert.js.map +1 -1
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -1
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/Chip/Chip.js.map +1 -1
- package/dist/components/Combobox/Combobox.js.map +1 -1
- package/dist/components/Divider/Divider.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/Field/Field.js.map +1 -1
- package/dist/components/FileUpload/FileUpload.js.map +1 -1
- package/dist/components/Footer/Footer.js.map +1 -1
- package/dist/components/GlassPanel/GlassPanel.js.map +1 -1
- package/dist/components/Header/Header.js.map +1 -1
- package/dist/components/Highlight/Highlight.js.map +1 -1
- package/dist/components/Icon/Icon.js.map +1 -1
- package/dist/components/IconButton/IconButton.js.map +1 -1
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/Layout/Layout.js.map +1 -1
- package/dist/components/Logo/Logo.js.map +1 -1
- package/dist/components/MiniCard/MiniCard.js.map +1 -1
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/Navigation/Navigation.js.map +1 -1
- package/dist/components/NumberInput/NumberInput.js.map +1 -1
- package/dist/components/PageHeader/PageHeader.js.map +1 -1
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/Paragraph/Paragraph.js.map +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.js.map +1 -1
- package/dist/components/Radio/Radio.js.map +1 -1
- package/dist/components/SectionHeader/SectionHeader.js.map +1 -1
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/SideNav/SideNav.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Spinner/Spinner.js.map +1 -1
- package/dist/components/Stepper/Stepper.js.map +1 -1
- package/dist/components/Subtitle/Subtitle.js.map +1 -1
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/components/Title/Title.js.map +1 -1
- package/dist/components/Toast/Toast.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/Typography/weight.js.map +1 -1
- package/dist/fonts.css +8 -8
- package/dist/index.cjs.map +1 -1
- package/dist/reset.css +9 -9
- package/dist/tailwind.css +153 -153
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/tokens.js.map +1 -1
- package/dist/theme.css +327 -327
- package/dist/tokens.css +327 -327
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/styles.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## [2.0.0] - 2026-09-
|
|
4
|
-
|
|
5
|
-
Alinhamento ao Brand Book SBK 2026. Contém mudanças incompatíveis: veja o [guia de migração](./MIGRATION.md).
|
|
6
|
-
|
|
7
|
-
### Breaking
|
|
8
|
-
|
|
9
|
-
- Paleta substituída pela oficial 2026 (Verde Escuro `#023631`, Ciano Escuro `#075056`, Off White `#ECEFF3`, Verde Claro `#0A5A52` e secundárias). Turquesa `#01B2AA`, paleta "O Criador" e gradiente turquesa removidos.
|
|
10
|
-
- Tema padrão SBK IA (primária Verde Claro). Tema institucional SBK via `data-brand="sbk"`.
|
|
11
|
-
- Tipografia restrita aos pesos 300 (corpo) e 600 (títulos). Sora removida.
|
|
12
|
-
- Componentes leem apenas tokens `--sbk-*`. Nomes da 1.x (`--md-*`, `--brand-*`, `--bg-*`, `--text-*`) permanecem como aliases deprecados.
|
|
13
|
-
- A lib não importa mais a fonte (use `@sbkbs/ui/fonts.css`) e não inclui mais o preflight do Tailwind no `styles.css`.
|
|
14
|
-
- `Button`: prop `palette` removida; `type="button"` por padrão; loading preserva a largura.
|
|
15
|
-
- `Title`: prop `gradient` removida; padrões de peso passam a 600 (títulos/subtítulos) e 300 (parágrafos).
|
|
16
|
-
- `Alert` informativo usa `role="status"`. `Modal` com `role="dialog"` no painel e renderizado em portal.
|
|
17
|
-
- Build CJS renomeado de `oficios-ui.umd.cjs` para `index.cjs`; CSS de `oficios-ui.css` para `styles.css` (os subpaths do `exports` continuam os mesmos).
|
|
18
|
-
|
|
19
|
-
### Added
|
|
20
|
-
|
|
21
|
-
- Arquitetura de estilos híbrida: tokens em CSS custom properties + preset Tailwind CSS v4 (`@sbkbs/ui/tailwind.css`), com namespace `sbk`.
|
|
22
|
-
- Novos entrypoints: `tokens.css`, `tailwind.css`, `base.css`, `fonts.css`, `reset.css`, `assets/favicon/*`.
|
|
23
|
-
- Tokens `--sbk-color-{success,warning,error,info}-fg` para texto e ícones de estado com contraste nos dois temas.
|
|
24
|
-
- Novos componentes: `Logo` (SVGs oficiais SBK e SBK IA, zona de respiro), `Icon` (lucide-react), `IconButton`, `MiniCard`, `GlassPanel`, `Highlight`, `SideNav`, `DropdownMenu`, `Field`, subcomponentes de `Card`.
|
|
25
|
-
- Exportados componentes que existiam sem export: `Avatar`, `Divider`, `ProgressBar`, `Spinner`.
|
|
26
|
-
- Superfície Liquid Glass (`sbk-glass`) com fallback para `prefers-reduced-transparency` e navegadores sem `backdrop-filter`; `variant="glass"` em Button, IconButton, Card, MiniCard, Header, Footer, SideNav, Modal, Popover, DropdownMenu e Toast.
|
|
27
|
-
- `ThemeProvider`: modo `system`, troca de marca (`setBrand`), `storageKey` configurável e acesso seguro ao `localStorage`.
|
|
28
|
-
- `ProgressBar` indeterminado; `Skeleton` de texto; `Spinner` com label visível.
|
|
29
|
-
- `Pagination` com reticências e variante `simple`; `Tabs` com variante `line` e modo controlado; `Accordion` com `type="multiple"`.
|
|
30
|
-
- `Toast`: ícones por tom, ação, posições, limite de itens e pausa do timer em hover/foco.
|
|
31
|
-
- Tokens em TypeScript: `sbkTokens` e `sbkChartPalette`.
|
|
32
|
-
- Favicons oficiais no playground, Storybook e pacote.
|
|
33
|
-
- Storybook com alternância de tema e marca na toolbar; stories para as peças novas e fundamentos.
|
|
34
|
-
|
|
35
|
-
### Fixed
|
|
36
|
-
|
|
37
|
-
- IDs gerados com `Math.random()` a cada render (Input, Select, Combobox e outros) substituídos por `useId`. O Combobox mudava de ID a cada tecla.
|
|
38
|
-
- `id="modal-title"` fixo colidia com múltiplos modais.
|
|
39
|
-
- Anel de foco azul fixo (`rgba(47,93,140)`) trocado pelo token de foco da marca.
|
|
40
|
-
- `public/` deixou de ser copiado para `dist/`.
|
|
41
|
-
- `.d.ts` dos stories deixou de ser publicado; classes usadas só em stories não entram mais no `styles.css`.
|
|
42
|
-
- Testes E2E (Playwright) atualizados para o playground atual. Os 9 que falhavam já falhavam na 1.0.6.
|
|
43
|
-
|
|
44
|
-
## [1.0.2] - 2026-03-24
|
|
45
|
-
|
|
46
|
-
### Added
|
|
47
|
-
|
|
48
|
-
- Playground modernizado com navegação, exemplos e blocos copiáveis.
|
|
49
|
-
- Novos componentes base (feedback, form e layout).
|
|
50
|
-
- Componentes avançados: tooltip, popover, tabs, accordion, toast, table e pagination.
|
|
51
|
-
- Setup inicial de testes com Vitest + Testing Library.
|
|
52
|
-
- Setup inicial de Storybook com addon de acessibilidade.
|
|
53
|
-
|
|
54
|
-
### Changed
|
|
55
|
-
|
|
56
|
-
- Migração de componentes para abordagem utilitária (Tailwind classes).
|
|
57
|
-
- Refinos de tema dark mode e contraste.
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [2.0.0] - 2026-09-25
|
|
4
|
+
|
|
5
|
+
Alinhamento ao Brand Book SBK 2026. Contém mudanças incompatíveis: veja o [guia de migração](./MIGRATION.md).
|
|
6
|
+
|
|
7
|
+
### Breaking
|
|
8
|
+
|
|
9
|
+
- Paleta substituída pela oficial 2026 (Verde Escuro `#023631`, Ciano Escuro `#075056`, Off White `#ECEFF3`, Verde Claro `#0A5A52` e secundárias). Turquesa `#01B2AA`, paleta "O Criador" e gradiente turquesa removidos.
|
|
10
|
+
- Tema padrão SBK IA (primária Verde Claro). Tema institucional SBK via `data-brand="sbk"`.
|
|
11
|
+
- Tipografia restrita aos pesos 300 (corpo) e 600 (títulos). Sora removida.
|
|
12
|
+
- Componentes leem apenas tokens `--sbk-*`. Nomes da 1.x (`--md-*`, `--brand-*`, `--bg-*`, `--text-*`) permanecem como aliases deprecados.
|
|
13
|
+
- A lib não importa mais a fonte (use `@sbkbs/ui/fonts.css`) e não inclui mais o preflight do Tailwind no `styles.css`.
|
|
14
|
+
- `Button`: prop `palette` removida; `type="button"` por padrão; loading preserva a largura.
|
|
15
|
+
- `Title`: prop `gradient` removida; padrões de peso passam a 600 (títulos/subtítulos) e 300 (parágrafos).
|
|
16
|
+
- `Alert` informativo usa `role="status"`. `Modal` com `role="dialog"` no painel e renderizado em portal.
|
|
17
|
+
- Build CJS renomeado de `oficios-ui.umd.cjs` para `index.cjs`; CSS de `oficios-ui.css` para `styles.css` (os subpaths do `exports` continuam os mesmos).
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Arquitetura de estilos híbrida: tokens em CSS custom properties + preset Tailwind CSS v4 (`@sbkbs/ui/tailwind.css`), com namespace `sbk`.
|
|
22
|
+
- Novos entrypoints: `tokens.css`, `tailwind.css`, `base.css`, `fonts.css`, `reset.css`, `assets/favicon/*`.
|
|
23
|
+
- Tokens `--sbk-color-{success,warning,error,info}-fg` para texto e ícones de estado com contraste nos dois temas.
|
|
24
|
+
- Novos componentes: `Logo` (SVGs oficiais SBK e SBK IA, zona de respiro), `Icon` (lucide-react), `IconButton`, `MiniCard`, `GlassPanel`, `Highlight`, `SideNav`, `DropdownMenu`, `Field`, subcomponentes de `Card`.
|
|
25
|
+
- Exportados componentes que existiam sem export: `Avatar`, `Divider`, `ProgressBar`, `Spinner`.
|
|
26
|
+
- Superfície Liquid Glass (`sbk-glass`) com fallback para `prefers-reduced-transparency` e navegadores sem `backdrop-filter`; `variant="glass"` em Button, IconButton, Card, MiniCard, Header, Footer, SideNav, Modal, Popover, DropdownMenu e Toast.
|
|
27
|
+
- `ThemeProvider`: modo `system`, troca de marca (`setBrand`), `storageKey` configurável e acesso seguro ao `localStorage`.
|
|
28
|
+
- `ProgressBar` indeterminado; `Skeleton` de texto; `Spinner` com label visível.
|
|
29
|
+
- `Pagination` com reticências e variante `simple`; `Tabs` com variante `line` e modo controlado; `Accordion` com `type="multiple"`.
|
|
30
|
+
- `Toast`: ícones por tom, ação, posições, limite de itens e pausa do timer em hover/foco.
|
|
31
|
+
- Tokens em TypeScript: `sbkTokens` e `sbkChartPalette`.
|
|
32
|
+
- Favicons oficiais no playground, Storybook e pacote.
|
|
33
|
+
- Storybook com alternância de tema e marca na toolbar; stories para as peças novas e fundamentos.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- IDs gerados com `Math.random()` a cada render (Input, Select, Combobox e outros) substituídos por `useId`. O Combobox mudava de ID a cada tecla.
|
|
38
|
+
- `id="modal-title"` fixo colidia com múltiplos modais.
|
|
39
|
+
- Anel de foco azul fixo (`rgba(47,93,140)`) trocado pelo token de foco da marca.
|
|
40
|
+
- `public/` deixou de ser copiado para `dist/`.
|
|
41
|
+
- `.d.ts` dos stories deixou de ser publicado; classes usadas só em stories não entram mais no `styles.css`.
|
|
42
|
+
- Testes E2E (Playwright) atualizados para o playground atual. Os 9 que falhavam já falhavam na 1.0.6.
|
|
43
|
+
|
|
44
|
+
## [1.0.2] - 2026-03-24
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- Playground modernizado com navegação, exemplos e blocos copiáveis.
|
|
49
|
+
- Novos componentes base (feedback, form e layout).
|
|
50
|
+
- Componentes avançados: tooltip, popover, tabs, accordion, toast, table e pagination.
|
|
51
|
+
- Setup inicial de testes com Vitest + Testing Library.
|
|
52
|
+
- Setup inicial de Storybook com addon de acessibilidade.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Migração de componentes para abordagem utilitária (Tailwind classes).
|
|
57
|
+
- Refinos de tema dark mode e contraste.
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "SBK",
|
|
3
|
-
"short_name": "SBK",
|
|
4
|
-
"icons": [
|
|
5
|
-
{
|
|
6
|
-
"src": "/web-app-manifest-192x192.png",
|
|
7
|
-
"sizes": "192x192",
|
|
8
|
-
"type": "image/png",
|
|
9
|
-
"purpose": "maskable"
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"src": "/web-app-manifest-512x512.png",
|
|
13
|
-
"sizes": "512x512",
|
|
14
|
-
"type": "image/png",
|
|
15
|
-
"purpose": "maskable"
|
|
16
|
-
}
|
|
17
|
-
],
|
|
18
|
-
"theme_color": "#023631",
|
|
19
|
-
"background_color": "#ECEFF3",
|
|
20
|
-
"display": "standalone"
|
|
21
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "SBK",
|
|
3
|
+
"short_name": "SBK",
|
|
4
|
+
"icons": [
|
|
5
|
+
{
|
|
6
|
+
"src": "/web-app-manifest-192x192.png",
|
|
7
|
+
"sizes": "192x192",
|
|
8
|
+
"type": "image/png",
|
|
9
|
+
"purpose": "maskable"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"src": "/web-app-manifest-512x512.png",
|
|
13
|
+
"sizes": "512x512",
|
|
14
|
+
"type": "image/png",
|
|
15
|
+
"purpose": "maskable"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"theme_color": "#023631",
|
|
19
|
+
"background_color": "#ECEFF3",
|
|
20
|
+
"display": "standalone"
|
|
21
|
+
}
|
package/dist/base.css
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
/* ============================================================
|
|
2
|
-
@sbkbs/ui · Base opcional (import '@sbkbs/ui/base.css')
|
|
3
|
-
Aplica fonte, pesos e fundo da marca ao documento.
|
|
4
|
-
Especificidade zero (:where) para o app sobrescrever sem esforço.
|
|
5
|
-
============================================================ */
|
|
6
|
-
|
|
7
|
-
@layer base {
|
|
8
|
-
:where(html) {
|
|
9
|
-
font-family: var(--sbk-font-family);
|
|
10
|
-
-webkit-font-smoothing: antialiased;
|
|
11
|
-
-moz-osx-font-smoothing: grayscale;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
:where(body) {
|
|
15
|
-
margin: 0;
|
|
16
|
-
background-color: var(--sbk-color-bg);
|
|
17
|
-
color: var(--sbk-color-fg);
|
|
18
|
-
font-weight: var(--sbk-font-weight-body);
|
|
19
|
-
line-height: 1.5;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
:where(h1, h2, h3, h4, h5, h6, strong, b, th) {
|
|
23
|
-
font-weight: var(--sbk-font-weight-heading);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
:where(h1, h2, h3, h4, h5, h6) {
|
|
27
|
-
color: var(--sbk-color-fg-heading);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@media (prefers-reduced-motion: reduce) {
|
|
31
|
-
:where(*, *::before, *::after) {
|
|
32
|
-
animation-duration: 0.01ms !important;
|
|
33
|
-
animation-iteration-count: 1 !important;
|
|
34
|
-
transition-duration: 0.01ms !important;
|
|
35
|
-
scroll-behavior: auto !important;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
1
|
+
/* ============================================================
|
|
2
|
+
@sbkbs/ui · Base opcional (import '@sbkbs/ui/base.css')
|
|
3
|
+
Aplica fonte, pesos e fundo da marca ao documento.
|
|
4
|
+
Especificidade zero (:where) para o app sobrescrever sem esforço.
|
|
5
|
+
============================================================ */
|
|
6
|
+
|
|
7
|
+
@layer base {
|
|
8
|
+
:where(html) {
|
|
9
|
+
font-family: var(--sbk-font-family);
|
|
10
|
+
-webkit-font-smoothing: antialiased;
|
|
11
|
+
-moz-osx-font-smoothing: grayscale;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:where(body) {
|
|
15
|
+
margin: 0;
|
|
16
|
+
background-color: var(--sbk-color-bg);
|
|
17
|
+
color: var(--sbk-color-fg);
|
|
18
|
+
font-weight: var(--sbk-font-weight-body);
|
|
19
|
+
line-height: 1.5;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
:where(h1, h2, h3, h4, h5, h6, strong, b, th) {
|
|
23
|
+
font-weight: var(--sbk-font-weight-heading);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
:where(h1, h2, h3, h4, h5, h6) {
|
|
27
|
+
color: var(--sbk-color-fg-heading);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@media (prefers-reduced-motion: reduce) {
|
|
31
|
+
:where(*, *::before, *::after) {
|
|
32
|
+
animation-duration: 0.01ms !important;
|
|
33
|
+
animation-iteration-count: 1 !important;
|
|
34
|
+
transition-duration: 0.01ms !important;
|
|
35
|
+
scroll-behavior: auto !important;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.js","sources":["../../../src/components/Accordion/Accordion.tsx"],"sourcesContent":["import type React from 'react';\nimport { useId, useRef, useState } from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, transitionColors } from '../../utils/styles';\n\nexport interface AccordionItem {\n content: React.ReactNode;\n disabled?: boolean;\n id: string;\n title: React.ReactNode;\n}\n\nexport interface AccordionProps {\n className?: string;\n /** Item aberto inicialmente (modo single). */\n defaultOpenId?: string;\n /** Itens abertos inicialmente (modo multiple). */\n defaultOpenIds?: string[];\n items: AccordionItem[];\n /** `single`: um item aberto por vez. `multiple`: vários. Padrão: single. */\n type?: 'single' | 'multiple';\n /** `separated`: cards independentes. `flush`: lista contínua com divisórias. */\n variant?: 'separated' | 'flush';\n}\n\nexport const Accordion = ({\n items,\n defaultOpenId,\n defaultOpenIds,\n type = 'single',\n variant = 'separated',\n className,\n}: AccordionProps) => {\n const [openIds, setOpenIds] = useState<string[]>(\n defaultOpenIds ?? (defaultOpenId ? [defaultOpenId] : []),\n );\n const rootRef = useRef<HTMLDivElement>(null);\n const baseId = useId();\n\n const toggle = (id: string) =>\n setOpenIds((prev) =>\n prev.includes(id) ? prev.filter((x) => x !== id) : type === 'single' ? [id] : [...prev, id],\n );\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n const buttons = Array.from(\n rootRef.current?.querySelectorAll<HTMLButtonElement>(\n '[data-accordion-trigger]:not(:disabled)',\n ) ?? [],\n );\n const index = buttons.indexOf(event.currentTarget);\n const targets: Record<string, number> = {\n ArrowDown: (index + 1) % buttons.length,\n ArrowUp: (index - 1 + buttons.length) % buttons.length,\n Home: 0,\n End: buttons.length - 1,\n };\n if (event.key in targets) {\n event.preventDefault();\n buttons[targets[event.key]]?.focus();\n }\n };\n\n return (\n <div\n ref={rootRef}\n className={cn(\n variant === 'separated'\n ? 'grid gap-2'\n : 'divide-y divide-sbk-line overflow-hidden rounded-sbk-sm border border-sbk-line',\n className,\n )}\n >\n {items.map((item) => {\n const isOpen = openIds.includes(item.id);\n const triggerId = `${baseId}-trigger-${item.id}`;\n const panelId = `${baseId}-panel-${item.id}`;\n return (\n <div\n key={item.id}\n className={cn(\n variant === 'separated' && 'overflow-hidden rounded-sbk-sm border border-sbk-line',\n 'bg-sbk-surface',\n )}\n >\n <h3 className=\"m-0\">\n <button\n aria-controls={panelId}\n aria-expanded={isOpen}\n className={cn(\n buttonReset,\n 'flex w-full cursor-pointer items-center justify-between gap-3 px-4 py-3 text-left text-sm font-semibold text-sbk-fg hover:bg-sbk-surface-hover disabled:cursor-not-allowed disabled:opacity-50',\n 'focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-sbk-focus focus-visible:outline-solid',\n transitionColors,\n )}\n data-accordion-trigger=\"\"\n disabled={item.disabled}\n id={triggerId}\n onClick={() => toggle(item.id)}\n onKeyDown={onKeyDown}\n type=\"button\"\n >\n {item.title}\n <ChevronDown\n aria-hidden=\"true\"\n className={cn(\n 'size-4 shrink-0 text-sbk-fg-muted transition-transform duration-200 motion-reduce:transition-none',\n isOpen && 'rotate-180',\n )}\n />\n </button>\n </h3>\n {isOpen && (\n <div\n aria-labelledby={triggerId}\n className=\"px-4 pb-4 pt-1 text-sm font-light text-sbk-fg-muted animate-sbk-fade-in motion-reduce:animate-none\"\n id={panelId}\n role=\"region\"\n >\n {item.content}\n </div>\n )}\n </div>\n );\n })}\n </div>\n );\n};\n\nAccordion.displayName = 'Accordion';\n"],"names":["Accordion","items","defaultOpenId","defaultOpenIds","type","variant","className","openIds","setOpenIds","useState","rootRef","useRef","baseId","useId","toggle","id","prev","x","onKeyDown","event","buttons","_a","index","targets","_b","jsx","cn","item","isOpen","triggerId","panelId","jsxs","buttonReset","transitionColors","ChevronDown"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Accordion.js","sources":["../../../src/components/Accordion/Accordion.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { useId, useRef, useState } from 'react';\r\nimport { ChevronDown } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, transitionColors } from '../../utils/styles';\r\n\r\nexport interface AccordionItem {\r\n content: React.ReactNode;\r\n disabled?: boolean;\r\n id: string;\r\n title: React.ReactNode;\r\n}\r\n\r\nexport interface AccordionProps {\r\n className?: string;\r\n /** Item aberto inicialmente (modo single). */\r\n defaultOpenId?: string;\r\n /** Itens abertos inicialmente (modo multiple). */\r\n defaultOpenIds?: string[];\r\n items: AccordionItem[];\r\n /** `single`: um item aberto por vez. `multiple`: vários. Padrão: single. */\r\n type?: 'single' | 'multiple';\r\n /** `separated`: cards independentes. `flush`: lista contínua com divisórias. */\r\n variant?: 'separated' | 'flush';\r\n}\r\n\r\nexport const Accordion = ({\r\n items,\r\n defaultOpenId,\r\n defaultOpenIds,\r\n type = 'single',\r\n variant = 'separated',\r\n className,\r\n}: AccordionProps) => {\r\n const [openIds, setOpenIds] = useState<string[]>(\r\n defaultOpenIds ?? (defaultOpenId ? [defaultOpenId] : []),\r\n );\r\n const rootRef = useRef<HTMLDivElement>(null);\r\n const baseId = useId();\r\n\r\n const toggle = (id: string) =>\r\n setOpenIds((prev) =>\r\n prev.includes(id) ? prev.filter((x) => x !== id) : type === 'single' ? [id] : [...prev, id],\r\n );\r\n\r\n const onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\r\n const buttons = Array.from(\r\n rootRef.current?.querySelectorAll<HTMLButtonElement>(\r\n '[data-accordion-trigger]:not(:disabled)',\r\n ) ?? [],\r\n );\r\n const index = buttons.indexOf(event.currentTarget);\r\n const targets: Record<string, number> = {\r\n ArrowDown: (index + 1) % buttons.length,\r\n ArrowUp: (index - 1 + buttons.length) % buttons.length,\r\n Home: 0,\r\n End: buttons.length - 1,\r\n };\r\n if (event.key in targets) {\r\n event.preventDefault();\r\n buttons[targets[event.key]]?.focus();\r\n }\r\n };\r\n\r\n return (\r\n <div\r\n ref={rootRef}\r\n className={cn(\r\n variant === 'separated'\r\n ? 'grid gap-2'\r\n : 'divide-y divide-sbk-line overflow-hidden rounded-sbk-sm border border-sbk-line',\r\n className,\r\n )}\r\n >\r\n {items.map((item) => {\r\n const isOpen = openIds.includes(item.id);\r\n const triggerId = `${baseId}-trigger-${item.id}`;\r\n const panelId = `${baseId}-panel-${item.id}`;\r\n return (\r\n <div\r\n key={item.id}\r\n className={cn(\r\n variant === 'separated' && 'overflow-hidden rounded-sbk-sm border border-sbk-line',\r\n 'bg-sbk-surface',\r\n )}\r\n >\r\n <h3 className=\"m-0\">\r\n <button\r\n aria-controls={panelId}\r\n aria-expanded={isOpen}\r\n className={cn(\r\n buttonReset,\r\n 'flex w-full cursor-pointer items-center justify-between gap-3 px-4 py-3 text-left text-sm font-semibold text-sbk-fg hover:bg-sbk-surface-hover disabled:cursor-not-allowed disabled:opacity-50',\r\n 'focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-sbk-focus focus-visible:outline-solid',\r\n transitionColors,\r\n )}\r\n data-accordion-trigger=\"\"\r\n disabled={item.disabled}\r\n id={triggerId}\r\n onClick={() => toggle(item.id)}\r\n onKeyDown={onKeyDown}\r\n type=\"button\"\r\n >\r\n {item.title}\r\n <ChevronDown\r\n aria-hidden=\"true\"\r\n className={cn(\r\n 'size-4 shrink-0 text-sbk-fg-muted transition-transform duration-200 motion-reduce:transition-none',\r\n isOpen && 'rotate-180',\r\n )}\r\n />\r\n </button>\r\n </h3>\r\n {isOpen && (\r\n <div\r\n aria-labelledby={triggerId}\r\n className=\"px-4 pb-4 pt-1 text-sm font-light text-sbk-fg-muted animate-sbk-fade-in motion-reduce:animate-none\"\r\n id={panelId}\r\n role=\"region\"\r\n >\r\n {item.content}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n\r\nAccordion.displayName = 'Accordion';\r\n"],"names":["Accordion","items","defaultOpenId","defaultOpenIds","type","variant","className","openIds","setOpenIds","useState","rootRef","useRef","baseId","useId","toggle","id","prev","x","onKeyDown","event","buttons","_a","index","targets","_b","jsx","cn","item","isOpen","triggerId","panelId","jsxs","buttonReset","transitionColors","ChevronDown"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert.js","sources":["../../../src/components/Alert/Alert.tsx"],"sourcesContent":["import type React from 'react';\nimport { AlertTriangle, CheckCircle2, Info, X, XCircle } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, focusRing } from '../../utils/styles';\n\nexport type AlertTone = 'info' | 'success' | 'warning' | 'error';\n\nexport interface AlertProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Ações (botões/links) exibidas abaixo do texto. */\n action?: React.ReactNode;\n /** Ícone customizado. `false` remove o ícone. */\n icon?: React.ReactNode | false;\n onClose?: () => void;\n title?: React.ReactNode;\n tone?: AlertTone;\n}\n\nconst TONE: Record<AlertTone, { box: string; icon: string; Icon: typeof Info }> = {\n info: { box: 'border-sbk-info/30 bg-sbk-info-subtle', icon: 'text-sbk-info-fg', Icon: Info },\n success: {\n box: 'border-sbk-success/30 bg-sbk-success-subtle',\n icon: 'text-sbk-success-fg',\n Icon: CheckCircle2,\n },\n warning: {\n box: 'border-sbk-warning/30 bg-sbk-warning-subtle',\n icon: 'text-sbk-warning-fg',\n Icon: AlertTriangle,\n },\n error: {\n box: 'border-sbk-error/30 bg-sbk-error-subtle',\n icon: 'text-sbk-error-fg',\n Icon: XCircle,\n },\n};\n\n/**\n * Mensagem de feedback persistente na página.\n * `error` e `warning` usam role=\"alert\" (anúncio imediato); `info` e `success` usam role=\"status\".\n */\nexport const Alert = ({\n title,\n tone = 'info',\n icon,\n action,\n onClose,\n children,\n className,\n role,\n ...props\n}: AlertProps) => {\n const { box, icon: iconColor, Icon } = TONE[tone];\n const urgent = tone === 'error' || tone === 'warning';\n\n return (\n <div\n className={cn('flex items-start gap-3 rounded-sbk-sm border p-4 text-sbk-fg', box, className)}\n role={role ?? (urgent ? 'alert' : 'status')}\n {...props}\n >\n {icon !== false && (\n <span\n aria-hidden=\"true\"\n className={cn('mt-0.5 inline-flex shrink-0 [&_svg]:size-5', iconColor)}\n >\n {icon ?? <Icon strokeWidth={1.75} />}\n </span>\n )}\n <div className=\"grid min-w-0 flex-1 gap-1\">\n {title && <p className=\"m-0 text-sm font-semibold text-sbk-fg-heading\">{title}</p>}\n {children && <div className=\"text-sm font-light leading-relaxed\">{children}</div>}\n {action && <div className=\"mt-2 flex flex-wrap gap-2\">{action}</div>}\n </div>\n {onClose && (\n <button\n aria-label=\"Fechar alerta\"\n className={cn(\n buttonReset,\n 'inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-sbk-xs text-sbk-fg-muted hover:bg-sbk-surface-hover hover:text-sbk-fg',\n focusRing,\n )}\n onClick={onClose}\n type=\"button\"\n >\n <X aria-hidden=\"true\" className=\"size-4\" />\n </button>\n )}\n </div>\n );\n};\n\nAlert.displayName = 'Alert';\n"],"names":["TONE","Info","CheckCircle2","AlertTriangle","XCircle","Alert","title","tone","icon","action","onClose","children","className","role","props","box","iconColor","Icon","urgent","jsxs","cn","jsx","buttonReset","focusRing","X"],"mappings":";;;;AAiBA,MAAMA,IAA4E;AAAA,EAChF,MAAM,EAAE,KAAK,yCAAyC,MAAM,oBAAoB,MAAMC,EAAA;AAAA,EACtF,SAAS;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAMC;AAAA,EAAA;AAAA,EAER,SAAS;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAMC;AAAA,EAAA;AAAA,EAER,OAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAMC;AAAA,EAAA;AAEV,GAMaC,IAAQ,CAAC;AAAA,EACpB,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,MAAAC;AAAA,EACA,GAAGC;AACL,MAAkB;AAChB,QAAM,EAAE,KAAAC,GAAK,MAAMC,GAAW,MAAAC,EAAA,IAASjB,EAAKO,CAAI,GAC1CW,IAASX,MAAS,WAAWA,MAAS;AAE5C,SACE,gBAAAY;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAG,gEAAgEL,GAAKH,CAAS;AAAA,MAC5F,MAAMC,MAASK,IAAS,UAAU;AAAA,MACjC,GAAGJ;AAAA,MAEH,UAAA;AAAA,QAAAN,MAAS,MACR,gBAAAa;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAWD,EAAG,8CAA8CJ,CAAS;AAAA,YAEpE,UAAAR,KAAQ,gBAAAa,EAACJ,GAAA,EAAK,aAAa,KAAA,CAAM;AAAA,UAAA;AAAA,QAAA;AAAA,QAGtC,gBAAAE,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,UAAAb,KAAS,gBAAAe,EAAC,KAAA,EAAE,WAAU,iDAAiD,UAAAf,GAAM;AAAA,UAC7EK,KAAY,gBAAAU,EAAC,OAAA,EAAI,WAAU,sCAAsC,UAAAV,GAAS;AAAA,UAC1EF,KAAU,gBAAAY,EAAC,OAAA,EAAI,WAAU,6BAA6B,UAAAZ,EAAA,CAAO;AAAA,QAAA,GAChE;AAAA,QACCC,KACC,gBAAAW;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAW;AAAA,YACX,WAAWD;AAAA,cACTE;AAAA,cACA;AAAA,cACAC;AAAA,YAAA;AAAA,YAEF,SAASb;AAAA,YACT,MAAK;AAAA,YAEL,UAAA,gBAAAW,EAACG,GAAA,EAAE,eAAY,QAAO,WAAU,SAAA,CAAS;AAAA,UAAA;AAAA,QAAA;AAAA,MAC3C;AAAA,IAAA;AAAA,EAAA;AAIR;AAEAnB,EAAM,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Alert.js","sources":["../../../src/components/Alert/Alert.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { AlertTriangle, CheckCircle2, Info, X, XCircle } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, focusRing } from '../../utils/styles';\r\n\r\nexport type AlertTone = 'info' | 'success' | 'warning' | 'error';\r\n\r\nexport interface AlertProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\r\n /** Ações (botões/links) exibidas abaixo do texto. */\r\n action?: React.ReactNode;\r\n /** Ícone customizado. `false` remove o ícone. */\r\n icon?: React.ReactNode | false;\r\n onClose?: () => void;\r\n title?: React.ReactNode;\r\n tone?: AlertTone;\r\n}\r\n\r\nconst TONE: Record<AlertTone, { box: string; icon: string; Icon: typeof Info }> = {\r\n info: { box: 'border-sbk-info/30 bg-sbk-info-subtle', icon: 'text-sbk-info-fg', Icon: Info },\r\n success: {\r\n box: 'border-sbk-success/30 bg-sbk-success-subtle',\r\n icon: 'text-sbk-success-fg',\r\n Icon: CheckCircle2,\r\n },\r\n warning: {\r\n box: 'border-sbk-warning/30 bg-sbk-warning-subtle',\r\n icon: 'text-sbk-warning-fg',\r\n Icon: AlertTriangle,\r\n },\r\n error: {\r\n box: 'border-sbk-error/30 bg-sbk-error-subtle',\r\n icon: 'text-sbk-error-fg',\r\n Icon: XCircle,\r\n },\r\n};\r\n\r\n/**\r\n * Mensagem de feedback persistente na página.\r\n * `error` e `warning` usam role=\"alert\" (anúncio imediato); `info` e `success` usam role=\"status\".\r\n */\r\nexport const Alert = ({\r\n title,\r\n tone = 'info',\r\n icon,\r\n action,\r\n onClose,\r\n children,\r\n className,\r\n role,\r\n ...props\r\n}: AlertProps) => {\r\n const { box, icon: iconColor, Icon } = TONE[tone];\r\n const urgent = tone === 'error' || tone === 'warning';\r\n\r\n return (\r\n <div\r\n className={cn('flex items-start gap-3 rounded-sbk-sm border p-4 text-sbk-fg', box, className)}\r\n role={role ?? (urgent ? 'alert' : 'status')}\r\n {...props}\r\n >\r\n {icon !== false && (\r\n <span\r\n aria-hidden=\"true\"\r\n className={cn('mt-0.5 inline-flex shrink-0 [&_svg]:size-5', iconColor)}\r\n >\r\n {icon ?? <Icon strokeWidth={1.75} />}\r\n </span>\r\n )}\r\n <div className=\"grid min-w-0 flex-1 gap-1\">\r\n {title && <p className=\"m-0 text-sm font-semibold text-sbk-fg-heading\">{title}</p>}\r\n {children && <div className=\"text-sm font-light leading-relaxed\">{children}</div>}\r\n {action && <div className=\"mt-2 flex flex-wrap gap-2\">{action}</div>}\r\n </div>\r\n {onClose && (\r\n <button\r\n aria-label=\"Fechar alerta\"\r\n className={cn(\r\n buttonReset,\r\n 'inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-sbk-xs text-sbk-fg-muted hover:bg-sbk-surface-hover hover:text-sbk-fg',\r\n focusRing,\r\n )}\r\n onClick={onClose}\r\n type=\"button\"\r\n >\r\n <X aria-hidden=\"true\" className=\"size-4\" />\r\n </button>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nAlert.displayName = 'Alert';\r\n"],"names":["TONE","Info","CheckCircle2","AlertTriangle","XCircle","Alert","title","tone","icon","action","onClose","children","className","role","props","box","iconColor","Icon","urgent","jsxs","cn","jsx","buttonReset","focusRing","X"],"mappings":";;;;AAiBA,MAAMA,IAA4E;AAAA,EAChF,MAAM,EAAE,KAAK,yCAAyC,MAAM,oBAAoB,MAAMC,EAAA;AAAA,EACtF,SAAS;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAMC;AAAA,EAAA;AAAA,EAER,SAAS;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAMC;AAAA,EAAA;AAAA,EAER,OAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAMC;AAAA,EAAA;AAEV,GAMaC,IAAQ,CAAC;AAAA,EACpB,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,MAAAC;AAAA,EACA,GAAGC;AACL,MAAkB;AAChB,QAAM,EAAE,KAAAC,GAAK,MAAMC,GAAW,MAAAC,EAAA,IAASjB,EAAKO,CAAI,GAC1CW,IAASX,MAAS,WAAWA,MAAS;AAE5C,SACE,gBAAAY;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAG,gEAAgEL,GAAKH,CAAS;AAAA,MAC5F,MAAMC,MAASK,IAAS,UAAU;AAAA,MACjC,GAAGJ;AAAA,MAEH,UAAA;AAAA,QAAAN,MAAS,MACR,gBAAAa;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAWD,EAAG,8CAA8CJ,CAAS;AAAA,YAEpE,UAAAR,KAAQ,gBAAAa,EAACJ,GAAA,EAAK,aAAa,KAAA,CAAM;AAAA,UAAA;AAAA,QAAA;AAAA,QAGtC,gBAAAE,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,UAAAb,KAAS,gBAAAe,EAAC,KAAA,EAAE,WAAU,iDAAiD,UAAAf,GAAM;AAAA,UAC7EK,KAAY,gBAAAU,EAAC,OAAA,EAAI,WAAU,sCAAsC,UAAAV,GAAS;AAAA,UAC1EF,KAAU,gBAAAY,EAAC,OAAA,EAAI,WAAU,6BAA6B,UAAAZ,EAAA,CAAO;AAAA,QAAA,GAChE;AAAA,QACCC,KACC,gBAAAW;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAW;AAAA,YACX,WAAWD;AAAA,cACTE;AAAA,cACA;AAAA,cACAC;AAAA,YAAA;AAAA,YAEF,SAASb;AAAA,YACT,MAAK;AAAA,YAEL,UAAA,gBAAAW,EAACG,GAAA,EAAE,eAAY,QAAO,WAAU,SAAA,CAAS;AAAA,UAAA;AAAA,QAAA;AAAA,MAC3C;AAAA,IAAA;AAAA,EAAA;AAIR;AAEAnB,EAAM,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar.js","sources":["../../../src/components/Avatar/Avatar.tsx"],"sourcesContent":["import type React from 'react';\nimport { useState } from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Nome da pessoa: usado como label acessível e para gerar as iniciais. */\n alt: string;\n shape?: 'circle' | 'square';\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n /** URL da imagem. Se ausente ou com erro, exibe as iniciais. */\n src?: string;\n /** Indicador de presença. */\n status?: 'online' | 'offline' | 'busy';\n}\n\nconst SIZE_CLASS: Record<NonNullable<AvatarProps['size']>, string> = {\n xs: 'size-6 text-[0.625rem]',\n sm: 'size-8 text-xs',\n md: 'size-10 text-sm',\n lg: 'size-12 text-base',\n xl: 'size-16 text-lg',\n};\n\nconst STATUS_CLASS = {\n online: 'bg-sbk-success',\n offline: 'bg-sbk-line-strong',\n busy: 'bg-sbk-error',\n} as const;\nconst STATUS_LABEL = { online: 'online', offline: 'offline', busy: 'ocupado' } as const;\n\n/** Extrai até 2 iniciais. Ex.: \"Carlos Augusto\" gera \"CA\". */\nexport const getInitials = (name: string): string =>\n name\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((word) => word[0]?.toUpperCase() ?? '')\n .join('');\n\nexport const Avatar = ({\n src,\n alt,\n size = 'md',\n shape = 'circle',\n status,\n className,\n ...props\n}: AvatarProps) => {\n const [imgError, setImgError] = useState(false);\n const showImage = src && !imgError;\n const label = status ? `${alt} (${STATUS_LABEL[status]})` : alt;\n\n return (\n <span className={cn('relative inline-flex shrink-0', className)} {...props}>\n <span\n aria-label={label}\n className={cn(\n 'inline-flex select-none items-center justify-center overflow-hidden bg-sbk-ciano font-semibold text-sbk-branco',\n shape === 'circle' ? 'rounded-full' : 'rounded-sbk-sm',\n SIZE_CLASS[size],\n )}\n role=\"img\"\n >\n {showImage ? (\n <img\n alt=\"\"\n className=\"size-full object-cover\"\n onError={() => setImgError(true)}\n src={src}\n />\n ) : (\n <span aria-hidden=\"true\">{getInitials(alt)}</span>\n )}\n </span>\n {status && (\n <span\n aria-hidden=\"true\"\n className={cn(\n 'absolute bottom-0 right-0 size-2.5 rounded-full ring-2 ring-sbk-surface',\n STATUS_CLASS[status],\n )}\n />\n )}\n </span>\n );\n};\n\nAvatar.displayName = 'Avatar';\n"],"names":["SIZE_CLASS","STATUS_CLASS","STATUS_LABEL","getInitials","name","word","_a","Avatar","src","alt","size","shape","status","className","props","imgError","setImgError","useState","showImage","label","jsxs","cn","jsx"],"mappings":";;;AAeA,MAAMA,IAA+D;AAAA,EACnE,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAAe;AAAA,EACnB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AACR,GACMC,IAAe,EAAE,QAAQ,UAAU,SAAS,WAAW,MAAM,UAAA,GAGtDC,IAAc,CAACC,MAC1BA,EACG,KAAA,EACA,MAAM,KAAK,EACX,OAAO,OAAO,EACd,MAAM,GAAG,CAAC,EACV,IAAI,CAACC;;AAAS,WAAAC,IAAAD,EAAK,CAAC,MAAN,gBAAAC,EAAS,kBAAiB;AAAA,CAAE,EAC1C,KAAK,EAAE,GAECC,IAAS,CAAC;AAAA,EACrB,KAAAC;AAAA,EACA,KAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,OAAAC,IAAQ;AAAA,EACR,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,MAAmB;AACjB,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAAS,EAAK,GACxCC,IAAYV,KAAO,CAACO,GACpBI,IAAQP,IAAS,GAAGH,CAAG,KAAKP,EAAaU,CAAM,CAAC,MAAMH;AAE5D,SACE,gBAAAW,EAAC,UAAK,WAAWC,EAAG,iCAAiCR,CAAS,GAAI,GAAGC,GACnE,UAAA;AAAA,IAAA,gBAAAQ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,cAAYH;AAAA,QACZ,WAAWE;AAAA,UACT;AAAA,UACAV,MAAU,WAAW,iBAAiB;AAAA,UACtCX,EAAWU,CAAI;AAAA,QAAA;AAAA,QAEjB,MAAK;AAAA,QAEJ,UAAAQ,IACC,gBAAAI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAI;AAAA,YACJ,WAAU;AAAA,YACV,SAAS,MAAMN,EAAY,EAAI;AAAA,YAC/B,KAAAR;AAAA,UAAA;AAAA,QAAA,IAGF,gBAAAc,EAAC,QAAA,EAAK,eAAY,QAAQ,UAAAnB,EAAYM,CAAG,EAAA,CAAE;AAAA,MAAA;AAAA,IAAA;AAAA,IAG9CG,KACC,gBAAAU;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAY;AAAA,QACZ,WAAWD;AAAA,UACT;AAAA,UACApB,EAAaW,CAAM;AAAA,QAAA;AAAA,MACrB;AAAA,IAAA;AAAA,EACF,GAEJ;AAEJ;AAEAL,EAAO,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Avatar.js","sources":["../../../src/components/Avatar/Avatar.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { useState } from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\r\n /** Nome da pessoa: usado como label acessível e para gerar as iniciais. */\r\n alt: string;\r\n shape?: 'circle' | 'square';\r\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n /** URL da imagem. Se ausente ou com erro, exibe as iniciais. */\r\n src?: string;\r\n /** Indicador de presença. */\r\n status?: 'online' | 'offline' | 'busy';\r\n}\r\n\r\nconst SIZE_CLASS: Record<NonNullable<AvatarProps['size']>, string> = {\r\n xs: 'size-6 text-[0.625rem]',\r\n sm: 'size-8 text-xs',\r\n md: 'size-10 text-sm',\r\n lg: 'size-12 text-base',\r\n xl: 'size-16 text-lg',\r\n};\r\n\r\nconst STATUS_CLASS = {\r\n online: 'bg-sbk-success',\r\n offline: 'bg-sbk-line-strong',\r\n busy: 'bg-sbk-error',\r\n} as const;\r\nconst STATUS_LABEL = { online: 'online', offline: 'offline', busy: 'ocupado' } as const;\r\n\r\n/** Extrai até 2 iniciais. Ex.: \"Carlos Augusto\" gera \"CA\". */\r\nexport const getInitials = (name: string): string =>\r\n name\r\n .trim()\r\n .split(/\\s+/)\r\n .filter(Boolean)\r\n .slice(0, 2)\r\n .map((word) => word[0]?.toUpperCase() ?? '')\r\n .join('');\r\n\r\nexport const Avatar = ({\r\n src,\r\n alt,\r\n size = 'md',\r\n shape = 'circle',\r\n status,\r\n className,\r\n ...props\r\n}: AvatarProps) => {\r\n const [imgError, setImgError] = useState(false);\r\n const showImage = src && !imgError;\r\n const label = status ? `${alt} (${STATUS_LABEL[status]})` : alt;\r\n\r\n return (\r\n <span className={cn('relative inline-flex shrink-0', className)} {...props}>\r\n <span\r\n aria-label={label}\r\n className={cn(\r\n 'inline-flex select-none items-center justify-center overflow-hidden bg-sbk-ciano font-semibold text-sbk-branco',\r\n shape === 'circle' ? 'rounded-full' : 'rounded-sbk-sm',\r\n SIZE_CLASS[size],\r\n )}\r\n role=\"img\"\r\n >\r\n {showImage ? (\r\n <img\r\n alt=\"\"\r\n className=\"size-full object-cover\"\r\n onError={() => setImgError(true)}\r\n src={src}\r\n />\r\n ) : (\r\n <span aria-hidden=\"true\">{getInitials(alt)}</span>\r\n )}\r\n </span>\r\n {status && (\r\n <span\r\n aria-hidden=\"true\"\r\n className={cn(\r\n 'absolute bottom-0 right-0 size-2.5 rounded-full ring-2 ring-sbk-surface',\r\n STATUS_CLASS[status],\r\n )}\r\n />\r\n )}\r\n </span>\r\n );\r\n};\r\n\r\nAvatar.displayName = 'Avatar';\r\n"],"names":["SIZE_CLASS","STATUS_CLASS","STATUS_LABEL","getInitials","name","word","_a","Avatar","src","alt","size","shape","status","className","props","imgError","setImgError","useState","showImage","label","jsxs","cn","jsx"],"mappings":";;;AAeA,MAAMA,IAA+D;AAAA,EACnE,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAAe;AAAA,EACnB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AACR,GACMC,IAAe,EAAE,QAAQ,UAAU,SAAS,WAAW,MAAM,UAAA,GAGtDC,IAAc,CAACC,MAC1BA,EACG,KAAA,EACA,MAAM,KAAK,EACX,OAAO,OAAO,EACd,MAAM,GAAG,CAAC,EACV,IAAI,CAACC;;AAAS,WAAAC,IAAAD,EAAK,CAAC,MAAN,gBAAAC,EAAS,kBAAiB;AAAA,CAAE,EAC1C,KAAK,EAAE,GAECC,IAAS,CAAC;AAAA,EACrB,KAAAC;AAAA,EACA,KAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,OAAAC,IAAQ;AAAA,EACR,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,MAAmB;AACjB,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAAS,EAAK,GACxCC,IAAYV,KAAO,CAACO,GACpBI,IAAQP,IAAS,GAAGH,CAAG,KAAKP,EAAaU,CAAM,CAAC,MAAMH;AAE5D,SACE,gBAAAW,EAAC,UAAK,WAAWC,EAAG,iCAAiCR,CAAS,GAAI,GAAGC,GACnE,UAAA;AAAA,IAAA,gBAAAQ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,cAAYH;AAAA,QACZ,WAAWE;AAAA,UACT;AAAA,UACAV,MAAU,WAAW,iBAAiB;AAAA,UACtCX,EAAWU,CAAI;AAAA,QAAA;AAAA,QAEjB,MAAK;AAAA,QAEJ,UAAAQ,IACC,gBAAAI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAI;AAAA,YACJ,WAAU;AAAA,YACV,SAAS,MAAMN,EAAY,EAAI;AAAA,YAC/B,KAAAR;AAAA,UAAA;AAAA,QAAA,IAGF,gBAAAc,EAAC,QAAA,EAAK,eAAY,QAAQ,UAAAnB,EAAYM,CAAG,EAAA,CAAE;AAAA,MAAA;AAAA,IAAA;AAAA,IAG9CG,KACC,gBAAAU;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAY;AAAA,QACZ,WAAWD;AAAA,UACT;AAAA,UACApB,EAAaW,CAAM;AAAA,QAAA;AAAA,MACrB;AAAA,IAAA;AAAA,EACF,GAEJ;AAEJ;AAEAL,EAAO,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.js","sources":["../../../src/components/Badge/Badge.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport type BadgeTone =\n | 'neutral'\n | 'primary'\n | 'secondary'\n | 'success'\n | 'warning'\n | 'error'\n | 'info';\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Ponto colorido antes do texto (status). */\n dot?: boolean;\n size?: 'sm' | 'md';\n tone?: BadgeTone;\n /** `solid`: fundo cheio. `subtle`: fundo suave com texto colorido. Padrão: solid. */\n variant?: 'solid' | 'subtle';\n}\n\nconst SOLID: Record<BadgeTone, string> = {\n neutral: 'bg-sbk-surface-sunken text-sbk-fg-muted border border-sbk-line',\n primary: 'bg-sbk-primary text-sbk-on-primary',\n secondary: 'bg-sbk-secondary text-sbk-on-secondary',\n success: 'bg-sbk-success text-sbk-on-state',\n warning: 'bg-sbk-warning text-sbk-on-state',\n error: 'bg-sbk-error text-sbk-on-state',\n info: 'bg-sbk-info text-sbk-on-state',\n};\n\nconst SUBTLE: Record<BadgeTone, string> = {\n neutral: 'bg-sbk-surface-sunken text-sbk-fg-muted',\n primary: 'bg-sbk-primary-subtle text-sbk-primary dark:text-sbk-fg',\n secondary: 'bg-sbk-primary-subtle text-sbk-secondary dark:text-sbk-fg',\n success: 'bg-sbk-success-subtle text-sbk-success-fg',\n warning: 'bg-sbk-warning-subtle text-sbk-warning-fg',\n error: 'bg-sbk-error-subtle text-sbk-error-fg',\n info: 'bg-sbk-info-subtle text-sbk-info-fg',\n};\n\n/** Etiqueta curta de status ou contagem (formato pill da SBK IA). */\nexport const Badge = ({\n size = 'md',\n tone = 'neutral',\n variant = 'solid',\n dot = false,\n className,\n children,\n ...props\n}: BadgeProps) => (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 whitespace-nowrap rounded-full font-semibold leading-none',\n size === 'sm' ? 'px-2 py-0.5 text-[0.6875rem]' : 'px-2.5 py-1 text-xs',\n (variant === 'solid' ? SOLID : SUBTLE)[tone],\n className,\n )}\n {...props}\n >\n {dot && <span aria-hidden=\"true\" className=\"size-1.5 rounded-full bg-current\" />}\n {children}\n </span>\n);\n\nBadge.displayName = 'Badge';\n"],"names":["SOLID","SUBTLE","Badge","size","tone","variant","dot","className","children","props","jsxs","cn","jsx"],"mappings":";;AAqBA,MAAMA,IAAmC;AAAA,EACvC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR,GAEMC,IAAoC;AAAA,EACxC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR,GAGaC,IAAQ,CAAC;AAAA,EACpB,MAAAC,IAAO;AAAA,EACP,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAU;AAAA,EACV,KAAAC,IAAM;AAAA,EACN,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,MACE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAR,MAAS,OAAO,iCAAiC;AAAA,OAChDE,MAAY,UAAUL,IAAQC,GAAQG,CAAI;AAAA,MAC3CG;AAAA,IAAA;AAAA,IAED,GAAGE;AAAA,IAEH,UAAA;AAAA,MAAAH,KAAO,gBAAAM,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,oCAAmC;AAAA,MAC7EJ;AAAA,IAAA;AAAA,EAAA;AACH;AAGFN,EAAM,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Badge.js","sources":["../../../src/components/Badge/Badge.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport type BadgeTone =\r\n | 'neutral'\r\n | 'primary'\r\n | 'secondary'\r\n | 'success'\r\n | 'warning'\r\n | 'error'\r\n | 'info';\r\n\r\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\r\n /** Ponto colorido antes do texto (status). */\r\n dot?: boolean;\r\n size?: 'sm' | 'md';\r\n tone?: BadgeTone;\r\n /** `solid`: fundo cheio. `subtle`: fundo suave com texto colorido. Padrão: solid. */\r\n variant?: 'solid' | 'subtle';\r\n}\r\n\r\nconst SOLID: Record<BadgeTone, string> = {\r\n neutral: 'bg-sbk-surface-sunken text-sbk-fg-muted border border-sbk-line',\r\n primary: 'bg-sbk-primary text-sbk-on-primary',\r\n secondary: 'bg-sbk-secondary text-sbk-on-secondary',\r\n success: 'bg-sbk-success text-sbk-on-state',\r\n warning: 'bg-sbk-warning text-sbk-on-state',\r\n error: 'bg-sbk-error text-sbk-on-state',\r\n info: 'bg-sbk-info text-sbk-on-state',\r\n};\r\n\r\nconst SUBTLE: Record<BadgeTone, string> = {\r\n neutral: 'bg-sbk-surface-sunken text-sbk-fg-muted',\r\n primary: 'bg-sbk-primary-subtle text-sbk-primary dark:text-sbk-fg',\r\n secondary: 'bg-sbk-primary-subtle text-sbk-secondary dark:text-sbk-fg',\r\n success: 'bg-sbk-success-subtle text-sbk-success-fg',\r\n warning: 'bg-sbk-warning-subtle text-sbk-warning-fg',\r\n error: 'bg-sbk-error-subtle text-sbk-error-fg',\r\n info: 'bg-sbk-info-subtle text-sbk-info-fg',\r\n};\r\n\r\n/** Etiqueta curta de status ou contagem (formato pill da SBK IA). */\r\nexport const Badge = ({\r\n size = 'md',\r\n tone = 'neutral',\r\n variant = 'solid',\r\n dot = false,\r\n className,\r\n children,\r\n ...props\r\n}: BadgeProps) => (\r\n <span\r\n className={cn(\r\n 'inline-flex items-center gap-1.5 whitespace-nowrap rounded-full font-semibold leading-none',\r\n size === 'sm' ? 'px-2 py-0.5 text-[0.6875rem]' : 'px-2.5 py-1 text-xs',\r\n (variant === 'solid' ? SOLID : SUBTLE)[tone],\r\n className,\r\n )}\r\n {...props}\r\n >\r\n {dot && <span aria-hidden=\"true\" className=\"size-1.5 rounded-full bg-current\" />}\r\n {children}\r\n </span>\r\n);\r\n\r\nBadge.displayName = 'Badge';\r\n"],"names":["SOLID","SUBTLE","Badge","size","tone","variant","dot","className","children","props","jsxs","cn","jsx"],"mappings":";;AAqBA,MAAMA,IAAmC;AAAA,EACvC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR,GAEMC,IAAoC;AAAA,EACxC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR,GAGaC,IAAQ,CAAC;AAAA,EACpB,MAAAC,IAAO;AAAA,EACP,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAU;AAAA,EACV,KAAAC,IAAM;AAAA,EACN,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,MACE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAR,MAAS,OAAO,iCAAiC;AAAA,OAChDE,MAAY,UAAUL,IAAQC,GAAQG,CAAI;AAAA,MAC3CG;AAAA,IAAA;AAAA,IAED,GAAGE;AAAA,IAEH,UAAA;AAAA,MAAAH,KAAO,gBAAAM,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,oCAAmC;AAAA,MAC7EJ;AAAA,IAAA;AAAA,EAAA;AACH;AAGFN,EAAM,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumb.js","sources":["../../../src/components/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["import type React from 'react';\nimport { ChevronRight } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { focusRing } from '../../utils/styles';\n\nexport interface BreadcrumbItem {\n href?: string;\n label: React.ReactNode;\n}\n\nexport interface BreadcrumbProps extends React.HTMLAttributes<HTMLElement> {\n items: BreadcrumbItem[];\n separator?: React.ReactNode;\n}\n\nexport const Breadcrumb = ({ items, separator, className, ...props }: BreadcrumbProps) => (\n <nav aria-label=\"Breadcrumb\" className={cn('flex items-center', className)} {...props}>\n <ol className=\"m-0 flex list-none flex-wrap items-center gap-1.5 p-0 text-sm\">\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n return (\n <li key={index} className=\"flex items-center gap-1.5\">\n {index > 0 && (\n <span\n aria-hidden=\"true\"\n className=\"inline-flex select-none text-sbk-fg-muted [&_svg]:size-3.5\"\n >\n {separator ?? <ChevronRight />}\n </span>\n )}\n {isLast ? (\n <span aria-current=\"page\" className=\"font-semibold text-sbk-fg-heading\">\n {item.label}\n </span>\n ) : item.href ? (\n <a\n className={cn(\n 'rounded-sbk-xs font-light text-sbk-fg-muted underline-offset-4 hover:text-sbk-primary hover:underline',\n focusRing,\n )}\n href={item.href}\n >\n {item.label}\n </a>\n ) : (\n <span className=\"font-light text-sbk-fg-muted\">{item.label}</span>\n )}\n </li>\n );\n })}\n </ol>\n </nav>\n);\n\nBreadcrumb.displayName = 'Breadcrumb';\n"],"names":["Breadcrumb","items","separator","className","props","jsx","cn","item","index","isLast","jsxs","ChevronRight","focusRing"],"mappings":";;;;AAeO,MAAMA,IAAa,CAAC,EAAE,OAAAC,GAAO,WAAAC,GAAW,WAAAC,GAAW,GAAGC,EAAA,MAC3D,gBAAAC,EAAC,OAAA,EAAI,cAAW,cAAa,WAAWC,EAAG,qBAAqBH,CAAS,GAAI,GAAGC,GAC9E,UAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,iEACX,UAAAJ,EAAM,IAAI,CAACM,GAAMC,MAAU;AAC1B,QAAMC,IAASD,MAAUP,EAAM,SAAS;AACxC,SACE,gBAAAS,EAAC,MAAA,EAAe,WAAU,6BACvB,UAAA;AAAA,IAAAF,IAAQ,KACP,gBAAAH;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAY;AAAA,QACZ,WAAU;AAAA,QAET,UAAAH,uBAAcS,GAAA,CAAA,CAAa;AAAA,MAAA;AAAA,IAAA;AAAA,IAG/BF,IACC,gBAAAJ,EAAC,QAAA,EAAK,gBAAa,QAAO,WAAU,qCACjC,UAAAE,EAAK,MAAA,CACR,IACEA,EAAK,OACP,gBAAAF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC;AAAA,UACT;AAAA,UACAM;AAAA,QAAA;AAAA,QAEF,MAAML,EAAK;AAAA,QAEV,UAAAA,EAAK;AAAA,MAAA;AAAA,IAAA,IAGR,gBAAAF,EAAC,QAAA,EAAK,WAAU,gCAAgC,YAAK,MAAA,CAAM;AAAA,EAAA,EAAA,GAxBtDG,CA0BT;AAEJ,CAAC,GACH,EAAA,CACF;AAGFR,EAAW,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Breadcrumb.js","sources":["../../../src/components/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { ChevronRight } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { focusRing } from '../../utils/styles';\r\n\r\nexport interface BreadcrumbItem {\r\n href?: string;\r\n label: React.ReactNode;\r\n}\r\n\r\nexport interface BreadcrumbProps extends React.HTMLAttributes<HTMLElement> {\r\n items: BreadcrumbItem[];\r\n separator?: React.ReactNode;\r\n}\r\n\r\nexport const Breadcrumb = ({ items, separator, className, ...props }: BreadcrumbProps) => (\r\n <nav aria-label=\"Breadcrumb\" className={cn('flex items-center', className)} {...props}>\r\n <ol className=\"m-0 flex list-none flex-wrap items-center gap-1.5 p-0 text-sm\">\r\n {items.map((item, index) => {\r\n const isLast = index === items.length - 1;\r\n return (\r\n <li key={index} className=\"flex items-center gap-1.5\">\r\n {index > 0 && (\r\n <span\r\n aria-hidden=\"true\"\r\n className=\"inline-flex select-none text-sbk-fg-muted [&_svg]:size-3.5\"\r\n >\r\n {separator ?? <ChevronRight />}\r\n </span>\r\n )}\r\n {isLast ? (\r\n <span aria-current=\"page\" className=\"font-semibold text-sbk-fg-heading\">\r\n {item.label}\r\n </span>\r\n ) : item.href ? (\r\n <a\r\n className={cn(\r\n 'rounded-sbk-xs font-light text-sbk-fg-muted underline-offset-4 hover:text-sbk-primary hover:underline',\r\n focusRing,\r\n )}\r\n href={item.href}\r\n >\r\n {item.label}\r\n </a>\r\n ) : (\r\n <span className=\"font-light text-sbk-fg-muted\">{item.label}</span>\r\n )}\r\n </li>\r\n );\r\n })}\r\n </ol>\r\n </nav>\r\n);\r\n\r\nBreadcrumb.displayName = 'Breadcrumb';\r\n"],"names":["Breadcrumb","items","separator","className","props","jsx","cn","item","index","isLast","jsxs","ChevronRight","focusRing"],"mappings":";;;;AAeO,MAAMA,IAAa,CAAC,EAAE,OAAAC,GAAO,WAAAC,GAAW,WAAAC,GAAW,GAAGC,EAAA,MAC3D,gBAAAC,EAAC,OAAA,EAAI,cAAW,cAAa,WAAWC,EAAG,qBAAqBH,CAAS,GAAI,GAAGC,GAC9E,UAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,iEACX,UAAAJ,EAAM,IAAI,CAACM,GAAMC,MAAU;AAC1B,QAAMC,IAASD,MAAUP,EAAM,SAAS;AACxC,SACE,gBAAAS,EAAC,MAAA,EAAe,WAAU,6BACvB,UAAA;AAAA,IAAAF,IAAQ,KACP,gBAAAH;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAY;AAAA,QACZ,WAAU;AAAA,QAET,UAAAH,uBAAcS,GAAA,CAAA,CAAa;AAAA,MAAA;AAAA,IAAA;AAAA,IAG/BF,IACC,gBAAAJ,EAAC,QAAA,EAAK,gBAAa,QAAO,WAAU,qCACjC,UAAAE,EAAK,MAAA,CACR,IACEA,EAAK,OACP,gBAAAF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC;AAAA,UACT;AAAA,UACAM;AAAA,QAAA;AAAA,QAEF,MAAML,EAAK;AAAA,QAEV,UAAAA,EAAK;AAAA,MAAA;AAAA,IAAA,IAGR,gBAAAF,EAAC,QAAA,EAAK,WAAU,gCAAgC,YAAK,MAAA,CAAM;AAAA,EAAA,EAAA,GAxBtDG,CA0BT;AAEJ,CAAC,GACH,EAAA,CACF;AAGFR,EAAW,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\nimport { Spinner } from '../Spinner/Spinner';\n\nexport type ButtonVariant =\n | 'primary'\n | 'secondary'\n | 'outline'\n | 'ghost'\n | 'link'\n | 'inverse'\n | 'glass'\n | 'success'\n | 'error'\n | 'warning'\n | 'info'\n | 'neutral';\n\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n /** Reduz o padding horizontal (útil em toolbars e tabelas). */\n compact?: boolean;\n fullWidth?: boolean;\n /** Mostra spinner, desabilita o botão e anuncia `aria-busy`. A largura é preservada. */\n isLoading?: boolean;\n /** Texto anunciado durante o carregamento. Padrão: \"Carregando\". */\n loadingLabel?: string;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n size?: ButtonSize;\n variant?: ButtonVariant;\n}\n\nconst SIZE_CLASS: Record<ButtonSize, string> = {\n xs: 'min-h-7 gap-1 px-2.5 text-xs',\n sm: 'min-h-8 gap-1.5 px-3 text-sm',\n md: 'min-h-10 gap-2 px-4 text-sm',\n lg: 'min-h-12 gap-2 px-5 text-base',\n xl: 'min-h-14 gap-2.5 px-7 text-lg',\n};\n\nconst COMPACT_CLASS: Record<ButtonSize, string> = {\n xs: 'px-1.5',\n sm: 'px-2',\n md: 'px-2.5',\n lg: 'px-3',\n xl: 'px-4',\n};\n\nconst VARIANT_CLASS: Record<ButtonVariant, string> = {\n primary: 'bg-sbk-primary text-sbk-on-primary hover:bg-sbk-primary-hover',\n secondary: 'bg-sbk-secondary text-sbk-on-secondary hover:bg-sbk-secondary-hover',\n outline:\n 'border-sbk-primary bg-transparent text-sbk-primary hover:bg-sbk-primary-subtle dark:border-sbk-fg dark:text-sbk-fg',\n ghost: 'bg-transparent text-sbk-fg hover:bg-sbk-surface-hover',\n link: 'min-h-0 bg-transparent px-0 text-sbk-primary underline-offset-4 hover:underline dark:text-sbk-fg',\n inverse: 'bg-sbk-surface-inverse text-sbk-fg-inverse hover:opacity-90',\n glass: 'sbk-glass text-sbk-fg hover:sbk-glass-strong',\n success: 'bg-sbk-success text-sbk-on-state hover:opacity-90',\n error: 'bg-sbk-error text-sbk-on-state hover:opacity-90',\n warning: 'bg-sbk-warning text-sbk-on-state hover:opacity-90',\n info: 'bg-sbk-info text-sbk-on-state hover:opacity-90',\n neutral: 'border-sbk-line-strong bg-sbk-surface text-sbk-fg hover:bg-sbk-surface-hover',\n};\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = 'primary',\n size = 'md',\n compact = false,\n fullWidth = false,\n isLoading = false,\n loadingLabel = 'Carregando',\n leftIcon,\n rightIcon,\n children,\n className,\n disabled,\n type = 'button',\n ...props\n },\n ref,\n ) => (\n <button\n ref={ref}\n aria-busy={isLoading || undefined}\n className={cn(\n buttonReset,\n 'relative inline-flex select-none items-center justify-center whitespace-nowrap rounded-sbk-sm border border-transparent font-sbk font-semibold leading-none',\n 'cursor-pointer disabled:cursor-not-allowed disabled:opacity-50',\n transitionColors,\n focusRing,\n SIZE_CLASS[size],\n compact && COMPACT_CLASS[size],\n VARIANT_CLASS[variant],\n fullWidth && 'w-full',\n className,\n )}\n disabled={disabled || isLoading}\n type={type}\n {...props}\n >\n {isLoading && (\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <Spinner label={loadingLabel} size=\"sm\" />\n </span>\n )}\n <span className={cn('inline-flex items-center gap-[inherit]', isLoading && 'invisible')}>\n {leftIcon && (\n <span aria-hidden=\"true\" className=\"inline-flex shrink-0 [&_svg]:size-[1.15em]\">\n {leftIcon}\n </span>\n )}\n {children}\n {rightIcon && (\n <span aria-hidden=\"true\" className=\"inline-flex shrink-0 [&_svg]:size-[1.15em]\">\n {rightIcon}\n </span>\n )}\n </span>\n </button>\n ),\n);\n\nButton.displayName = 'Button';\n"],"names":["SIZE_CLASS","COMPACT_CLASS","VARIANT_CLASS","Button","React","variant","size","compact","fullWidth","isLoading","loadingLabel","leftIcon","rightIcon","children","className","disabled","type","props","ref","jsxs","cn","buttonReset","transitionColors","focusRing","jsx","Spinner"],"mappings":";;;;;AAoCA,MAAMA,IAAyC;AAAA,EAC7C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAA4C;AAAA,EAChD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAA+C;AAAA,EACnD,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SACE;AAAA,EACF,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AACX,GAEaC,IAASC,EAAM;AAAA,EAC1B,CACE;AAAA,IACE,SAAAC,IAAU;AAAA,IACV,MAAAC,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,WAAAC,IAAY;AAAA,IACZ,WAAAC,IAAY;AAAA,IACZ,cAAAC,IAAe;AAAA,IACf,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,GAAGC;AAAA,EAAA,GAELC,MAEA,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,aAAWT,KAAa;AAAA,MACxB,WAAWW;AAAA,QACTC;AAAA,QACA;AAAA,QACA;AAAA,QACAC;AAAA,QACAC;AAAA,QACAvB,EAAWM,CAAI;AAAA,QACfC,KAAWN,EAAcK,CAAI;AAAA,QAC7BJ,EAAcG,CAAO;AAAA,QACrBG,KAAa;AAAA,QACbM;AAAA,MAAA;AAAA,MAEF,UAAUC,KAAYN;AAAA,MACtB,MAAAO;AAAA,MACC,GAAGC;AAAA,MAEH,UAAA;AAAA,QAAAR,KACC,gBAAAe,EAAC,QAAA,EAAK,WAAU,qDACd,UAAA,gBAAAA,EAACC,KAAQ,OAAOf,GAAc,MAAK,KAAA,CAAK,EAAA,CAC1C;AAAA,0BAED,QAAA,EAAK,WAAWU,EAAG,0CAA0CX,KAAa,WAAW,GACnF,UAAA;AAAA,UAAAE,uBACE,QAAA,EAAK,eAAY,QAAO,WAAU,8CAChC,UAAAA,GACH;AAAA,UAEDE;AAAA,UACAD,KACC,gBAAAY,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,8CAChC,UAAAZ,EAAA,CACH;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEAT,EAAO,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Button.js","sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["import React from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\r\nimport { Spinner } from '../Spinner/Spinner';\r\n\r\nexport type ButtonVariant =\r\n | 'primary'\r\n | 'secondary'\r\n | 'outline'\r\n | 'ghost'\r\n | 'link'\r\n | 'inverse'\r\n | 'glass'\r\n | 'success'\r\n | 'error'\r\n | 'warning'\r\n | 'info'\r\n | 'neutral';\r\n\r\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n\r\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n children: React.ReactNode;\r\n /** Reduz o padding horizontal (útil em toolbars e tabelas). */\r\n compact?: boolean;\r\n fullWidth?: boolean;\r\n /** Mostra spinner, desabilita o botão e anuncia `aria-busy`. A largura é preservada. */\r\n isLoading?: boolean;\r\n /** Texto anunciado durante o carregamento. Padrão: \"Carregando\". */\r\n loadingLabel?: string;\r\n leftIcon?: React.ReactNode;\r\n rightIcon?: React.ReactNode;\r\n size?: ButtonSize;\r\n variant?: ButtonVariant;\r\n}\r\n\r\nconst SIZE_CLASS: Record<ButtonSize, string> = {\r\n xs: 'min-h-7 gap-1 px-2.5 text-xs',\r\n sm: 'min-h-8 gap-1.5 px-3 text-sm',\r\n md: 'min-h-10 gap-2 px-4 text-sm',\r\n lg: 'min-h-12 gap-2 px-5 text-base',\r\n xl: 'min-h-14 gap-2.5 px-7 text-lg',\r\n};\r\n\r\nconst COMPACT_CLASS: Record<ButtonSize, string> = {\r\n xs: 'px-1.5',\r\n sm: 'px-2',\r\n md: 'px-2.5',\r\n lg: 'px-3',\r\n xl: 'px-4',\r\n};\r\n\r\nconst VARIANT_CLASS: Record<ButtonVariant, string> = {\r\n primary: 'bg-sbk-primary text-sbk-on-primary hover:bg-sbk-primary-hover',\r\n secondary: 'bg-sbk-secondary text-sbk-on-secondary hover:bg-sbk-secondary-hover',\r\n outline:\r\n 'border-sbk-primary bg-transparent text-sbk-primary hover:bg-sbk-primary-subtle dark:border-sbk-fg dark:text-sbk-fg',\r\n ghost: 'bg-transparent text-sbk-fg hover:bg-sbk-surface-hover',\r\n link: 'min-h-0 bg-transparent px-0 text-sbk-primary underline-offset-4 hover:underline dark:text-sbk-fg',\r\n inverse: 'bg-sbk-surface-inverse text-sbk-fg-inverse hover:opacity-90',\r\n glass: 'sbk-glass text-sbk-fg hover:sbk-glass-strong',\r\n success: 'bg-sbk-success text-sbk-on-state hover:opacity-90',\r\n error: 'bg-sbk-error text-sbk-on-state hover:opacity-90',\r\n warning: 'bg-sbk-warning text-sbk-on-state hover:opacity-90',\r\n info: 'bg-sbk-info text-sbk-on-state hover:opacity-90',\r\n neutral: 'border-sbk-line-strong bg-sbk-surface text-sbk-fg hover:bg-sbk-surface-hover',\r\n};\r\n\r\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\r\n (\r\n {\r\n variant = 'primary',\r\n size = 'md',\r\n compact = false,\r\n fullWidth = false,\r\n isLoading = false,\r\n loadingLabel = 'Carregando',\r\n leftIcon,\r\n rightIcon,\r\n children,\r\n className,\r\n disabled,\r\n type = 'button',\r\n ...props\r\n },\r\n ref,\r\n ) => (\r\n <button\r\n ref={ref}\r\n aria-busy={isLoading || undefined}\r\n className={cn(\r\n buttonReset,\r\n 'relative inline-flex select-none items-center justify-center whitespace-nowrap rounded-sbk-sm border border-transparent font-sbk font-semibold leading-none',\r\n 'cursor-pointer disabled:cursor-not-allowed disabled:opacity-50',\r\n transitionColors,\r\n focusRing,\r\n SIZE_CLASS[size],\r\n compact && COMPACT_CLASS[size],\r\n VARIANT_CLASS[variant],\r\n fullWidth && 'w-full',\r\n className,\r\n )}\r\n disabled={disabled || isLoading}\r\n type={type}\r\n {...props}\r\n >\r\n {isLoading && (\r\n <span className=\"absolute inset-0 flex items-center justify-center\">\r\n <Spinner label={loadingLabel} size=\"sm\" />\r\n </span>\r\n )}\r\n <span className={cn('inline-flex items-center gap-[inherit]', isLoading && 'invisible')}>\r\n {leftIcon && (\r\n <span aria-hidden=\"true\" className=\"inline-flex shrink-0 [&_svg]:size-[1.15em]\">\r\n {leftIcon}\r\n </span>\r\n )}\r\n {children}\r\n {rightIcon && (\r\n <span aria-hidden=\"true\" className=\"inline-flex shrink-0 [&_svg]:size-[1.15em]\">\r\n {rightIcon}\r\n </span>\r\n )}\r\n </span>\r\n </button>\r\n ),\r\n);\r\n\r\nButton.displayName = 'Button';\r\n"],"names":["SIZE_CLASS","COMPACT_CLASS","VARIANT_CLASS","Button","React","variant","size","compact","fullWidth","isLoading","loadingLabel","leftIcon","rightIcon","children","className","disabled","type","props","ref","jsxs","cn","buttonReset","transitionColors","focusRing","jsx","Spinner"],"mappings":";;;;;AAoCA,MAAMA,IAAyC;AAAA,EAC7C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAA4C;AAAA,EAChD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAA+C;AAAA,EACnD,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SACE;AAAA,EACF,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AACX,GAEaC,IAASC,EAAM;AAAA,EAC1B,CACE;AAAA,IACE,SAAAC,IAAU;AAAA,IACV,MAAAC,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,WAAAC,IAAY;AAAA,IACZ,WAAAC,IAAY;AAAA,IACZ,cAAAC,IAAe;AAAA,IACf,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,GAAGC;AAAA,EAAA,GAELC,MAEA,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,aAAWT,KAAa;AAAA,MACxB,WAAWW;AAAA,QACTC;AAAA,QACA;AAAA,QACA;AAAA,QACAC;AAAA,QACAC;AAAA,QACAvB,EAAWM,CAAI;AAAA,QACfC,KAAWN,EAAcK,CAAI;AAAA,QAC7BJ,EAAcG,CAAO;AAAA,QACrBG,KAAa;AAAA,QACbM;AAAA,MAAA;AAAA,MAEF,UAAUC,KAAYN;AAAA,MACtB,MAAAO;AAAA,MACC,GAAGC;AAAA,MAEH,UAAA;AAAA,QAAAR,KACC,gBAAAe,EAAC,QAAA,EAAK,WAAU,qDACd,UAAA,gBAAAA,EAACC,KAAQ,OAAOf,GAAc,MAAK,KAAA,CAAK,EAAA,CAC1C;AAAA,0BAED,QAAA,EAAK,WAAWU,EAAG,0CAA0CX,KAAa,WAAW,GACnF,UAAA;AAAA,UAAAE,uBACE,QAAA,EAAK,eAAY,QAAO,WAAU,8CAChC,UAAAA,GACH;AAAA,UAEDE;AAAA,UACAD,KACC,gBAAAY,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,8CAChC,UAAAZ,EAAA,CACH;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEAT,EAAO,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.js","sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\nimport { inverseScope, transitionColors } from '../../utils/styles';\n\nexport type CardVariant = 'default' | 'elevated' | 'outlined' | 'flat' | 'inverse' | 'glass';\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Realce de hover (borda e sombra). Para cards clicáveis, use um <a>/<button> dentro do card. */\n hoverable?: boolean;\n /**\n * Cards empilhados atrás do card principal, com opacidades de 90% a 60%\n * (sistema de cards do brand book). Use com moderação, em destaques.\n */\n layered?: boolean;\n padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';\n variant?: CardVariant;\n}\n\nconst VARIANT_CLASS: Record<CardVariant, string> = {\n default: 'border border-sbk-line bg-sbk-surface text-sbk-fg',\n elevated: 'border border-sbk-line bg-sbk-surface text-sbk-fg shadow-sbk-sm',\n outlined: 'border border-sbk-line-strong bg-transparent text-sbk-fg',\n flat: 'border border-transparent bg-sbk-surface-sunken text-sbk-fg',\n inverse: cn('border border-transparent', inverseScope),\n glass: 'sbk-glass text-sbk-fg',\n};\n\nconst PADDING_CLASS: Record<NonNullable<CardProps['padding']>, string> = {\n none: 'p-0',\n sm: 'p-3',\n md: 'p-4',\n lg: 'p-6',\n xl: 'p-8',\n};\n\nexport const Card = React.forwardRef<HTMLDivElement, CardProps>(\n (\n {\n variant = 'default',\n padding = 'md',\n hoverable = false,\n layered = false,\n children,\n className,\n ...props\n },\n ref,\n ) => {\n const card = (\n <div\n ref={ref}\n className={cn(\n 'relative overflow-hidden rounded-sbk-md',\n VARIANT_CLASS[variant],\n PADDING_CLASS[padding],\n hoverable &&\n cn(\n 'hover:border-sbk-line-strong hover:shadow-sbk-md',\n transitionColors,\n 'transition-shadow',\n ),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n if (!layered) return card;\n\n // Camadas atrás do card (sistema de cards do brand book, opacidades 75% e 60%).\n return (\n <div className=\"relative isolate pb-4\">\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-x-6 top-4 bottom-0 -z-20 rounded-sbk-md bg-sbk-verde-claro opacity-[var(--sbk-card-layer-opacity-3)]\"\n />\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-x-3 top-2 bottom-2 -z-10 rounded-sbk-md bg-sbk-ciano opacity-[var(--sbk-card-layer-opacity-2)]\"\n />\n {card}\n </div>\n );\n },\n);\nCard.displayName = 'Card';\n\nexport const CardHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n <div className={cn('mb-3 flex items-start justify-between gap-3', className)} {...props} />\n);\nCardHeader.displayName = 'CardHeader';\n\nexport interface CardTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n as?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n}\nexport const CardTitle = ({ as: Tag = 'h3', className, ...props }: CardTitleProps) => (\n <Tag\n className={cn('m-0 text-lg font-semibold leading-tight text-sbk-fg-heading', className)}\n {...props}\n />\n);\nCardTitle.displayName = 'CardTitle';\n\nexport const CardDescription = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLParagraphElement>) => (\n <p className={cn('m-0 text-sm font-light text-sbk-fg-muted', className)} {...props} />\n);\nCardDescription.displayName = 'CardDescription';\n\nexport const CardContent = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n <div className={cn('font-light', className)} {...props} />\n);\nCardContent.displayName = 'CardContent';\n\nexport const CardFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n <div className={cn('mt-4 flex items-center justify-end gap-2', className)} {...props} />\n);\nCardFooter.displayName = 'CardFooter';\n"],"names":["VARIANT_CLASS","cn","inverseScope","PADDING_CLASS","Card","React","variant","padding","hoverable","layered","children","className","props","ref","card","jsx","transitionColors","jsxs","CardHeader","CardTitle","Tag","CardDescription","CardContent","CardFooter"],"mappings":";;;;AAmBA,MAAMA,IAA6C;AAAA,EACjD,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAASC,EAAG,6BAA6BC,CAAY;AAAA,EACrD,OAAO;AACT,GAEMC,IAAmE;AAAA,EACvE,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEaC,IAAOC,EAAM;AAAA,EACxB,CACE;AAAA,IACE,SAAAC,IAAU;AAAA,IACV,SAAAC,IAAU;AAAA,IACV,WAAAC,IAAY;AAAA,IACZ,SAAAC,IAAU;AAAA,IACV,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IACJ,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAF;AAAA,QACA,WAAWZ;AAAA,UACT;AAAA,UACAD,EAAcM,CAAO;AAAA,UACrBH,EAAcI,CAAO;AAAA,UACrBC,KACEP;AAAA,YACE;AAAA,YACAe;AAAA,YACA;AAAA,UAAA;AAAA,UAEJL;AAAA,QAAA;AAAA,QAED,GAAGC;AAAA,QAEH,UAAAF;AAAA,MAAA;AAAA,IAAA;AAIL,WAAKD,IAIH,gBAAAQ,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,MAAA,gBAAAF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEXD;AAAA,IAAA,GACH,IAdmBA;AAAA,EAgBvB;AACF;AACAV,EAAK,cAAc;AAEZ,MAAMc,IAAa,CAAC,EAAE,WAAAP,GAAW,GAAGC,EAAA,MACzC,gBAAAG,EAAC,OAAA,EAAI,WAAWd,EAAG,+CAA+CU,CAAS,GAAI,GAAGC,EAAA,CAAO;AAE3FM,EAAW,cAAc;AAKlB,MAAMC,IAAY,CAAC,EAAE,IAAIC,IAAM,MAAM,WAAAT,GAAW,GAAGC,EAAA,MACxD,gBAAAG;AAAA,EAACK;AAAA,EAAA;AAAA,IACC,WAAWnB,EAAG,+DAA+DU,CAAS;AAAA,IACrF,GAAGC;AAAA,EAAA;AACN;AAEFO,EAAU,cAAc;AAEjB,MAAME,IAAkB,CAAC;AAAA,EAC9B,WAAAV;AAAA,EACA,GAAGC;AACL,MACE,gBAAAG,EAAC,OAAE,WAAWd,EAAG,4CAA4CU,CAAS,GAAI,GAAGC,EAAA,CAAO;AAEtFS,EAAgB,cAAc;AAEvB,MAAMC,IAAc,CAAC,EAAE,WAAAX,GAAW,GAAGC,EAAA,MAC1C,gBAAAG,EAAC,OAAA,EAAI,WAAWd,EAAG,cAAcU,CAAS,GAAI,GAAGC,EAAA,CAAO;AAE1DU,EAAY,cAAc;AAEnB,MAAMC,IAAa,CAAC,EAAE,WAAAZ,GAAW,GAAGC,EAAA,MACzC,gBAAAG,EAAC,OAAA,EAAI,WAAWd,EAAG,4CAA4CU,CAAS,GAAI,GAAGC,EAAA,CAAO;AAExFW,EAAW,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Card.js","sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import React from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { inverseScope, transitionColors } from '../../utils/styles';\r\n\r\nexport type CardVariant = 'default' | 'elevated' | 'outlined' | 'flat' | 'inverse' | 'glass';\r\n\r\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\r\n children: React.ReactNode;\r\n /** Realce de hover (borda e sombra). Para cards clicáveis, use um <a>/<button> dentro do card. */\r\n hoverable?: boolean;\r\n /**\r\n * Cards empilhados atrás do card principal, com opacidades de 90% a 60%\r\n * (sistema de cards do brand book). Use com moderação, em destaques.\r\n */\r\n layered?: boolean;\r\n padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';\r\n variant?: CardVariant;\r\n}\r\n\r\nconst VARIANT_CLASS: Record<CardVariant, string> = {\r\n default: 'border border-sbk-line bg-sbk-surface text-sbk-fg',\r\n elevated: 'border border-sbk-line bg-sbk-surface text-sbk-fg shadow-sbk-sm',\r\n outlined: 'border border-sbk-line-strong bg-transparent text-sbk-fg',\r\n flat: 'border border-transparent bg-sbk-surface-sunken text-sbk-fg',\r\n inverse: cn('border border-transparent', inverseScope),\r\n glass: 'sbk-glass text-sbk-fg',\r\n};\r\n\r\nconst PADDING_CLASS: Record<NonNullable<CardProps['padding']>, string> = {\r\n none: 'p-0',\r\n sm: 'p-3',\r\n md: 'p-4',\r\n lg: 'p-6',\r\n xl: 'p-8',\r\n};\r\n\r\nexport const Card = React.forwardRef<HTMLDivElement, CardProps>(\r\n (\r\n {\r\n variant = 'default',\r\n padding = 'md',\r\n hoverable = false,\r\n layered = false,\r\n children,\r\n className,\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const card = (\r\n <div\r\n ref={ref}\r\n className={cn(\r\n 'relative overflow-hidden rounded-sbk-md',\r\n VARIANT_CLASS[variant],\r\n PADDING_CLASS[padding],\r\n hoverable &&\r\n cn(\r\n 'hover:border-sbk-line-strong hover:shadow-sbk-md',\r\n transitionColors,\r\n 'transition-shadow',\r\n ),\r\n className,\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n\r\n if (!layered) return card;\r\n\r\n // Camadas atrás do card (sistema de cards do brand book, opacidades 75% e 60%).\r\n return (\r\n <div className=\"relative isolate pb-4\">\r\n <span\r\n aria-hidden=\"true\"\r\n className=\"absolute inset-x-6 top-4 bottom-0 -z-20 rounded-sbk-md bg-sbk-verde-claro opacity-[var(--sbk-card-layer-opacity-3)]\"\r\n />\r\n <span\r\n aria-hidden=\"true\"\r\n className=\"absolute inset-x-3 top-2 bottom-2 -z-10 rounded-sbk-md bg-sbk-ciano opacity-[var(--sbk-card-layer-opacity-2)]\"\r\n />\r\n {card}\r\n </div>\r\n );\r\n },\r\n);\r\nCard.displayName = 'Card';\r\n\r\nexport const CardHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\r\n <div className={cn('mb-3 flex items-start justify-between gap-3', className)} {...props} />\r\n);\r\nCardHeader.displayName = 'CardHeader';\r\n\r\nexport interface CardTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\r\n as?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\r\n}\r\nexport const CardTitle = ({ as: Tag = 'h3', className, ...props }: CardTitleProps) => (\r\n <Tag\r\n className={cn('m-0 text-lg font-semibold leading-tight text-sbk-fg-heading', className)}\r\n {...props}\r\n />\r\n);\r\nCardTitle.displayName = 'CardTitle';\r\n\r\nexport const CardDescription = ({\r\n className,\r\n ...props\r\n}: React.HTMLAttributes<HTMLParagraphElement>) => (\r\n <p className={cn('m-0 text-sm font-light text-sbk-fg-muted', className)} {...props} />\r\n);\r\nCardDescription.displayName = 'CardDescription';\r\n\r\nexport const CardContent = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\r\n <div className={cn('font-light', className)} {...props} />\r\n);\r\nCardContent.displayName = 'CardContent';\r\n\r\nexport const CardFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\r\n <div className={cn('mt-4 flex items-center justify-end gap-2', className)} {...props} />\r\n);\r\nCardFooter.displayName = 'CardFooter';\r\n"],"names":["VARIANT_CLASS","cn","inverseScope","PADDING_CLASS","Card","React","variant","padding","hoverable","layered","children","className","props","ref","card","jsx","transitionColors","jsxs","CardHeader","CardTitle","Tag","CardDescription","CardContent","CardFooter"],"mappings":";;;;AAmBA,MAAMA,IAA6C;AAAA,EACjD,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAASC,EAAG,6BAA6BC,CAAY;AAAA,EACrD,OAAO;AACT,GAEMC,IAAmE;AAAA,EACvE,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEaC,IAAOC,EAAM;AAAA,EACxB,CACE;AAAA,IACE,SAAAC,IAAU;AAAA,IACV,SAAAC,IAAU;AAAA,IACV,WAAAC,IAAY;AAAA,IACZ,SAAAC,IAAU;AAAA,IACV,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IACJ,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAF;AAAA,QACA,WAAWZ;AAAA,UACT;AAAA,UACAD,EAAcM,CAAO;AAAA,UACrBH,EAAcI,CAAO;AAAA,UACrBC,KACEP;AAAA,YACE;AAAA,YACAe;AAAA,YACA;AAAA,UAAA;AAAA,UAEJL;AAAA,QAAA;AAAA,QAED,GAAGC;AAAA,QAEH,UAAAF;AAAA,MAAA;AAAA,IAAA;AAIL,WAAKD,IAIH,gBAAAQ,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,MAAA,gBAAAF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEXD;AAAA,IAAA,GACH,IAdmBA;AAAA,EAgBvB;AACF;AACAV,EAAK,cAAc;AAEZ,MAAMc,IAAa,CAAC,EAAE,WAAAP,GAAW,GAAGC,EAAA,MACzC,gBAAAG,EAAC,OAAA,EAAI,WAAWd,EAAG,+CAA+CU,CAAS,GAAI,GAAGC,EAAA,CAAO;AAE3FM,EAAW,cAAc;AAKlB,MAAMC,IAAY,CAAC,EAAE,IAAIC,IAAM,MAAM,WAAAT,GAAW,GAAGC,EAAA,MACxD,gBAAAG;AAAA,EAACK;AAAA,EAAA;AAAA,IACC,WAAWnB,EAAG,+DAA+DU,CAAS;AAAA,IACrF,GAAGC;AAAA,EAAA;AACN;AAEFO,EAAU,cAAc;AAEjB,MAAME,IAAkB,CAAC;AAAA,EAC9B,WAAAV;AAAA,EACA,GAAGC;AACL,MACE,gBAAAG,EAAC,OAAE,WAAWd,EAAG,4CAA4CU,CAAS,GAAI,GAAGC,EAAA,CAAO;AAEtFS,EAAgB,cAAc;AAEvB,MAAMC,IAAc,CAAC,EAAE,WAAAX,GAAW,GAAGC,EAAA,MAC1C,gBAAAG,EAAC,OAAA,EAAI,WAAWd,EAAG,cAAcU,CAAS,GAAI,GAAGC,EAAA,CAAO;AAE1DU,EAAY,cAAc;AAEnB,MAAMC,IAAa,CAAC,EAAE,WAAAZ,GAAW,GAAGC,EAAA,MACzC,gBAAAG,EAAC,OAAA,EAAI,WAAWd,EAAG,4CAA4CU,CAAS,GAAI,GAAGC,EAAA,CAAO;AAExFW,EAAW,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.js","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import React, { useEffect, useId, useImperativeHandle, useRef } from 'react';\nimport { cn } from '../../utils/cn';\nimport { choiceControl } from '../../utils/styles';\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n error?: string;\n helperText?: string;\n /** Estado intermediário (ex.: \"selecionar todos\" parcial). */\n indeterminate?: boolean;\n label?: React.ReactNode;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ label, helperText, error, indeterminate = false, className, id, disabled, ...props }, ref) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n const innerRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);\n\n useEffect(() => {\n if (innerRef.current) innerRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n\n const hintId = error ? `${inputId}-error` : helperText ? `${inputId}-helper` : undefined;\n\n return (\n <div className={cn('inline-flex items-start gap-2', disabled && 'opacity-60', className)}>\n <input\n ref={innerRef}\n aria-describedby={hintId}\n aria-invalid={error ? true : undefined}\n className={choiceControl}\n disabled={disabled}\n id={inputId}\n type=\"checkbox\"\n {...props}\n />\n <span className=\"grid gap-0.5\">\n {label && (\n <label className=\"cursor-pointer text-sm font-light text-sbk-fg\" htmlFor={inputId}>\n {label}\n </label>\n )}\n {error ? (\n <span className=\"text-xs font-semibold text-sbk-error-fg\" id={hintId} role=\"alert\">\n {error}\n </span>\n ) : (\n helperText && (\n <span className=\"text-xs font-light text-sbk-fg-muted\" id={hintId}>\n {helperText}\n </span>\n )\n )}\n </span>\n </div>\n );\n },\n);\n\nCheckbox.displayName = 'Checkbox';\n"],"names":["Checkbox","React","label","helperText","error","indeterminate","className","id","disabled","props","ref","autoId","useId","inputId","innerRef","useRef","useImperativeHandle","useEffect","hintId","jsxs","cn","jsx","choiceControl"],"mappings":";;;;AAYO,MAAMA,IAAWC,EAAM;AAAA,EAC5B,CAAC,EAAE,OAAAC,GAAO,YAAAC,GAAY,OAAAC,GAAO,eAAAC,IAAgB,IAAO,WAAAC,GAAW,IAAAC,GAAI,UAAAC,GAAU,GAAGC,EAAA,GAASC,MAAQ;AAC/F,UAAMC,IAASC,EAAA,GACTC,IAAUN,KAAMI,GAChBG,IAAWC,EAAyB,IAAI;AAC9C,IAAAC,EAAoBN,GAAK,MAAMI,EAAS,OAA2B,GAEnEG,EAAU,MAAM;AACd,MAAIH,EAAS,YAASA,EAAS,QAAQ,gBAAgBT;AAAA,IACzD,GAAG,CAACA,CAAa,CAAC;AAElB,UAAMa,IAASd,IAAQ,GAAGS,CAAO,WAAWV,IAAa,GAAGU,CAAO,YAAY;AAE/E,WACE,gBAAAM,EAAC,SAAI,WAAWC,EAAG,iCAAiCZ,KAAY,cAAcF,CAAS,GACrF,UAAA;AAAA,MAAA,gBAAAe;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKP;AAAA,UACL,oBAAkBI;AAAA,UAClB,gBAAcd,IAAQ,KAAO;AAAA,UAC7B,WAAWkB;AAAA,UACX,UAAAd;AAAA,UACA,IAAIK;AAAA,UACJ,MAAK;AAAA,UACJ,GAAGJ;AAAA,QAAA;AAAA,MAAA;AAAA,MAEN,gBAAAU,EAAC,QAAA,EAAK,WAAU,gBACb,UAAA;AAAA,QAAAjB,uBACE,SAAA,EAAM,WAAU,iDAAgD,SAASW,GACvE,UAAAX,GACH;AAAA,QAEDE,IACC,gBAAAiB,EAAC,QAAA,EAAK,WAAU,2CAA0C,IAAIH,GAAQ,MAAK,SACxE,UAAAd,EAAA,CACH,IAEAD,KACE,gBAAAkB,EAAC,QAAA,EAAK,WAAU,wCAAuC,IAAIH,GACxD,UAAAf,EAAA,CACH;AAAA,MAAA,EAAA,CAGN;AAAA,IAAA,GACF;AAAA,EAEJ;AACF;AAEAH,EAAS,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Checkbox.js","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import React, { useEffect, useId, useImperativeHandle, useRef } from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { choiceControl } from '../../utils/styles';\r\n\r\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\r\n error?: string;\r\n helperText?: string;\r\n /** Estado intermediário (ex.: \"selecionar todos\" parcial). */\r\n indeterminate?: boolean;\r\n label?: React.ReactNode;\r\n}\r\n\r\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\r\n ({ label, helperText, error, indeterminate = false, className, id, disabled, ...props }, ref) => {\r\n const autoId = useId();\r\n const inputId = id ?? autoId;\r\n const innerRef = useRef<HTMLInputElement>(null);\r\n useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);\r\n\r\n useEffect(() => {\r\n if (innerRef.current) innerRef.current.indeterminate = indeterminate;\r\n }, [indeterminate]);\r\n\r\n const hintId = error ? `${inputId}-error` : helperText ? `${inputId}-helper` : undefined;\r\n\r\n return (\r\n <div className={cn('inline-flex items-start gap-2', disabled && 'opacity-60', className)}>\r\n <input\r\n ref={innerRef}\r\n aria-describedby={hintId}\r\n aria-invalid={error ? true : undefined}\r\n className={choiceControl}\r\n disabled={disabled}\r\n id={inputId}\r\n type=\"checkbox\"\r\n {...props}\r\n />\r\n <span className=\"grid gap-0.5\">\r\n {label && (\r\n <label className=\"cursor-pointer text-sm font-light text-sbk-fg\" htmlFor={inputId}>\r\n {label}\r\n </label>\r\n )}\r\n {error ? (\r\n <span className=\"text-xs font-semibold text-sbk-error-fg\" id={hintId} role=\"alert\">\r\n {error}\r\n </span>\r\n ) : (\r\n helperText && (\r\n <span className=\"text-xs font-light text-sbk-fg-muted\" id={hintId}>\r\n {helperText}\r\n </span>\r\n )\r\n )}\r\n </span>\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nCheckbox.displayName = 'Checkbox';\r\n"],"names":["Checkbox","React","label","helperText","error","indeterminate","className","id","disabled","props","ref","autoId","useId","inputId","innerRef","useRef","useImperativeHandle","useEffect","hintId","jsxs","cn","jsx","choiceControl"],"mappings":";;;;AAYO,MAAMA,IAAWC,EAAM;AAAA,EAC5B,CAAC,EAAE,OAAAC,GAAO,YAAAC,GAAY,OAAAC,GAAO,eAAAC,IAAgB,IAAO,WAAAC,GAAW,IAAAC,GAAI,UAAAC,GAAU,GAAGC,EAAA,GAASC,MAAQ;AAC/F,UAAMC,IAASC,EAAA,GACTC,IAAUN,KAAMI,GAChBG,IAAWC,EAAyB,IAAI;AAC9C,IAAAC,EAAoBN,GAAK,MAAMI,EAAS,OAA2B,GAEnEG,EAAU,MAAM;AACd,MAAIH,EAAS,YAASA,EAAS,QAAQ,gBAAgBT;AAAA,IACzD,GAAG,CAACA,CAAa,CAAC;AAElB,UAAMa,IAASd,IAAQ,GAAGS,CAAO,WAAWV,IAAa,GAAGU,CAAO,YAAY;AAE/E,WACE,gBAAAM,EAAC,SAAI,WAAWC,EAAG,iCAAiCZ,KAAY,cAAcF,CAAS,GACrF,UAAA;AAAA,MAAA,gBAAAe;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKP;AAAA,UACL,oBAAkBI;AAAA,UAClB,gBAAcd,IAAQ,KAAO;AAAA,UAC7B,WAAWkB;AAAA,UACX,UAAAd;AAAA,UACA,IAAIK;AAAA,UACJ,MAAK;AAAA,UACJ,GAAGJ;AAAA,QAAA;AAAA,MAAA;AAAA,MAEN,gBAAAU,EAAC,QAAA,EAAK,WAAU,gBACb,UAAA;AAAA,QAAAjB,uBACE,SAAA,EAAM,WAAU,iDAAgD,SAASW,GACvE,UAAAX,GACH;AAAA,QAEDE,IACC,gBAAAiB,EAAC,QAAA,EAAK,WAAU,2CAA0C,IAAIH,GAAQ,MAAK,SACxE,UAAAd,EAAA,CACH,IAEAD,KACE,gBAAAkB,EAAC,QAAA,EAAK,WAAU,wCAAuC,IAAIH,GACxD,UAAAf,EAAA,CACH;AAAA,MAAA,EAAA,CAGN;AAAA,IAAA,GACF;AAAA,EAEJ;AACF;AAEAH,EAAS,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chip.js","sources":["../../../src/components/Chip/Chip.tsx"],"sourcesContent":["import type React from 'react';\nimport { Check } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\n\nexport interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon?: React.ReactNode;\n /** Estado de seleção (filtro ativo), anunciado via aria-pressed. */\n selected?: boolean;\n}\n\n/** Filtro rápido alternável (toggle button). */\nexport const Chip = ({ selected = false, icon, className, children, ...props }: ChipProps) => (\n <button\n aria-pressed={selected}\n className={cn(\n buttonReset,\n 'inline-flex cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1.5 text-sm disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:size-4',\n transitionColors,\n focusRing,\n selected\n ? 'border-sbk-primary bg-sbk-primary-subtle font-semibold text-sbk-fg-heading'\n : 'border-sbk-line-strong bg-sbk-surface font-light text-sbk-fg hover:bg-sbk-surface-hover',\n className,\n )}\n type=\"button\"\n {...props}\n >\n {selected ? (\n <Check aria-hidden=\"true\" />\n ) : (\n icon && (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {icon}\n </span>\n )\n )}\n {children}\n </button>\n);\n\nChip.displayName = 'Chip';\n"],"names":["Chip","selected","icon","className","children","props","jsxs","cn","buttonReset","transitionColors","focusRing","jsx","Check"],"mappings":";;;;AAYO,MAAMA,IAAO,CAAC,EAAE,UAAAC,IAAW,IAAO,MAAAC,GAAM,WAAAC,GAAW,UAAAC,GAAU,GAAGC,EAAA,MACrE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,gBAAcL;AAAA,IACd,WAAWM;AAAA,MACTC;AAAA,MACA;AAAA,MACAC;AAAA,MACAC;AAAA,MACAT,IACI,+EACA;AAAA,MACJE;AAAA,IAAA;AAAA,IAEF,MAAK;AAAA,IACJ,GAAGE;AAAA,IAEH,UAAA;AAAA,MAAAJ,IACC,gBAAAU,EAACC,GAAA,EAAM,eAAY,OAAA,CAAO,IAE1BV,KACE,gBAAAS,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,eAChC,UAAAT,GACH;AAAA,MAGHE;AAAA,IAAA;AAAA,EAAA;AACH;AAGFJ,EAAK,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Chip.js","sources":["../../../src/components/Chip/Chip.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { Check } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\r\n\r\nexport interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n icon?: React.ReactNode;\r\n /** Estado de seleção (filtro ativo), anunciado via aria-pressed. */\r\n selected?: boolean;\r\n}\r\n\r\n/** Filtro rápido alternável (toggle button). */\r\nexport const Chip = ({ selected = false, icon, className, children, ...props }: ChipProps) => (\r\n <button\r\n aria-pressed={selected}\r\n className={cn(\r\n buttonReset,\r\n 'inline-flex cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1.5 text-sm disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:size-4',\r\n transitionColors,\r\n focusRing,\r\n selected\r\n ? 'border-sbk-primary bg-sbk-primary-subtle font-semibold text-sbk-fg-heading'\r\n : 'border-sbk-line-strong bg-sbk-surface font-light text-sbk-fg hover:bg-sbk-surface-hover',\r\n className,\r\n )}\r\n type=\"button\"\r\n {...props}\r\n >\r\n {selected ? (\r\n <Check aria-hidden=\"true\" />\r\n ) : (\r\n icon && (\r\n <span aria-hidden=\"true\" className=\"inline-flex\">\r\n {icon}\r\n </span>\r\n )\r\n )}\r\n {children}\r\n </button>\r\n);\r\n\r\nChip.displayName = 'Chip';\r\n"],"names":["Chip","selected","icon","className","children","props","jsxs","cn","buttonReset","transitionColors","focusRing","jsx","Check"],"mappings":";;;;AAYO,MAAMA,IAAO,CAAC,EAAE,UAAAC,IAAW,IAAO,MAAAC,GAAM,WAAAC,GAAW,UAAAC,GAAU,GAAGC,EAAA,MACrE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,gBAAcL;AAAA,IACd,WAAWM;AAAA,MACTC;AAAA,MACA;AAAA,MACAC;AAAA,MACAC;AAAA,MACAT,IACI,+EACA;AAAA,MACJE;AAAA,IAAA;AAAA,IAEF,MAAK;AAAA,IACJ,GAAGE;AAAA,IAEH,UAAA;AAAA,MAAAJ,IACC,gBAAAU,EAACC,GAAA,EAAM,eAAY,OAAA,CAAO,IAE1BV,KACE,gBAAAS,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,eAChC,UAAAT,GACH;AAAA,MAGHE;AAAA,IAAA;AAAA,EAAA;AACH;AAGFJ,EAAK,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.js","sources":["../../../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import React, { useEffect, useId, useRef, useState } from 'react';\nimport { Check, ChevronDown } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { describedBy, fieldControl, fieldSize } from '../../utils/styles';\nimport { Field } from '../Field/Field';\n\nexport interface ComboboxOption {\n label: string;\n value: string;\n}\n\nexport interface ComboboxProps {\n className?: string;\n disabled?: boolean;\n /** Texto exibido quando o filtro não encontra opções. */\n emptyText?: string;\n error?: string;\n helperText?: string;\n id?: string;\n label?: React.ReactNode;\n onChange?: (value: string) => void;\n options: ComboboxOption[];\n placeholder?: string;\n required?: boolean;\n value?: string;\n}\n\n/** Campo com busca e lista de opções (padrão ARIA combobox + listbox). */\nexport const Combobox = ({\n label,\n helperText,\n error,\n options,\n value,\n onChange,\n placeholder = 'Selecione ou pesquise...',\n emptyText = 'Nenhum resultado encontrado.',\n disabled = false,\n required,\n id,\n className,\n}: ComboboxProps) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n const listId = `${inputId}-list`;\n const [query, setQuery] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const containerRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n const selectedOption = options.find((o) => o.value === value);\n const normalizedQuery = query.trim().toLocaleLowerCase('pt-BR');\n const filtered = normalizedQuery\n ? options.filter((o) => o.label.toLocaleLowerCase('pt-BR').includes(normalizedQuery))\n : options;\n\n const close = () => {\n setIsOpen(false);\n setQuery('');\n setActiveIndex(-1);\n };\n\n useEffect(() => {\n if (!isOpen) return;\n const handleClickOutside = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) close();\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [isOpen]);\n\n useEffect(() => {\n if (activeIndex < 0) return;\n listRef.current\n ?.querySelector(`[data-index=\"${activeIndex}\"]`)\n ?.scrollIntoView?.({ block: 'nearest' });\n }, [activeIndex]);\n\n const handleSelect = (option: ComboboxOption) => {\n onChange?.(option.value);\n close();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (!isOpen) {\n if (e.key === 'ArrowDown' || e.key === 'Enter') {\n e.preventDefault();\n setIsOpen(true);\n setActiveIndex(0);\n }\n return;\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setActiveIndex((i) => Math.max(i - 1, 0));\n } else if (e.key === 'Home') {\n e.preventDefault();\n setActiveIndex(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n setActiveIndex(filtered.length - 1);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n const option = filtered[activeIndex];\n if (option) handleSelect(option);\n } else if (e.key === 'Escape' || e.key === 'Tab') {\n close();\n }\n };\n\n return (\n <Field\n className={className}\n error={error}\n helperText={helperText}\n id={inputId}\n label={label}\n required={required}\n >\n <div ref={containerRef} className=\"relative\">\n <input\n aria-activedescendant={\n isOpen && activeIndex >= 0 ? `${inputId}-option-${activeIndex}` : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listId}\n aria-describedby={describedBy(inputId, error, helperText)}\n aria-expanded={isOpen}\n aria-invalid={error ? true : undefined}\n autoComplete=\"off\"\n className={cn(fieldControl, fieldSize.md, 'pr-10')}\n disabled={disabled}\n id={inputId}\n onChange={(e) => {\n setQuery(e.target.value);\n setIsOpen(true);\n setActiveIndex(0);\n }}\n onClick={() => setIsOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n required={required}\n role=\"combobox\"\n type=\"text\"\n value={isOpen ? query : (selectedOption?.label ?? '')}\n />\n <ChevronDown\n aria-hidden=\"true\"\n className={cn(\n 'pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-sbk-fg-muted transition-transform motion-reduce:transition-none',\n isOpen && 'rotate-180',\n )}\n />\n\n {isOpen && (\n <ul\n ref={listRef}\n className=\"absolute z-[var(--sbk-z-dropdown)] mt-1 max-h-60 w-full overflow-auto rounded-sbk-sm border border-sbk-line bg-sbk-surface py-1 shadow-sbk-md animate-sbk-fade-in\"\n id={listId}\n role=\"listbox\"\n >\n {filtered.length === 0 && (\n <li\n aria-disabled=\"true\"\n className=\"px-3.5 py-2.5 text-sm font-light text-sbk-fg-muted\"\n role=\"option\"\n aria-selected={false}\n >\n {emptyText}\n </li>\n )}\n {filtered.map((option, index) => {\n const selected = option.value === value;\n return (\n <li\n key={option.value}\n aria-selected={selected}\n className={cn(\n 'flex cursor-pointer items-center justify-between gap-2 px-3.5 py-2 text-sm font-light text-sbk-fg',\n index === activeIndex && 'bg-sbk-surface-hover',\n selected && 'font-semibold text-sbk-primary',\n )}\n data-index={index}\n id={`${inputId}-option-${index}`}\n onMouseDown={(e) => {\n e.preventDefault();\n handleSelect(option);\n }}\n onMouseEnter={() => setActiveIndex(index)}\n role=\"option\"\n >\n {option.label}\n {selected && <Check aria-hidden=\"true\" className=\"size-4\" />}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n </Field>\n );\n};\n\nCombobox.displayName = 'Combobox';\n"],"names":["Combobox","label","helperText","error","options","value","onChange","placeholder","emptyText","disabled","required","id","className","autoId","useId","inputId","listId","query","setQuery","useState","isOpen","setIsOpen","activeIndex","setActiveIndex","containerRef","useRef","listRef","selectedOption","o","normalizedQuery","filtered","close","useEffect","handleClickOutside","e","_a","_c","_b","handleSelect","option","handleKeyDown","i","jsx","Field","jsxs","describedBy","cn","fieldControl","fieldSize","ChevronDown","index","selected","Check"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Combobox.js","sources":["../../../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import React, { useEffect, useId, useRef, useState } from 'react';\r\nimport { Check, ChevronDown } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { describedBy, fieldControl, fieldSize } from '../../utils/styles';\r\nimport { Field } from '../Field/Field';\r\n\r\nexport interface ComboboxOption {\r\n label: string;\r\n value: string;\r\n}\r\n\r\nexport interface ComboboxProps {\r\n className?: string;\r\n disabled?: boolean;\r\n /** Texto exibido quando o filtro não encontra opções. */\r\n emptyText?: string;\r\n error?: string;\r\n helperText?: string;\r\n id?: string;\r\n label?: React.ReactNode;\r\n onChange?: (value: string) => void;\r\n options: ComboboxOption[];\r\n placeholder?: string;\r\n required?: boolean;\r\n value?: string;\r\n}\r\n\r\n/** Campo com busca e lista de opções (padrão ARIA combobox + listbox). */\r\nexport const Combobox = ({\r\n label,\r\n helperText,\r\n error,\r\n options,\r\n value,\r\n onChange,\r\n placeholder = 'Selecione ou pesquise...',\r\n emptyText = 'Nenhum resultado encontrado.',\r\n disabled = false,\r\n required,\r\n id,\r\n className,\r\n}: ComboboxProps) => {\r\n const autoId = useId();\r\n const inputId = id ?? autoId;\r\n const listId = `${inputId}-list`;\r\n const [query, setQuery] = useState('');\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [activeIndex, setActiveIndex] = useState(-1);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const listRef = useRef<HTMLUListElement>(null);\r\n\r\n const selectedOption = options.find((o) => o.value === value);\r\n const normalizedQuery = query.trim().toLocaleLowerCase('pt-BR');\r\n const filtered = normalizedQuery\r\n ? options.filter((o) => o.label.toLocaleLowerCase('pt-BR').includes(normalizedQuery))\r\n : options;\r\n\r\n const close = () => {\r\n setIsOpen(false);\r\n setQuery('');\r\n setActiveIndex(-1);\r\n };\r\n\r\n useEffect(() => {\r\n if (!isOpen) return;\r\n const handleClickOutside = (e: MouseEvent) => {\r\n if (!containerRef.current?.contains(e.target as Node)) close();\r\n };\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => document.removeEventListener('mousedown', handleClickOutside);\r\n }, [isOpen]);\r\n\r\n useEffect(() => {\r\n if (activeIndex < 0) return;\r\n listRef.current\r\n ?.querySelector(`[data-index=\"${activeIndex}\"]`)\r\n ?.scrollIntoView?.({ block: 'nearest' });\r\n }, [activeIndex]);\r\n\r\n const handleSelect = (option: ComboboxOption) => {\r\n onChange?.(option.value);\r\n close();\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (!isOpen) {\r\n if (e.key === 'ArrowDown' || e.key === 'Enter') {\r\n e.preventDefault();\r\n setIsOpen(true);\r\n setActiveIndex(0);\r\n }\r\n return;\r\n }\r\n if (e.key === 'ArrowDown') {\r\n e.preventDefault();\r\n setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));\r\n } else if (e.key === 'ArrowUp') {\r\n e.preventDefault();\r\n setActiveIndex((i) => Math.max(i - 1, 0));\r\n } else if (e.key === 'Home') {\r\n e.preventDefault();\r\n setActiveIndex(0);\r\n } else if (e.key === 'End') {\r\n e.preventDefault();\r\n setActiveIndex(filtered.length - 1);\r\n } else if (e.key === 'Enter') {\r\n e.preventDefault();\r\n const option = filtered[activeIndex];\r\n if (option) handleSelect(option);\r\n } else if (e.key === 'Escape' || e.key === 'Tab') {\r\n close();\r\n }\r\n };\r\n\r\n return (\r\n <Field\r\n className={className}\r\n error={error}\r\n helperText={helperText}\r\n id={inputId}\r\n label={label}\r\n required={required}\r\n >\r\n <div ref={containerRef} className=\"relative\">\r\n <input\r\n aria-activedescendant={\r\n isOpen && activeIndex >= 0 ? `${inputId}-option-${activeIndex}` : undefined\r\n }\r\n aria-autocomplete=\"list\"\r\n aria-controls={listId}\r\n aria-describedby={describedBy(inputId, error, helperText)}\r\n aria-expanded={isOpen}\r\n aria-invalid={error ? true : undefined}\r\n autoComplete=\"off\"\r\n className={cn(fieldControl, fieldSize.md, 'pr-10')}\r\n disabled={disabled}\r\n id={inputId}\r\n onChange={(e) => {\r\n setQuery(e.target.value);\r\n setIsOpen(true);\r\n setActiveIndex(0);\r\n }}\r\n onClick={() => setIsOpen(true)}\r\n onKeyDown={handleKeyDown}\r\n placeholder={placeholder}\r\n required={required}\r\n role=\"combobox\"\r\n type=\"text\"\r\n value={isOpen ? query : (selectedOption?.label ?? '')}\r\n />\r\n <ChevronDown\r\n aria-hidden=\"true\"\r\n className={cn(\r\n 'pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-sbk-fg-muted transition-transform motion-reduce:transition-none',\r\n isOpen && 'rotate-180',\r\n )}\r\n />\r\n\r\n {isOpen && (\r\n <ul\r\n ref={listRef}\r\n className=\"absolute z-[var(--sbk-z-dropdown)] mt-1 max-h-60 w-full overflow-auto rounded-sbk-sm border border-sbk-line bg-sbk-surface py-1 shadow-sbk-md animate-sbk-fade-in\"\r\n id={listId}\r\n role=\"listbox\"\r\n >\r\n {filtered.length === 0 && (\r\n <li\r\n aria-disabled=\"true\"\r\n className=\"px-3.5 py-2.5 text-sm font-light text-sbk-fg-muted\"\r\n role=\"option\"\r\n aria-selected={false}\r\n >\r\n {emptyText}\r\n </li>\r\n )}\r\n {filtered.map((option, index) => {\r\n const selected = option.value === value;\r\n return (\r\n <li\r\n key={option.value}\r\n aria-selected={selected}\r\n className={cn(\r\n 'flex cursor-pointer items-center justify-between gap-2 px-3.5 py-2 text-sm font-light text-sbk-fg',\r\n index === activeIndex && 'bg-sbk-surface-hover',\r\n selected && 'font-semibold text-sbk-primary',\r\n )}\r\n data-index={index}\r\n id={`${inputId}-option-${index}`}\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n handleSelect(option);\r\n }}\r\n onMouseEnter={() => setActiveIndex(index)}\r\n role=\"option\"\r\n >\r\n {option.label}\r\n {selected && <Check aria-hidden=\"true\" className=\"size-4\" />}\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n )}\r\n </div>\r\n </Field>\r\n );\r\n};\r\n\r\nCombobox.displayName = 'Combobox';\r\n"],"names":["Combobox","label","helperText","error","options","value","onChange","placeholder","emptyText","disabled","required","id","className","autoId","useId","inputId","listId","query","setQuery","useState","isOpen","setIsOpen","activeIndex","setActiveIndex","containerRef","useRef","listRef","selectedOption","o","normalizedQuery","filtered","close","useEffect","handleClickOutside","e","_a","_c","_b","handleSelect","option","handleKeyDown","i","jsx","Field","jsxs","describedBy","cn","fieldControl","fieldSize","ChevronDown","index","selected","Check"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Divider.js","sources":["../../../src/components/Divider/Divider.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface DividerProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Texto central (ex.: \"ou\"). Apenas na orientação horizontal. */\n label?: React.ReactNode;\n orientation?: 'horizontal' | 'vertical';\n}\n\n/** Linha divisória funcional (brand book: linhas conduzem o olhar, não decoram). */\nexport const Divider = ({\n orientation = 'horizontal',\n label,\n className,\n ...props\n}: DividerProps) => {\n if (label && orientation === 'horizontal') {\n return (\n <div\n aria-orientation=\"horizontal\"\n className={cn('flex items-center gap-3', className)}\n role=\"separator\"\n {...props}\n >\n <span className=\"h-px flex-1 bg-sbk-line\" />\n <span className=\"text-xs font-light text-sbk-fg-muted\">{label}</span>\n <span className=\"h-px flex-1 bg-sbk-line\" />\n </div>\n );\n }\n return (\n <div\n aria-orientation={orientation}\n className={cn(\n 'shrink-0 bg-sbk-line',\n orientation === 'horizontal' ? 'h-px w-full' : 'h-full w-px self-stretch',\n className,\n )}\n role=\"separator\"\n {...props}\n />\n );\n};\n\nDivider.displayName = 'Divider';\n"],"names":["Divider","orientation","label","className","props","jsxs","cn","jsx"],"mappings":";;AAUO,MAAMA,IAAU,CAAC;AAAA,EACtB,aAAAC,IAAc;AAAA,EACd,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,MACMF,KAASD,MAAgB,eAEzB,gBAAAI;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,oBAAiB;AAAA,IACjB,WAAWC,EAAG,2BAA2BH,CAAS;AAAA,IAClD,MAAK;AAAA,IACJ,GAAGC;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAG,EAAC,QAAA,EAAK,WAAU,0BAAA,CAA0B;AAAA,MAC1C,gBAAAA,EAAC,QAAA,EAAK,WAAU,wCAAwC,UAAAL,GAAM;AAAA,MAC9D,gBAAAK,EAAC,QAAA,EAAK,WAAU,0BAAA,CAA0B;AAAA,IAAA;AAAA,EAAA;AAAA,IAK9C,gBAAAA;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,oBAAkBN;AAAA,IAClB,WAAWK;AAAA,MACT;AAAA,MACAL,MAAgB,eAAe,gBAAgB;AAAA,MAC/CE;AAAA,IAAA;AAAA,IAEF,MAAK;AAAA,IACJ,GAAGC;AAAA,EAAA;AAAA;AAKVJ,EAAQ,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Divider.js","sources":["../../../src/components/Divider/Divider.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport interface DividerProps extends React.HTMLAttributes<HTMLDivElement> {\r\n /** Texto central (ex.: \"ou\"). Apenas na orientação horizontal. */\r\n label?: React.ReactNode;\r\n orientation?: 'horizontal' | 'vertical';\r\n}\r\n\r\n/** Linha divisória funcional (brand book: linhas conduzem o olhar, não decoram). */\r\nexport const Divider = ({\r\n orientation = 'horizontal',\r\n label,\r\n className,\r\n ...props\r\n}: DividerProps) => {\r\n if (label && orientation === 'horizontal') {\r\n return (\r\n <div\r\n aria-orientation=\"horizontal\"\r\n className={cn('flex items-center gap-3', className)}\r\n role=\"separator\"\r\n {...props}\r\n >\r\n <span className=\"h-px flex-1 bg-sbk-line\" />\r\n <span className=\"text-xs font-light text-sbk-fg-muted\">{label}</span>\r\n <span className=\"h-px flex-1 bg-sbk-line\" />\r\n </div>\r\n );\r\n }\r\n return (\r\n <div\r\n aria-orientation={orientation}\r\n className={cn(\r\n 'shrink-0 bg-sbk-line',\r\n orientation === 'horizontal' ? 'h-px w-full' : 'h-full w-px self-stretch',\r\n className,\r\n )}\r\n role=\"separator\"\r\n {...props}\r\n />\r\n );\r\n};\r\n\r\nDivider.displayName = 'Divider';\r\n"],"names":["Divider","orientation","label","className","props","jsxs","cn","jsx"],"mappings":";;AAUO,MAAMA,IAAU,CAAC;AAAA,EACtB,aAAAC,IAAc;AAAA,EACd,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,MACMF,KAASD,MAAgB,eAEzB,gBAAAI;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,oBAAiB;AAAA,IACjB,WAAWC,EAAG,2BAA2BH,CAAS;AAAA,IAClD,MAAK;AAAA,IACJ,GAAGC;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAG,EAAC,QAAA,EAAK,WAAU,0BAAA,CAA0B;AAAA,MAC1C,gBAAAA,EAAC,QAAA,EAAK,WAAU,wCAAwC,UAAAL,GAAM;AAAA,MAC9D,gBAAAK,EAAC,QAAA,EAAK,WAAU,0BAAA,CAA0B;AAAA,IAAA;AAAA,EAAA;AAAA,IAK9C,gBAAAA;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,oBAAkBN;AAAA,IAClB,WAAWK;AAAA,MACT;AAAA,MACAL,MAAgB,eAAe,gBAAgB;AAAA,MAC/CE;AAAA,IAAA;AAAA,IAEF,MAAK;AAAA,IACJ,GAAGC;AAAA,EAAA;AAAA;AAKVJ,EAAQ,cAAc;"}
|