@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.
Files changed (64) hide show
  1. package/CHANGELOG.md +57 -57
  2. package/dist/assets/favicon/site.webmanifest +21 -21
  3. package/dist/base.css +38 -38
  4. package/dist/components/Accordion/Accordion.js.map +1 -1
  5. package/dist/components/Alert/Alert.js.map +1 -1
  6. package/dist/components/Avatar/Avatar.js.map +1 -1
  7. package/dist/components/Badge/Badge.js.map +1 -1
  8. package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -1
  9. package/dist/components/Button/Button.js.map +1 -1
  10. package/dist/components/Card/Card.js.map +1 -1
  11. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  12. package/dist/components/Chip/Chip.js.map +1 -1
  13. package/dist/components/Combobox/Combobox.js.map +1 -1
  14. package/dist/components/Divider/Divider.js.map +1 -1
  15. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  16. package/dist/components/EmptyState/EmptyState.js.map +1 -1
  17. package/dist/components/Field/Field.js.map +1 -1
  18. package/dist/components/FileUpload/FileUpload.js.map +1 -1
  19. package/dist/components/Footer/Footer.js.map +1 -1
  20. package/dist/components/GlassPanel/GlassPanel.js.map +1 -1
  21. package/dist/components/Header/Header.js.map +1 -1
  22. package/dist/components/Highlight/Highlight.js.map +1 -1
  23. package/dist/components/Icon/Icon.js.map +1 -1
  24. package/dist/components/IconButton/IconButton.js.map +1 -1
  25. package/dist/components/Input/Input.js.map +1 -1
  26. package/dist/components/Layout/Layout.js.map +1 -1
  27. package/dist/components/Logo/Logo.js.map +1 -1
  28. package/dist/components/MiniCard/MiniCard.js.map +1 -1
  29. package/dist/components/Modal/Modal.js.map +1 -1
  30. package/dist/components/Navigation/Navigation.js.map +1 -1
  31. package/dist/components/NumberInput/NumberInput.js.map +1 -1
  32. package/dist/components/PageHeader/PageHeader.js.map +1 -1
  33. package/dist/components/Pagination/Pagination.js.map +1 -1
  34. package/dist/components/Paragraph/Paragraph.js.map +1 -1
  35. package/dist/components/Popover/Popover.js.map +1 -1
  36. package/dist/components/ProgressBar/ProgressBar.js.map +1 -1
  37. package/dist/components/Radio/Radio.js.map +1 -1
  38. package/dist/components/SectionHeader/SectionHeader.js.map +1 -1
  39. package/dist/components/Select/Select.js.map +1 -1
  40. package/dist/components/SideNav/SideNav.js.map +1 -1
  41. package/dist/components/Skeleton/Skeleton.js.map +1 -1
  42. package/dist/components/Spinner/Spinner.js.map +1 -1
  43. package/dist/components/Stepper/Stepper.js.map +1 -1
  44. package/dist/components/Subtitle/Subtitle.js.map +1 -1
  45. package/dist/components/Switch/Switch.js.map +1 -1
  46. package/dist/components/Table/Table.js.map +1 -1
  47. package/dist/components/Tabs/Tabs.js.map +1 -1
  48. package/dist/components/Tag/Tag.js.map +1 -1
  49. package/dist/components/Textarea/Textarea.js.map +1 -1
  50. package/dist/components/Title/Title.js.map +1 -1
  51. package/dist/components/Toast/Toast.js.map +1 -1
  52. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  53. package/dist/components/Typography/weight.js.map +1 -1
  54. package/dist/fonts.css +8 -8
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/reset.css +9 -9
  57. package/dist/tailwind.css +153 -153
  58. package/dist/theme/ThemeProvider.js.map +1 -1
  59. package/dist/theme/tokens.js.map +1 -1
  60. package/dist/theme.css +327 -327
  61. package/dist/tokens.css +327 -327
  62. package/dist/utils/cn.js.map +1 -1
  63. package/dist/utils/styles.js.map +1 -1
  64. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.js","sources":["../../../src/components/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, focusRing } from '../../utils/styles';\n\nexport interface DropdownMenuItem {\n /** Ação destrutiva (ex.: excluir), exibida em cor de erro. */\n danger?: boolean;\n disabled?: boolean;\n icon?: React.ReactNode;\n id: string;\n label: React.ReactNode;\n onSelect?: () => void;\n /** Atalho exibido à direita (ex.: \"Ctrl+S\"). */\n shortcut?: string;\n type?: 'item';\n}\n\nexport interface DropdownMenuSeparator {\n id: string;\n type: 'separator';\n}\n\nexport type DropdownMenuEntry = DropdownMenuItem | DropdownMenuSeparator;\n\nexport interface DropdownMenuProps {\n align?: 'start' | 'end';\n /** Rótulo acessível do menu quando o gatilho não tem texto. */\n 'aria-label'?: string;\n items: DropdownMenuEntry[];\n /** Conteúdo do botão gatilho. */\n trigger: React.ReactNode;\n triggerClassName?: string;\n variant?: 'default' | 'glass';\n}\n\nconst isItem = (entry: DropdownMenuEntry): entry is DropdownMenuItem => entry.type !== 'separator';\n\n/** Menu de ações (padrão ARIA menu button): setas, Home/End, Enter, Esc e digitação por letra. */\nexport const DropdownMenu = ({\n trigger,\n items,\n align = 'start',\n variant = 'default',\n triggerClassName,\n 'aria-label': ariaLabel,\n}: DropdownMenuProps) => {\n const [open, setOpen] = useState(false);\n const menuId = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const enabledItems = () =>\n Array.from(\n menuRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])',\n ) ?? [],\n );\n\n const focusAt = (index: number) => {\n const list = enabledItems();\n if (list.length === 0) return;\n list[(index + list.length) % list.length]?.focus();\n };\n\n const close = (restoreFocus = true) => {\n setOpen(false);\n if (restoreFocus) triggerRef.current?.focus();\n };\n\n useEffect(() => {\n if (!open) return;\n requestAnimationFrame(() =>\n menuRef.current\n ?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])')\n ?.focus(),\n );\n const onClickOutside = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', onClickOutside);\n return () => document.removeEventListener('mousedown', onClickOutside);\n }, [open]);\n\n const onMenuKeyDown = (e: React.KeyboardEvent) => {\n const list = enabledItems();\n const index = list.indexOf(document.activeElement as HTMLElement);\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n focusAt(index + 1);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n focusAt(index - 1);\n } else if (e.key === 'Home') {\n e.preventDefault();\n focusAt(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n focusAt(list.length - 1);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n close();\n } else if (e.key === 'Tab') {\n close(false);\n } else if (e.key.length === 1 && /\\S/.test(e.key)) {\n const char = e.key.toLocaleLowerCase('pt-BR');\n const match = list.findIndex(\n (el, i) => i > index && el.textContent?.trim().toLocaleLowerCase('pt-BR').startsWith(char),\n );\n const fallback = list.findIndex((el) =>\n el.textContent?.trim().toLocaleLowerCase('pt-BR').startsWith(char),\n );\n const target = match >= 0 ? match : fallback;\n if (target >= 0) focusAt(target);\n }\n };\n\n return (\n <div ref={containerRef} className=\"relative inline-flex\">\n <button\n ref={triggerRef}\n aria-controls={open ? menuId : undefined}\n aria-expanded={open}\n aria-haspopup=\"menu\"\n aria-label={ariaLabel}\n className={cn(\n buttonReset,\n 'inline-flex cursor-pointer items-center',\n focusRing,\n triggerClassName,\n )}\n onClick={() => setOpen((v) => !v)}\n onKeyDown={(e) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n setOpen(true);\n }\n }}\n type=\"button\"\n >\n {trigger}\n </button>\n {open && (\n <div\n ref={menuRef}\n aria-label={ariaLabel}\n className={cn(\n 'absolute top-full z-[var(--sbk-z-dropdown)] mt-1 min-w-48 rounded-sbk-sm p-1 animate-sbk-fade-in',\n variant === 'glass'\n ? 'sbk-glass sbk-glass-strong'\n : 'border border-sbk-line bg-sbk-surface shadow-sbk-md',\n align === 'end' ? 'right-0' : 'left-0',\n )}\n id={menuId}\n onKeyDown={onMenuKeyDown}\n role=\"menu\"\n tabIndex={-1}\n >\n {items.map((entry) =>\n isItem(entry) ? (\n <div\n key={entry.id}\n aria-disabled={entry.disabled || undefined}\n className={cn(\n 'flex cursor-pointer select-none items-center gap-2 rounded-sbk-xs px-2.5 py-2 text-sm font-light outline-none',\n 'hover:bg-sbk-surface-hover focus:bg-sbk-surface-hover',\n entry.danger ? 'text-sbk-error-fg' : 'text-sbk-fg',\n entry.disabled && 'pointer-events-none opacity-50',\n '[&_svg]:size-4 [&_svg]:shrink-0',\n )}\n onClick={() => {\n if (entry.disabled) return;\n entry.onSelect?.();\n close();\n }}\n onKeyDown={(e) => {\n if ((e.key === 'Enter' || e.key === ' ') && !entry.disabled) {\n e.preventDefault();\n entry.onSelect?.();\n close();\n }\n }}\n role=\"menuitem\"\n tabIndex={-1}\n >\n {entry.icon && (\n <span aria-hidden=\"true\" className=\"inline-flex text-sbk-fg-muted\">\n {entry.icon}\n </span>\n )}\n <span className=\"flex-1\">{entry.label}</span>\n {entry.shortcut && (\n <kbd className=\"font-sbk text-xs font-light text-sbk-fg-muted\">\n {entry.shortcut}\n </kbd>\n )}\n </div>\n ) : (\n <div key={entry.id} className=\"my-1 h-px bg-sbk-line\" role=\"separator\" />\n ),\n )}\n </div>\n )}\n </div>\n );\n};\n\nDropdownMenu.displayName = 'DropdownMenu';\n"],"names":["isItem","entry","DropdownMenu","trigger","items","align","variant","triggerClassName","ariaLabel","open","setOpen","useState","menuId","useId","triggerRef","useRef","menuRef","containerRef","enabledItems","_a","focusAt","index","list","close","restoreFocus","useEffect","_b","onClickOutside","e","onMenuKeyDown","char","match","el","i","fallback","target","jsxs","jsx","cn","buttonReset","focusRing","v"],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.js","sources":["../../../src/components/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { useEffect, useId, useRef, useState } from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, focusRing } from '../../utils/styles';\r\n\r\nexport interface DropdownMenuItem {\r\n /** Ação destrutiva (ex.: excluir), exibida em cor de erro. */\r\n danger?: boolean;\r\n disabled?: boolean;\r\n icon?: React.ReactNode;\r\n id: string;\r\n label: React.ReactNode;\r\n onSelect?: () => void;\r\n /** Atalho exibido à direita (ex.: \"Ctrl+S\"). */\r\n shortcut?: string;\r\n type?: 'item';\r\n}\r\n\r\nexport interface DropdownMenuSeparator {\r\n id: string;\r\n type: 'separator';\r\n}\r\n\r\nexport type DropdownMenuEntry = DropdownMenuItem | DropdownMenuSeparator;\r\n\r\nexport interface DropdownMenuProps {\r\n align?: 'start' | 'end';\r\n /** Rótulo acessível do menu quando o gatilho não tem texto. */\r\n 'aria-label'?: string;\r\n items: DropdownMenuEntry[];\r\n /** Conteúdo do botão gatilho. */\r\n trigger: React.ReactNode;\r\n triggerClassName?: string;\r\n variant?: 'default' | 'glass';\r\n}\r\n\r\nconst isItem = (entry: DropdownMenuEntry): entry is DropdownMenuItem => entry.type !== 'separator';\r\n\r\n/** Menu de ações (padrão ARIA menu button): setas, Home/End, Enter, Esc e digitação por letra. */\r\nexport const DropdownMenu = ({\r\n trigger,\r\n items,\r\n align = 'start',\r\n variant = 'default',\r\n triggerClassName,\r\n 'aria-label': ariaLabel,\r\n}: DropdownMenuProps) => {\r\n const [open, setOpen] = useState(false);\r\n const menuId = useId();\r\n const triggerRef = useRef<HTMLButtonElement>(null);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n const enabledItems = () =>\r\n Array.from(\r\n menuRef.current?.querySelectorAll<HTMLElement>(\r\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])',\r\n ) ?? [],\r\n );\r\n\r\n const focusAt = (index: number) => {\r\n const list = enabledItems();\r\n if (list.length === 0) return;\r\n list[(index + list.length) % list.length]?.focus();\r\n };\r\n\r\n const close = (restoreFocus = true) => {\r\n setOpen(false);\r\n if (restoreFocus) triggerRef.current?.focus();\r\n };\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n requestAnimationFrame(() =>\r\n menuRef.current\r\n ?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])')\r\n ?.focus(),\r\n );\r\n const onClickOutside = (e: MouseEvent) => {\r\n if (!containerRef.current?.contains(e.target as Node)) setOpen(false);\r\n };\r\n document.addEventListener('mousedown', onClickOutside);\r\n return () => document.removeEventListener('mousedown', onClickOutside);\r\n }, [open]);\r\n\r\n const onMenuKeyDown = (e: React.KeyboardEvent) => {\r\n const list = enabledItems();\r\n const index = list.indexOf(document.activeElement as HTMLElement);\r\n if (e.key === 'ArrowDown') {\r\n e.preventDefault();\r\n focusAt(index + 1);\r\n } else if (e.key === 'ArrowUp') {\r\n e.preventDefault();\r\n focusAt(index - 1);\r\n } else if (e.key === 'Home') {\r\n e.preventDefault();\r\n focusAt(0);\r\n } else if (e.key === 'End') {\r\n e.preventDefault();\r\n focusAt(list.length - 1);\r\n } else if (e.key === 'Escape') {\r\n e.preventDefault();\r\n close();\r\n } else if (e.key === 'Tab') {\r\n close(false);\r\n } else if (e.key.length === 1 && /\\S/.test(e.key)) {\r\n const char = e.key.toLocaleLowerCase('pt-BR');\r\n const match = list.findIndex(\r\n (el, i) => i > index && el.textContent?.trim().toLocaleLowerCase('pt-BR').startsWith(char),\r\n );\r\n const fallback = list.findIndex((el) =>\r\n el.textContent?.trim().toLocaleLowerCase('pt-BR').startsWith(char),\r\n );\r\n const target = match >= 0 ? match : fallback;\r\n if (target >= 0) focusAt(target);\r\n }\r\n };\r\n\r\n return (\r\n <div ref={containerRef} className=\"relative inline-flex\">\r\n <button\r\n ref={triggerRef}\r\n aria-controls={open ? menuId : undefined}\r\n aria-expanded={open}\r\n aria-haspopup=\"menu\"\r\n aria-label={ariaLabel}\r\n className={cn(\r\n buttonReset,\r\n 'inline-flex cursor-pointer items-center',\r\n focusRing,\r\n triggerClassName,\r\n )}\r\n onClick={() => setOpen((v) => !v)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\r\n e.preventDefault();\r\n setOpen(true);\r\n }\r\n }}\r\n type=\"button\"\r\n >\r\n {trigger}\r\n </button>\r\n {open && (\r\n <div\r\n ref={menuRef}\r\n aria-label={ariaLabel}\r\n className={cn(\r\n 'absolute top-full z-[var(--sbk-z-dropdown)] mt-1 min-w-48 rounded-sbk-sm p-1 animate-sbk-fade-in',\r\n variant === 'glass'\r\n ? 'sbk-glass sbk-glass-strong'\r\n : 'border border-sbk-line bg-sbk-surface shadow-sbk-md',\r\n align === 'end' ? 'right-0' : 'left-0',\r\n )}\r\n id={menuId}\r\n onKeyDown={onMenuKeyDown}\r\n role=\"menu\"\r\n tabIndex={-1}\r\n >\r\n {items.map((entry) =>\r\n isItem(entry) ? (\r\n <div\r\n key={entry.id}\r\n aria-disabled={entry.disabled || undefined}\r\n className={cn(\r\n 'flex cursor-pointer select-none items-center gap-2 rounded-sbk-xs px-2.5 py-2 text-sm font-light outline-none',\r\n 'hover:bg-sbk-surface-hover focus:bg-sbk-surface-hover',\r\n entry.danger ? 'text-sbk-error-fg' : 'text-sbk-fg',\r\n entry.disabled && 'pointer-events-none opacity-50',\r\n '[&_svg]:size-4 [&_svg]:shrink-0',\r\n )}\r\n onClick={() => {\r\n if (entry.disabled) return;\r\n entry.onSelect?.();\r\n close();\r\n }}\r\n onKeyDown={(e) => {\r\n if ((e.key === 'Enter' || e.key === ' ') && !entry.disabled) {\r\n e.preventDefault();\r\n entry.onSelect?.();\r\n close();\r\n }\r\n }}\r\n role=\"menuitem\"\r\n tabIndex={-1}\r\n >\r\n {entry.icon && (\r\n <span aria-hidden=\"true\" className=\"inline-flex text-sbk-fg-muted\">\r\n {entry.icon}\r\n </span>\r\n )}\r\n <span className=\"flex-1\">{entry.label}</span>\r\n {entry.shortcut && (\r\n <kbd className=\"font-sbk text-xs font-light text-sbk-fg-muted\">\r\n {entry.shortcut}\r\n </kbd>\r\n )}\r\n </div>\r\n ) : (\r\n <div key={entry.id} className=\"my-1 h-px bg-sbk-line\" role=\"separator\" />\r\n ),\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nDropdownMenu.displayName = 'DropdownMenu';\r\n"],"names":["isItem","entry","DropdownMenu","trigger","items","align","variant","triggerClassName","ariaLabel","open","setOpen","useState","menuId","useId","triggerRef","useRef","menuRef","containerRef","enabledItems","_a","focusAt","index","list","close","restoreFocus","useEffect","_b","onClickOutside","e","onMenuKeyDown","char","match","el","i","fallback","target","jsxs","jsx","cn","buttonReset","focusRing","v"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EmptyState.js","sources":["../../../src/components/EmptyState/EmptyState.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface EmptyStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n action?: React.ReactNode;\n description?: React.ReactNode;\n icon?: React.ReactNode;\n title: React.ReactNode;\n /** Nível do título. Padrão: h3. */\n titleAs?: 'h2' | 'h3' | 'h4';\n}\n\n/** Estado vazio: ausência de dados com orientação do próximo passo. */\nexport const EmptyState = ({\n icon,\n title,\n titleAs: TitleTag = 'h3',\n description,\n action,\n className,\n ...props\n}: EmptyStateProps) => (\n <div\n className={cn(\n 'grid justify-items-center gap-3 rounded-sbk-md border border-dashed border-sbk-line-strong bg-sbk-surface p-8 text-center',\n className,\n )}\n {...props}\n >\n {icon && (\n <div\n aria-hidden=\"true\"\n className=\"inline-flex size-12 items-center justify-center rounded-full bg-sbk-primary-subtle text-sbk-primary [&_svg]:size-6\"\n >\n {icon}\n </div>\n )}\n <TitleTag className=\"m-0 text-lg font-semibold text-sbk-fg-heading\">{title}</TitleTag>\n {description && (\n <p className=\"m-0 max-w-[30rem] text-sm font-light text-sbk-fg-muted\">{description}</p>\n )}\n {action && <div className=\"mt-1\">{action}</div>}\n </div>\n);\n\nEmptyState.displayName = 'EmptyState';\n"],"names":["EmptyState","icon","title","TitleTag","description","action","className","props","jsxs","cn","jsx"],"mappings":";;AAaO,MAAMA,IAAa,CAAC;AAAA,EACzB,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,SAASC,IAAW;AAAA,EACpB,aAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,MACE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,IAEH,UAAA;AAAA,MAAAN,KACC,gBAAAS;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,UAET,UAAAT;AAAA,QAAA;AAAA,MAAA;AAAA,MAGL,gBAAAS,EAACP,GAAA,EAAS,WAAU,iDAAiD,UAAAD,GAAM;AAAA,MAC1EE,KACC,gBAAAM,EAAC,KAAA,EAAE,WAAU,0DAA0D,UAAAN,GAAY;AAAA,MAEpFC,KAAU,gBAAAK,EAAC,OAAA,EAAI,WAAU,QAAQ,UAAAL,EAAA,CAAO;AAAA,IAAA;AAAA,EAAA;AAC3C;AAGFL,EAAW,cAAc;"}
1
+ {"version":3,"file":"EmptyState.js","sources":["../../../src/components/EmptyState/EmptyState.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport interface EmptyStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\r\n action?: React.ReactNode;\r\n description?: React.ReactNode;\r\n icon?: React.ReactNode;\r\n title: React.ReactNode;\r\n /** Nível do título. Padrão: h3. */\r\n titleAs?: 'h2' | 'h3' | 'h4';\r\n}\r\n\r\n/** Estado vazio: ausência de dados com orientação do próximo passo. */\r\nexport const EmptyState = ({\r\n icon,\r\n title,\r\n titleAs: TitleTag = 'h3',\r\n description,\r\n action,\r\n className,\r\n ...props\r\n}: EmptyStateProps) => (\r\n <div\r\n className={cn(\r\n 'grid justify-items-center gap-3 rounded-sbk-md border border-dashed border-sbk-line-strong bg-sbk-surface p-8 text-center',\r\n className,\r\n )}\r\n {...props}\r\n >\r\n {icon && (\r\n <div\r\n aria-hidden=\"true\"\r\n className=\"inline-flex size-12 items-center justify-center rounded-full bg-sbk-primary-subtle text-sbk-primary [&_svg]:size-6\"\r\n >\r\n {icon}\r\n </div>\r\n )}\r\n <TitleTag className=\"m-0 text-lg font-semibold text-sbk-fg-heading\">{title}</TitleTag>\r\n {description && (\r\n <p className=\"m-0 max-w-[30rem] text-sm font-light text-sbk-fg-muted\">{description}</p>\r\n )}\r\n {action && <div className=\"mt-1\">{action}</div>}\r\n </div>\r\n);\r\n\r\nEmptyState.displayName = 'EmptyState';\r\n"],"names":["EmptyState","icon","title","TitleTag","description","action","className","props","jsxs","cn","jsx"],"mappings":";;AAaO,MAAMA,IAAa,CAAC;AAAA,EACzB,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,SAASC,IAAW;AAAA,EACpB,aAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,MACE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,IAEH,UAAA;AAAA,MAAAN,KACC,gBAAAS;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,UAET,UAAAT;AAAA,QAAA;AAAA,MAAA;AAAA,MAGL,gBAAAS,EAACP,GAAA,EAAS,WAAU,iDAAiD,UAAAD,GAAM;AAAA,MAC1EE,KACC,gBAAAM,EAAC,KAAA,EAAE,WAAU,0DAA0D,UAAAN,GAAY;AAAA,MAEpFC,KAAU,gBAAAK,EAAC,OAAA,EAAI,WAAU,QAAQ,UAAAL,EAAA,CAAO;AAAA,IAAA;AAAA,EAAA;AAC3C;AAGFL,EAAW,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Field.js","sources":["../../../src/components/Field/Field.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\nimport { fieldError, fieldHelper, fieldLabel } from '../../utils/styles';\n\nexport interface FieldProps {\n children: React.ReactNode;\n className?: string;\n error?: string;\n helperText?: string;\n /** id do controle. Os textos de apoio recebem `${id}-helper` e `${id}-error`. */\n id: string;\n label?: React.ReactNode;\n /** Use `span` quando o controle não for rotulável por <label> (ex.: grupo, upload). */\n labelAs?: 'label' | 'span';\n required?: boolean;\n}\n\n/**\n * Estrutura comum de campo: rótulo, controle, texto de apoio e erro.\n * Use para compor controles próprios mantendo o padrão visual e de acessibilidade.\n */\nexport const Field = ({\n id,\n label,\n labelAs = 'label',\n helperText,\n error,\n required,\n className,\n children,\n}: FieldProps) => {\n const LabelTag = labelAs;\n return (\n <div className={cn('grid gap-1.5', className)}>\n {label && (\n <LabelTag\n className={fieldLabel}\n {...(labelAs === 'label' ? { htmlFor: id } : { id: `${id}-label` })}\n >\n {label}\n {required && (\n <span aria-hidden=\"true\" className=\"ml-0.5 text-sbk-error-fg\">\n *\n </span>\n )}\n </LabelTag>\n )}\n {children}\n {error ? (\n <span className={fieldError} id={`${id}-error`} role=\"alert\">\n {error}\n </span>\n ) : (\n helperText && (\n <span className={fieldHelper} id={`${id}-helper`}>\n {helperText}\n </span>\n )\n )}\n </div>\n );\n};\n\nField.displayName = 'Field';\n"],"names":["Field","id","label","labelAs","helperText","error","required","className","children","LabelTag","cn","jsxs","fieldLabel","jsx","fieldError","fieldHelper"],"mappings":";;;AAqBO,MAAMA,IAAQ,CAAC;AAAA,EACpB,IAAAC;AAAA,EACA,OAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,YAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AACF,MAAkB;AAChB,QAAMC,IAAWN;AACjB,2BACG,OAAA,EAAI,WAAWO,EAAG,gBAAgBH,CAAS,GACzC,UAAA;AAAA,IAAAL,KACC,gBAAAS;AAAA,MAACF;AAAA,MAAA;AAAA,QACC,WAAWG;AAAA,QACV,GAAIT,MAAY,UAAU,EAAE,SAASF,EAAA,IAAO,EAAE,IAAI,GAAGA,CAAE,SAAA;AAAA,QAEvD,UAAA;AAAA,UAAAC;AAAA,UACAI,KACC,gBAAAO,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,4BAA2B,UAAA,IAAA,CAE9D;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAILL;AAAA,IACAH,sBACE,QAAA,EAAK,WAAWS,GAAY,IAAI,GAAGb,CAAE,UAAU,MAAK,SAClD,aACH,IAEAG,uBACG,QAAA,EAAK,WAAWW,GAAa,IAAI,GAAGd,CAAE,WACpC,UAAAG,EAAA,CACH;AAAA,EAAA,GAGN;AAEJ;AAEAJ,EAAM,cAAc;"}
1
+ {"version":3,"file":"Field.js","sources":["../../../src/components/Field/Field.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { fieldError, fieldHelper, fieldLabel } from '../../utils/styles';\r\n\r\nexport interface FieldProps {\r\n children: React.ReactNode;\r\n className?: string;\r\n error?: string;\r\n helperText?: string;\r\n /** id do controle. Os textos de apoio recebem `${id}-helper` e `${id}-error`. */\r\n id: string;\r\n label?: React.ReactNode;\r\n /** Use `span` quando o controle não for rotulável por <label> (ex.: grupo, upload). */\r\n labelAs?: 'label' | 'span';\r\n required?: boolean;\r\n}\r\n\r\n/**\r\n * Estrutura comum de campo: rótulo, controle, texto de apoio e erro.\r\n * Use para compor controles próprios mantendo o padrão visual e de acessibilidade.\r\n */\r\nexport const Field = ({\r\n id,\r\n label,\r\n labelAs = 'label',\r\n helperText,\r\n error,\r\n required,\r\n className,\r\n children,\r\n}: FieldProps) => {\r\n const LabelTag = labelAs;\r\n return (\r\n <div className={cn('grid gap-1.5', className)}>\r\n {label && (\r\n <LabelTag\r\n className={fieldLabel}\r\n {...(labelAs === 'label' ? { htmlFor: id } : { id: `${id}-label` })}\r\n >\r\n {label}\r\n {required && (\r\n <span aria-hidden=\"true\" className=\"ml-0.5 text-sbk-error-fg\">\r\n *\r\n </span>\r\n )}\r\n </LabelTag>\r\n )}\r\n {children}\r\n {error ? (\r\n <span className={fieldError} id={`${id}-error`} role=\"alert\">\r\n {error}\r\n </span>\r\n ) : (\r\n helperText && (\r\n <span className={fieldHelper} id={`${id}-helper`}>\r\n {helperText}\r\n </span>\r\n )\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nField.displayName = 'Field';\r\n"],"names":["Field","id","label","labelAs","helperText","error","required","className","children","LabelTag","cn","jsxs","fieldLabel","jsx","fieldError","fieldHelper"],"mappings":";;;AAqBO,MAAMA,IAAQ,CAAC;AAAA,EACpB,IAAAC;AAAA,EACA,OAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,YAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AACF,MAAkB;AAChB,QAAMC,IAAWN;AACjB,2BACG,OAAA,EAAI,WAAWO,EAAG,gBAAgBH,CAAS,GACzC,UAAA;AAAA,IAAAL,KACC,gBAAAS;AAAA,MAACF;AAAA,MAAA;AAAA,QACC,WAAWG;AAAA,QACV,GAAIT,MAAY,UAAU,EAAE,SAASF,EAAA,IAAO,EAAE,IAAI,GAAGA,CAAE,SAAA;AAAA,QAEvD,UAAA;AAAA,UAAAC;AAAA,UACAI,KACC,gBAAAO,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,4BAA2B,UAAA,IAAA,CAE9D;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAILL;AAAA,IACAH,sBACE,QAAA,EAAK,WAAWS,GAAY,IAAI,GAAGb,CAAE,UAAU,MAAK,SAClD,aACH,IAEAG,uBACG,QAAA,EAAK,WAAWW,GAAa,IAAI,GAAGd,CAAE,WACpC,UAAAG,EAAA,CACH;AAAA,EAAA,GAGN;AAEJ;AAEAJ,EAAM,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"FileUpload.js","sources":["../../../src/components/FileUpload/FileUpload.tsx"],"sourcesContent":["import React, { useId, useRef, useState } from 'react';\nimport { FileText, UploadCloud, X } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\nimport { Field } from '../Field/Field';\n\nexport interface FileUploadProps {\n accept?: string;\n className?: string;\n disabled?: boolean;\n error?: string;\n helperText?: string;\n id?: string;\n label?: React.ReactNode;\n maxSizeBytes?: number;\n multiple?: boolean;\n onChange?: (files: File[]) => void;\n /** Lista os arquivos selecionados com opção de remover. Padrão: true. */\n showFileList?: boolean;\n}\n\nconst formatSize = (bytes: number) =>\n bytes >= 1024 * 1024\n ? `${(bytes / 1024 / 1024).toFixed(1)} MB`\n : `${Math.max(1, Math.round(bytes / 1024))} KB`;\n\n/** Área de upload com arrastar e soltar, acessível por teclado. */\nexport const FileUpload = ({\n label,\n helperText,\n error,\n accept,\n multiple = false,\n maxSizeBytes,\n disabled = false,\n showFileList = true,\n onChange,\n id,\n className,\n}: FileUploadProps) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n const [sizeError, setSizeError] = useState<string | null>(null);\n const [files, setFiles] = useState<File[]>([]);\n\n const commit = (next: File[]) => {\n setFiles(next);\n onChange?.(next);\n };\n\n const handleFiles = (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return;\n const incoming = Array.from(fileList);\n if (maxSizeBytes) {\n const oversized = incoming.find((f) => f.size > maxSizeBytes);\n if (oversized) {\n setSizeError(\n `Arquivo \"${oversized.name}\" excede o tamanho máximo de ${formatSize(maxSizeBytes)}.`,\n );\n return;\n }\n }\n setSizeError(null);\n commit(multiple ? [...files, ...incoming] : incoming.slice(0, 1));\n };\n\n const displayError = error ?? sizeError ?? undefined;\n const hints = [\n accept && `Formatos aceitos: ${accept}`,\n maxSizeBytes && `Tamanho máximo: ${formatSize(maxSizeBytes)}`,\n ]\n .filter(Boolean)\n .join(' · ');\n\n return (\n <Field\n className={className}\n error={displayError}\n helperText={helperText}\n id={inputId}\n label={label}\n labelAs=\"span\"\n >\n <div\n aria-describedby={\n displayError ? `${inputId}-error` : helperText ? `${inputId}-helper` : undefined\n }\n aria-disabled={disabled || undefined}\n aria-labelledby={label ? `${inputId}-label` : undefined}\n className={cn(\n 'flex cursor-pointer flex-col items-center justify-center gap-2 rounded-sbk-md border-2 border-dashed p-8 text-center',\n transitionColors,\n focusRing,\n isDragging\n ? 'border-sbk-primary bg-sbk-primary-subtle'\n : 'border-sbk-line-strong bg-sbk-surface hover:border-sbk-primary hover:bg-sbk-surface-hover',\n displayError && 'border-sbk-error',\n disabled && 'pointer-events-none opacity-60',\n )}\n onClick={() => !disabled && inputRef.current?.click()}\n onDragLeave={() => setIsDragging(false)}\n onDragOver={(e) => {\n e.preventDefault();\n if (!disabled) setIsDragging(true);\n }}\n onDrop={(e) => {\n e.preventDefault();\n setIsDragging(false);\n if (!disabled) handleFiles(e.dataTransfer.files);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n inputRef.current?.click();\n }\n }}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n >\n <UploadCloud aria-hidden=\"true\" className=\"size-8 text-sbk-primary\" strokeWidth={1.5} />\n <p className=\"m-0 text-sm font-light text-sbk-fg\">\n Arraste arquivos aqui ou{' '}\n <span className=\"font-semibold text-sbk-primary underline\">clique para selecionar</span>\n </p>\n {hints && <p className=\"m-0 text-xs font-light text-sbk-fg-muted\">{hints}</p>}\n </div>\n <input\n ref={inputRef}\n accept={accept}\n className=\"sr-only\"\n disabled={disabled}\n id={inputId}\n multiple={multiple}\n onChange={(e) => {\n handleFiles(e.target.files);\n e.target.value = '';\n }}\n tabIndex={-1}\n type=\"file\"\n />\n {showFileList && files.length > 0 && (\n <ul aria-label=\"Arquivos selecionados\" className=\"m-0 grid list-none gap-1.5 p-0\">\n {files.map((file, index) => (\n <li\n key={`${file.name}-${index}`}\n className=\"flex items-center gap-2 rounded-sbk-sm border border-sbk-line bg-sbk-surface px-3 py-2 text-sm\"\n >\n <FileText aria-hidden=\"true\" className=\"size-4 shrink-0 text-sbk-fg-muted\" />\n <span className=\"min-w-0 flex-1 truncate font-light text-sbk-fg\">{file.name}</span>\n <span className=\"shrink-0 text-xs font-light text-sbk-fg-muted\">\n {formatSize(file.size)}\n </span>\n <button\n aria-label={`Remover ${file.name}`}\n className={cn(\n buttonReset,\n 'inline-flex size-6 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 disabled={disabled}\n onClick={() => commit(files.filter((_, i) => i !== index))}\n type=\"button\"\n >\n <X aria-hidden=\"true\" className=\"size-4\" />\n </button>\n </li>\n ))}\n </ul>\n )}\n </Field>\n );\n};\n\nFileUpload.displayName = 'FileUpload';\n"],"names":["formatSize","bytes","FileUpload","label","helperText","error","accept","multiple","maxSizeBytes","disabled","showFileList","onChange","id","className","autoId","useId","inputId","inputRef","useRef","isDragging","setIsDragging","useState","sizeError","setSizeError","files","setFiles","commit","next","handleFiles","fileList","incoming","oversized","f","displayError","hints","jsxs","Field","cn","transitionColors","focusRing","_a","jsx","UploadCloud","file","index","FileText","buttonReset","_","i","X"],"mappings":"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"}
1
+ {"version":3,"file":"FileUpload.js","sources":["../../../src/components/FileUpload/FileUpload.tsx"],"sourcesContent":["import React, { useId, useRef, useState } from 'react';\r\nimport { FileText, UploadCloud, X } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\r\nimport { Field } from '../Field/Field';\r\n\r\nexport interface FileUploadProps {\r\n accept?: string;\r\n className?: string;\r\n disabled?: boolean;\r\n error?: string;\r\n helperText?: string;\r\n id?: string;\r\n label?: React.ReactNode;\r\n maxSizeBytes?: number;\r\n multiple?: boolean;\r\n onChange?: (files: File[]) => void;\r\n /** Lista os arquivos selecionados com opção de remover. Padrão: true. */\r\n showFileList?: boolean;\r\n}\r\n\r\nconst formatSize = (bytes: number) =>\r\n bytes >= 1024 * 1024\r\n ? `${(bytes / 1024 / 1024).toFixed(1)} MB`\r\n : `${Math.max(1, Math.round(bytes / 1024))} KB`;\r\n\r\n/** Área de upload com arrastar e soltar, acessível por teclado. */\r\nexport const FileUpload = ({\r\n label,\r\n helperText,\r\n error,\r\n accept,\r\n multiple = false,\r\n maxSizeBytes,\r\n disabled = false,\r\n showFileList = true,\r\n onChange,\r\n id,\r\n className,\r\n}: FileUploadProps) => {\r\n const autoId = useId();\r\n const inputId = id ?? autoId;\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const [isDragging, setIsDragging] = useState(false);\r\n const [sizeError, setSizeError] = useState<string | null>(null);\r\n const [files, setFiles] = useState<File[]>([]);\r\n\r\n const commit = (next: File[]) => {\r\n setFiles(next);\r\n onChange?.(next);\r\n };\r\n\r\n const handleFiles = (fileList: FileList | null) => {\r\n if (!fileList || fileList.length === 0) return;\r\n const incoming = Array.from(fileList);\r\n if (maxSizeBytes) {\r\n const oversized = incoming.find((f) => f.size > maxSizeBytes);\r\n if (oversized) {\r\n setSizeError(\r\n `Arquivo \"${oversized.name}\" excede o tamanho máximo de ${formatSize(maxSizeBytes)}.`,\r\n );\r\n return;\r\n }\r\n }\r\n setSizeError(null);\r\n commit(multiple ? [...files, ...incoming] : incoming.slice(0, 1));\r\n };\r\n\r\n const displayError = error ?? sizeError ?? undefined;\r\n const hints = [\r\n accept && `Formatos aceitos: ${accept}`,\r\n maxSizeBytes && `Tamanho máximo: ${formatSize(maxSizeBytes)}`,\r\n ]\r\n .filter(Boolean)\r\n .join(' · ');\r\n\r\n return (\r\n <Field\r\n className={className}\r\n error={displayError}\r\n helperText={helperText}\r\n id={inputId}\r\n label={label}\r\n labelAs=\"span\"\r\n >\r\n <div\r\n aria-describedby={\r\n displayError ? `${inputId}-error` : helperText ? `${inputId}-helper` : undefined\r\n }\r\n aria-disabled={disabled || undefined}\r\n aria-labelledby={label ? `${inputId}-label` : undefined}\r\n className={cn(\r\n 'flex cursor-pointer flex-col items-center justify-center gap-2 rounded-sbk-md border-2 border-dashed p-8 text-center',\r\n transitionColors,\r\n focusRing,\r\n isDragging\r\n ? 'border-sbk-primary bg-sbk-primary-subtle'\r\n : 'border-sbk-line-strong bg-sbk-surface hover:border-sbk-primary hover:bg-sbk-surface-hover',\r\n displayError && 'border-sbk-error',\r\n disabled && 'pointer-events-none opacity-60',\r\n )}\r\n onClick={() => !disabled && inputRef.current?.click()}\r\n onDragLeave={() => setIsDragging(false)}\r\n onDragOver={(e) => {\r\n e.preventDefault();\r\n if (!disabled) setIsDragging(true);\r\n }}\r\n onDrop={(e) => {\r\n e.preventDefault();\r\n setIsDragging(false);\r\n if (!disabled) handleFiles(e.dataTransfer.files);\r\n }}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n inputRef.current?.click();\r\n }\r\n }}\r\n role=\"button\"\r\n tabIndex={disabled ? -1 : 0}\r\n >\r\n <UploadCloud aria-hidden=\"true\" className=\"size-8 text-sbk-primary\" strokeWidth={1.5} />\r\n <p className=\"m-0 text-sm font-light text-sbk-fg\">\r\n Arraste arquivos aqui ou{' '}\r\n <span className=\"font-semibold text-sbk-primary underline\">clique para selecionar</span>\r\n </p>\r\n {hints && <p className=\"m-0 text-xs font-light text-sbk-fg-muted\">{hints}</p>}\r\n </div>\r\n <input\r\n ref={inputRef}\r\n accept={accept}\r\n className=\"sr-only\"\r\n disabled={disabled}\r\n id={inputId}\r\n multiple={multiple}\r\n onChange={(e) => {\r\n handleFiles(e.target.files);\r\n e.target.value = '';\r\n }}\r\n tabIndex={-1}\r\n type=\"file\"\r\n />\r\n {showFileList && files.length > 0 && (\r\n <ul aria-label=\"Arquivos selecionados\" className=\"m-0 grid list-none gap-1.5 p-0\">\r\n {files.map((file, index) => (\r\n <li\r\n key={`${file.name}-${index}`}\r\n className=\"flex items-center gap-2 rounded-sbk-sm border border-sbk-line bg-sbk-surface px-3 py-2 text-sm\"\r\n >\r\n <FileText aria-hidden=\"true\" className=\"size-4 shrink-0 text-sbk-fg-muted\" />\r\n <span className=\"min-w-0 flex-1 truncate font-light text-sbk-fg\">{file.name}</span>\r\n <span className=\"shrink-0 text-xs font-light text-sbk-fg-muted\">\r\n {formatSize(file.size)}\r\n </span>\r\n <button\r\n aria-label={`Remover ${file.name}`}\r\n className={cn(\r\n buttonReset,\r\n 'inline-flex size-6 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 disabled={disabled}\r\n onClick={() => commit(files.filter((_, i) => i !== index))}\r\n type=\"button\"\r\n >\r\n <X aria-hidden=\"true\" className=\"size-4\" />\r\n </button>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </Field>\r\n );\r\n};\r\n\r\nFileUpload.displayName = 'FileUpload';\r\n"],"names":["formatSize","bytes","FileUpload","label","helperText","error","accept","multiple","maxSizeBytes","disabled","showFileList","onChange","id","className","autoId","useId","inputId","inputRef","useRef","isDragging","setIsDragging","useState","sizeError","setSizeError","files","setFiles","commit","next","handleFiles","fileList","incoming","oversized","f","displayError","hints","jsxs","Field","cn","transitionColors","focusRing","_a","jsx","UploadCloud","file","index","FileText","buttonReset","_","i","X"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Footer.js","sources":["../../../src/components/Footer/Footer.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\nimport { focusRing } from '../../utils/styles';\nimport { Logo, type LogoVariant } from '../Logo/Logo';\n\nexport interface FooterLink {\n href: string;\n label: React.ReactNode;\n}\n\nexport interface FooterProps {\n className?: string;\n /** Texto de copyright (ex.: \"© 2026 SBK\"). */\n copyright?: React.ReactNode;\n /** Links institucionais (privacidade, termos, suporte). */\n links?: FooterLink[];\n logoAlt?: string;\n /** @deprecated Não utilizado. Mantido por compatibilidade com a 1.x. */\n logoFallbackText?: string;\n /** Imagem de logo customizada (substitui o SVG oficial). */\n logoSrc?: string;\n logoVariant?: LogoVariant;\n /** Texto antes do logo. Padrão: \"Powered by\". Use \"\" para ocultar. */\n poweredByText?: string;\n /** `default`: superfície clara. `inverse`: verde escuro. `glass`: Liquid Glass. */\n variant?: 'default' | 'inverse' | 'glass';\n}\n\nconst VARIANT_CLASS = {\n default: 'border-t border-sbk-line bg-sbk-surface',\n inverse:\n 'bg-sbk-surface-inverse text-sbk-fg-inverse [--sbk-color-fg-muted:color-mix(in_srgb,var(--sbk-color-fg-inverse)_72%,transparent)] [--sbk-color-fg-heading:var(--sbk-color-fg-inverse)]',\n glass: 'sbk-glass rounded-none border-x-0 border-b-0',\n} as const;\n\nexport const Footer = ({\n poweredByText = 'Powered by',\n logoSrc,\n logoAlt = 'SBK',\n logoVariant = 'sbk',\n links,\n copyright,\n variant = 'default',\n className,\n}: FooterProps) => (\n <footer\n className={cn(\n 'relative box-border flex w-full shrink-0 flex-wrap items-center justify-center gap-x-8 gap-y-3 px-4 py-5 md:px-8',\n (links || copyright) && 'md:justify-between',\n VARIANT_CLASS[variant],\n className,\n )}\n >\n <div className=\"flex items-center gap-2.5\">\n {poweredByText && (\n <span className=\"text-xs font-light text-sbk-fg-muted\">{poweredByText}</span>\n )}\n {logoSrc ? (\n <img alt={logoAlt} className=\"h-7 w-auto object-contain\" src={logoSrc} />\n ) : (\n <Logo color={variant === 'inverse' ? 'white' : 'auto'} height={22} variant={logoVariant} />\n )}\n </div>\n {links && links.length > 0 && (\n <nav aria-label=\"Rodapé\">\n <ul className=\"m-0 flex list-none flex-wrap gap-x-5 gap-y-2 p-0\">\n {links.map((link) => (\n <li key={link.href}>\n <a\n className={cn(\n 'rounded-sbk-xs text-xs font-light text-sbk-fg-muted underline-offset-4 hover:text-sbk-fg-heading hover:underline',\n focusRing,\n )}\n href={link.href}\n >\n {link.label}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n )}\n {copyright && <p className=\"m-0 text-xs font-light text-sbk-fg-muted\">{copyright}</p>}\n </footer>\n);\n\nFooter.displayName = 'Footer';\n"],"names":["VARIANT_CLASS","Footer","poweredByText","logoSrc","logoAlt","logoVariant","links","copyright","variant","className","jsxs","cn","jsx","Logo","link","focusRing"],"mappings":";;;;AA4BA,MAAMA,IAAgB;AAAA,EACpB,SAAS;AAAA,EACT,SACE;AAAA,EACF,OAAO;AACT,GAEaC,IAAS,CAAC;AAAA,EACrB,eAAAC,IAAgB;AAAA,EAChB,SAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,aAAAC,IAAc;AAAA,EACd,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,WAAAC;AACF,MACE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,OACCL,KAASC,MAAc;AAAA,MACxBP,EAAcQ,CAAO;AAAA,MACrBC;AAAA,IAAA;AAAA,IAGF,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,QAAAR,KACC,gBAAAU,EAAC,QAAA,EAAK,WAAU,wCAAwC,UAAAV,GAAc;AAAA,QAEvEC,sBACE,OAAA,EAAI,KAAKC,GAAS,WAAU,6BAA4B,KAAKD,GAAS,sBAEtEU,GAAA,EAAK,OAAOL,MAAY,YAAY,UAAU,QAAQ,QAAQ,IAAI,SAASH,EAAA,CAAa;AAAA,MAAA,GAE7F;AAAA,MACCC,KAASA,EAAM,SAAS,KACvB,gBAAAM,EAAC,SAAI,cAAW,UACd,UAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,oDACX,UAAAN,EAAM,IAAI,CAACQ,wBACT,MAAA,EACC,UAAA,gBAAAF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWD;AAAA,YACT;AAAA,YACAI;AAAA,UAAA;AAAA,UAEF,MAAMD,EAAK;AAAA,UAEV,UAAAA,EAAK;AAAA,QAAA;AAAA,MAAA,EACR,GATOA,EAAK,IAUd,CACD,GACH,EAAA,CACF;AAAA,MAEDP,KAAa,gBAAAK,EAAC,KAAA,EAAE,WAAU,4CAA4C,UAAAL,EAAA,CAAU;AAAA,IAAA;AAAA,EAAA;AACnF;AAGFN,EAAO,cAAc;"}
1
+ {"version":3,"file":"Footer.js","sources":["../../../src/components/Footer/Footer.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { focusRing } from '../../utils/styles';\r\nimport { Logo, type LogoVariant } from '../Logo/Logo';\r\n\r\nexport interface FooterLink {\r\n href: string;\r\n label: React.ReactNode;\r\n}\r\n\r\nexport interface FooterProps {\r\n className?: string;\r\n /** Texto de copyright (ex.: \"© 2026 SBK\"). */\r\n copyright?: React.ReactNode;\r\n /** Links institucionais (privacidade, termos, suporte). */\r\n links?: FooterLink[];\r\n logoAlt?: string;\r\n /** @deprecated Não utilizado. Mantido por compatibilidade com a 1.x. */\r\n logoFallbackText?: string;\r\n /** Imagem de logo customizada (substitui o SVG oficial). */\r\n logoSrc?: string;\r\n logoVariant?: LogoVariant;\r\n /** Texto antes do logo. Padrão: \"Powered by\". Use \"\" para ocultar. */\r\n poweredByText?: string;\r\n /** `default`: superfície clara. `inverse`: verde escuro. `glass`: Liquid Glass. */\r\n variant?: 'default' | 'inverse' | 'glass';\r\n}\r\n\r\nconst VARIANT_CLASS = {\r\n default: 'border-t border-sbk-line bg-sbk-surface',\r\n inverse:\r\n 'bg-sbk-surface-inverse text-sbk-fg-inverse [--sbk-color-fg-muted:color-mix(in_srgb,var(--sbk-color-fg-inverse)_72%,transparent)] [--sbk-color-fg-heading:var(--sbk-color-fg-inverse)]',\r\n glass: 'sbk-glass rounded-none border-x-0 border-b-0',\r\n} as const;\r\n\r\nexport const Footer = ({\r\n poweredByText = 'Powered by',\r\n logoSrc,\r\n logoAlt = 'SBK',\r\n logoVariant = 'sbk',\r\n links,\r\n copyright,\r\n variant = 'default',\r\n className,\r\n}: FooterProps) => (\r\n <footer\r\n className={cn(\r\n 'relative box-border flex w-full shrink-0 flex-wrap items-center justify-center gap-x-8 gap-y-3 px-4 py-5 md:px-8',\r\n (links || copyright) && 'md:justify-between',\r\n VARIANT_CLASS[variant],\r\n className,\r\n )}\r\n >\r\n <div className=\"flex items-center gap-2.5\">\r\n {poweredByText && (\r\n <span className=\"text-xs font-light text-sbk-fg-muted\">{poweredByText}</span>\r\n )}\r\n {logoSrc ? (\r\n <img alt={logoAlt} className=\"h-7 w-auto object-contain\" src={logoSrc} />\r\n ) : (\r\n <Logo color={variant === 'inverse' ? 'white' : 'auto'} height={22} variant={logoVariant} />\r\n )}\r\n </div>\r\n {links && links.length > 0 && (\r\n <nav aria-label=\"Rodapé\">\r\n <ul className=\"m-0 flex list-none flex-wrap gap-x-5 gap-y-2 p-0\">\r\n {links.map((link) => (\r\n <li key={link.href}>\r\n <a\r\n className={cn(\r\n 'rounded-sbk-xs text-xs font-light text-sbk-fg-muted underline-offset-4 hover:text-sbk-fg-heading hover:underline',\r\n focusRing,\r\n )}\r\n href={link.href}\r\n >\r\n {link.label}\r\n </a>\r\n </li>\r\n ))}\r\n </ul>\r\n </nav>\r\n )}\r\n {copyright && <p className=\"m-0 text-xs font-light text-sbk-fg-muted\">{copyright}</p>}\r\n </footer>\r\n);\r\n\r\nFooter.displayName = 'Footer';\r\n"],"names":["VARIANT_CLASS","Footer","poweredByText","logoSrc","logoAlt","logoVariant","links","copyright","variant","className","jsxs","cn","jsx","Logo","link","focusRing"],"mappings":";;;;AA4BA,MAAMA,IAAgB;AAAA,EACpB,SAAS;AAAA,EACT,SACE;AAAA,EACF,OAAO;AACT,GAEaC,IAAS,CAAC;AAAA,EACrB,eAAAC,IAAgB;AAAA,EAChB,SAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,aAAAC,IAAc;AAAA,EACd,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,WAAAC;AACF,MACE,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,OACCL,KAASC,MAAc;AAAA,MACxBP,EAAcQ,CAAO;AAAA,MACrBC;AAAA,IAAA;AAAA,IAGF,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,QAAAR,KACC,gBAAAU,EAAC,QAAA,EAAK,WAAU,wCAAwC,UAAAV,GAAc;AAAA,QAEvEC,sBACE,OAAA,EAAI,KAAKC,GAAS,WAAU,6BAA4B,KAAKD,GAAS,sBAEtEU,GAAA,EAAK,OAAOL,MAAY,YAAY,UAAU,QAAQ,QAAQ,IAAI,SAASH,EAAA,CAAa;AAAA,MAAA,GAE7F;AAAA,MACCC,KAASA,EAAM,SAAS,KACvB,gBAAAM,EAAC,SAAI,cAAW,UACd,UAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,oDACX,UAAAN,EAAM,IAAI,CAACQ,wBACT,MAAA,EACC,UAAA,gBAAAF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWD;AAAA,YACT;AAAA,YACAI;AAAA,UAAA;AAAA,UAEF,MAAMD,EAAK;AAAA,UAEV,UAAAA,EAAK;AAAA,QAAA;AAAA,MAAA,EACR,GATOA,EAAK,IAUd,CACD,GACH,EAAA,CACF;AAAA,MAEDP,KAAa,gBAAAK,EAAC,KAAA,EAAE,WAAU,4CAA4C,UAAAL,EAAA,CAAU;AAAA,IAAA;AAAA,EAAA;AACnF;AAGFN,EAAO,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"GlassPanel.js","sources":["../../../src/components/GlassPanel/GlassPanel.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface GlassPanelProps extends React.HTMLAttributes<HTMLDivElement> {\n as?: 'div' | 'section' | 'aside' | 'header' | 'nav' | 'footer';\n /** Intensidade do desfoque. Padrão: md (20px). */\n blur?: 'sm' | 'md' | 'lg';\n padding?: 'none' | 'sm' | 'md' | 'lg';\n radius?: 'sm' | 'md' | 'lg' | 'full';\n /** Aumenta a opacidade do fundo para melhorar a leitura sobre imagens movimentadas. */\n strong?: boolean;\n}\n\nconst BLUR = { sm: '12px', md: '20px', lg: '32px' } as const;\nconst PADDING = { none: 'p-0', sm: 'p-3', md: 'p-5', lg: 'p-8' } as const;\nconst RADIUS = {\n sm: 'rounded-sbk-sm',\n md: 'rounded-sbk-md',\n lg: 'rounded-sbk-lg',\n full: 'rounded-full',\n} as const;\n\n/**\n * Superfície \"Liquid Glass\" (inspirada no material da Apple): translucidez tingida de verde,\n * desfoque com saturação, borda especular e brilho interno.\n *\n * Acessibilidade: em `prefers-reduced-transparency` ou sem suporte a `backdrop-filter`,\n * cai para superfície opaca. Garanta contraste do texto sobre o conteúdo de fundo.\n */\nexport const GlassPanel = React.forwardRef<HTMLDivElement, GlassPanelProps>(\n (\n {\n as: Tag = 'div',\n blur = 'md',\n padding = 'md',\n radius = 'md',\n strong = false,\n className,\n style,\n ...props\n },\n ref,\n ) => (\n <Tag\n ref={ref}\n className={cn(\n 'sbk-glass text-sbk-fg',\n strong && 'sbk-glass-strong',\n PADDING[padding],\n RADIUS[radius],\n className,\n )}\n style={{ '--sbk-glass-blur': BLUR[blur], ...style } as React.CSSProperties}\n {...props}\n />\n ),\n);\n\nGlassPanel.displayName = 'GlassPanel';\n"],"names":["BLUR","PADDING","RADIUS","GlassPanel","React","Tag","blur","padding","radius","strong","className","style","props","ref","jsx","cn"],"mappings":";;;AAaA,MAAMA,IAAO,EAAE,IAAI,QAAQ,IAAI,QAAQ,IAAI,OAAA,GACrCC,IAAU,EAAE,MAAM,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,MAAA,GACnDC,IAAS;AAAA,EACb,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR,GASaC,IAAaC,EAAM;AAAA,EAC9B,CACE;AAAA,IACE,IAAIC,IAAM;AAAA,IACV,MAAAC,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,QAAAC,IAAS;AAAA,IACT,QAAAC,IAAS;AAAA,IACT,WAAAC;AAAA,IACA,OAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MAEA,gBAAAC;AAAA,IAACT;AAAA,IAAA;AAAA,MACC,KAAAQ;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACAN,KAAU;AAAA,QACVR,EAAQM,CAAO;AAAA,QACfL,EAAOM,CAAM;AAAA,QACbE;AAAA,MAAA;AAAA,MAEF,OAAO,EAAE,oBAAoBV,EAAKM,CAAI,GAAG,GAAGK,EAAA;AAAA,MAC3C,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV;AAEAT,EAAW,cAAc;"}
1
+ {"version":3,"file":"GlassPanel.js","sources":["../../../src/components/GlassPanel/GlassPanel.tsx"],"sourcesContent":["import React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport interface GlassPanelProps extends React.HTMLAttributes<HTMLDivElement> {\r\n as?: 'div' | 'section' | 'aside' | 'header' | 'nav' | 'footer';\r\n /** Intensidade do desfoque. Padrão: md (20px). */\r\n blur?: 'sm' | 'md' | 'lg';\r\n padding?: 'none' | 'sm' | 'md' | 'lg';\r\n radius?: 'sm' | 'md' | 'lg' | 'full';\r\n /** Aumenta a opacidade do fundo para melhorar a leitura sobre imagens movimentadas. */\r\n strong?: boolean;\r\n}\r\n\r\nconst BLUR = { sm: '12px', md: '20px', lg: '32px' } as const;\r\nconst PADDING = { none: 'p-0', sm: 'p-3', md: 'p-5', lg: 'p-8' } as const;\r\nconst RADIUS = {\r\n sm: 'rounded-sbk-sm',\r\n md: 'rounded-sbk-md',\r\n lg: 'rounded-sbk-lg',\r\n full: 'rounded-full',\r\n} as const;\r\n\r\n/**\r\n * Superfície \"Liquid Glass\" (inspirada no material da Apple): translucidez tingida de verde,\r\n * desfoque com saturação, borda especular e brilho interno.\r\n *\r\n * Acessibilidade: em `prefers-reduced-transparency` ou sem suporte a `backdrop-filter`,\r\n * cai para superfície opaca. Garanta contraste do texto sobre o conteúdo de fundo.\r\n */\r\nexport const GlassPanel = React.forwardRef<HTMLDivElement, GlassPanelProps>(\r\n (\r\n {\r\n as: Tag = 'div',\r\n blur = 'md',\r\n padding = 'md',\r\n radius = 'md',\r\n strong = false,\r\n className,\r\n style,\r\n ...props\r\n },\r\n ref,\r\n ) => (\r\n <Tag\r\n ref={ref}\r\n className={cn(\r\n 'sbk-glass text-sbk-fg',\r\n strong && 'sbk-glass-strong',\r\n PADDING[padding],\r\n RADIUS[radius],\r\n className,\r\n )}\r\n style={{ '--sbk-glass-blur': BLUR[blur], ...style } as React.CSSProperties}\r\n {...props}\r\n />\r\n ),\r\n);\r\n\r\nGlassPanel.displayName = 'GlassPanel';\r\n"],"names":["BLUR","PADDING","RADIUS","GlassPanel","React","Tag","blur","padding","radius","strong","className","style","props","ref","jsx","cn"],"mappings":";;;AAaA,MAAMA,IAAO,EAAE,IAAI,QAAQ,IAAI,QAAQ,IAAI,OAAA,GACrCC,IAAU,EAAE,MAAM,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,MAAA,GACnDC,IAAS;AAAA,EACb,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR,GASaC,IAAaC,EAAM;AAAA,EAC9B,CACE;AAAA,IACE,IAAIC,IAAM;AAAA,IACV,MAAAC,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,QAAAC,IAAS;AAAA,IACT,QAAAC,IAAS;AAAA,IACT,WAAAC;AAAA,IACA,OAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MAEA,gBAAAC;AAAA,IAACT;AAAA,IAAA;AAAA,MACC,KAAAQ;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACAN,KAAU;AAAA,QACVR,EAAQM,CAAO;AAAA,QACfL,EAAOM,CAAM;AAAA,QACbE;AAAA,MAAA;AAAA,MAEF,OAAO,EAAE,oBAAoBV,EAAKM,CAAI,GAAG,GAAGK,EAAA;AAAA,MAC3C,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV;AAEAT,EAAW,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Header.js","sources":["../../../src/components/Header/Header.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useState } from 'react';\nimport { Menu } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, focusRing, inverseScope } from '../../utils/styles';\nimport type { Theme } from '../../theme/ThemeProvider';\nimport { Logo, type LogoVariant } from '../Logo/Logo';\n\nexport type HeaderVariant = 'solid' | 'light' | 'glass';\n\nexport interface HeaderProps {\n className?: string;\n /** Texto alternativo da imagem de logo customizada. */\n logoAlt?: string;\n /** Imagem de logo para o tema escuro (substitui o SVG oficial). */\n logoDarkSrc?: string;\n /** Imagem de logo customizada (substitui o SVG oficial). */\n logoSrc?: string;\n /** Logo oficial usado quando não há `logoSrc`. Padrão: sbk. */\n logoVariant?: LogoVariant;\n /** Estado do menu lateral, anunciado no botão hamburger (aria-expanded). */\n menuExpanded?: boolean;\n /** Rótulo do botão hamburger. Padrão: \"Abrir menu\". */\n menuLabel?: string;\n /** Navegação principal, exibida ao centro. */\n navigation?: React.ReactNode;\n onLogoClick?: () => void;\n onMenuClick?: () => void;\n /** Conteúdo à direita (ações, seletor de tema, menu do usuário). */\n rightContent?: React.ReactNode;\n showMenuIcon?: boolean;\n /** Fixa o header no topo. Padrão: true. */\n sticky?: boolean;\n subtitle?: React.ReactNode;\n /** Tema para escolher entre logoSrc e logoDarkSrc sem depender do ThemeProvider. */\n theme?: Theme;\n title?: React.ReactNode;\n /** Iniciais do usuário exibidas no avatar (ex.: \"CF\"). */\n userInitials?: string;\n /** `solid`: verde escuro (padrão). `light`: superfície clara. `glass`: Liquid Glass. */\n variant?: HeaderVariant;\n}\n\nconst detectTheme = (): Theme =>\n typeof document !== 'undefined' && document.documentElement.getAttribute('data-theme') === 'dark'\n ? 'dark'\n : 'light';\n\nconst VARIANT_CLASS: Record<HeaderVariant, string> = {\n solid: inverseScope,\n light: 'border-b border-sbk-line bg-sbk-surface text-sbk-fg',\n glass: 'sbk-glass rounded-none border-x-0 border-t-0 text-sbk-fg',\n};\n\nexport const Header = ({\n logoSrc,\n logoDarkSrc,\n logoAlt = 'SBK',\n logoVariant = 'sbk',\n title,\n subtitle,\n theme,\n navigation,\n onLogoClick,\n onMenuClick,\n menuExpanded,\n menuLabel = 'Abrir menu',\n rightContent,\n showMenuIcon = true,\n sticky = true,\n userInitials,\n variant = 'solid',\n className,\n}: HeaderProps) => {\n const [resolvedTheme, setResolvedTheme] = useState<Theme>(() => theme ?? detectTheme());\n\n useEffect(() => {\n if (theme) {\n setResolvedTheme(theme);\n return;\n }\n if (!logoDarkSrc || typeof MutationObserver === 'undefined') return;\n const sync = () => setResolvedTheme(detectTheme());\n sync();\n const observer = new MutationObserver(sync);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-theme'],\n });\n return () => observer.disconnect();\n }, [theme, logoDarkSrc]);\n\n const customLogo = resolvedTheme === 'dark' && logoDarkSrc ? logoDarkSrc : logoSrc;\n const brand = (\n <>\n {customLogo ? (\n <img alt={logoAlt} className=\"h-8 w-auto shrink-0 object-contain\" src={customLogo} />\n ) : (\n <Logo color={variant === 'solid' ? 'white' : 'auto'} height={28} variant={logoVariant} />\n )}\n {(title || subtitle) && (\n <span className=\"grid min-w-0 gap-px text-left\">\n {title && (\n <span className=\"truncate text-base font-semibold leading-tight text-sbk-fg-heading\">\n {title}\n </span>\n )}\n {subtitle && (\n <span className=\"truncate text-xs font-light leading-tight text-sbk-fg-muted\">\n {subtitle}\n </span>\n )}\n </span>\n )}\n </>\n );\n\n return (\n <header\n className={cn(\n 'z-[var(--sbk-z-sticky)] box-border flex h-16 w-full shrink-0 items-center justify-between gap-4 px-4 md:px-8',\n sticky && 'sticky top-0',\n VARIANT_CLASS[variant],\n className,\n )}\n >\n <div className=\"flex min-w-0 items-center gap-3\">\n {showMenuIcon && (\n <button\n aria-expanded={menuExpanded}\n aria-label={menuLabel}\n className={cn(\n buttonReset,\n 'inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-sbk-sm text-sbk-fg hover:bg-sbk-surface-hover',\n focusRing,\n )}\n onClick={onMenuClick}\n type=\"button\"\n >\n <Menu aria-hidden=\"true\" className=\"size-5\" />\n </button>\n )}\n {onLogoClick ? (\n <button\n className={cn(\n buttonReset,\n 'flex min-w-0 cursor-pointer items-center gap-3 rounded-sbk-xs',\n focusRing,\n )}\n onClick={onLogoClick}\n type=\"button\"\n >\n {brand}\n </button>\n ) : (\n <div className=\"flex min-w-0 items-center gap-3\">{brand}</div>\n )}\n </div>\n\n {navigation && (\n <nav aria-label=\"Principal\" className=\"hidden min-w-0 flex-1 justify-center md:flex\">\n {navigation}\n </nav>\n )}\n\n <div className=\"flex shrink-0 items-center gap-2\">\n {rightContent}\n {userInitials && (\n <span\n aria-label={`Usuário: ${userInitials}`}\n className=\"inline-flex size-9 shrink-0 select-none items-center justify-center rounded-full bg-sbk-ciano text-[0.8125rem] font-semibold text-sbk-branco\"\n role=\"img\"\n >\n {userInitials}\n </span>\n )}\n </div>\n </header>\n );\n};\n\nHeader.displayName = 'Header';\n"],"names":["detectTheme","VARIANT_CLASS","inverseScope","Header","logoSrc","logoDarkSrc","logoAlt","logoVariant","title","subtitle","theme","navigation","onLogoClick","onMenuClick","menuExpanded","menuLabel","rightContent","showMenuIcon","sticky","userInitials","variant","className","resolvedTheme","setResolvedTheme","useState","useEffect","sync","observer","customLogo","brand","jsxs","Fragment","Logo","jsx","cn","buttonReset","focusRing","Menu"],"mappings":"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"}
1
+ {"version":3,"file":"Header.js","sources":["../../../src/components/Header/Header.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { useEffect, useState } from 'react';\r\nimport { Menu } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, focusRing, inverseScope } from '../../utils/styles';\r\nimport type { Theme } from '../../theme/ThemeProvider';\r\nimport { Logo, type LogoVariant } from '../Logo/Logo';\r\n\r\nexport type HeaderVariant = 'solid' | 'light' | 'glass';\r\n\r\nexport interface HeaderProps {\r\n className?: string;\r\n /** Texto alternativo da imagem de logo customizada. */\r\n logoAlt?: string;\r\n /** Imagem de logo para o tema escuro (substitui o SVG oficial). */\r\n logoDarkSrc?: string;\r\n /** Imagem de logo customizada (substitui o SVG oficial). */\r\n logoSrc?: string;\r\n /** Logo oficial usado quando não há `logoSrc`. Padrão: sbk. */\r\n logoVariant?: LogoVariant;\r\n /** Estado do menu lateral, anunciado no botão hamburger (aria-expanded). */\r\n menuExpanded?: boolean;\r\n /** Rótulo do botão hamburger. Padrão: \"Abrir menu\". */\r\n menuLabel?: string;\r\n /** Navegação principal, exibida ao centro. */\r\n navigation?: React.ReactNode;\r\n onLogoClick?: () => void;\r\n onMenuClick?: () => void;\r\n /** Conteúdo à direita (ações, seletor de tema, menu do usuário). */\r\n rightContent?: React.ReactNode;\r\n showMenuIcon?: boolean;\r\n /** Fixa o header no topo. Padrão: true. */\r\n sticky?: boolean;\r\n subtitle?: React.ReactNode;\r\n /** Tema para escolher entre logoSrc e logoDarkSrc sem depender do ThemeProvider. */\r\n theme?: Theme;\r\n title?: React.ReactNode;\r\n /** Iniciais do usuário exibidas no avatar (ex.: \"CF\"). */\r\n userInitials?: string;\r\n /** `solid`: verde escuro (padrão). `light`: superfície clara. `glass`: Liquid Glass. */\r\n variant?: HeaderVariant;\r\n}\r\n\r\nconst detectTheme = (): Theme =>\r\n typeof document !== 'undefined' && document.documentElement.getAttribute('data-theme') === 'dark'\r\n ? 'dark'\r\n : 'light';\r\n\r\nconst VARIANT_CLASS: Record<HeaderVariant, string> = {\r\n solid: inverseScope,\r\n light: 'border-b border-sbk-line bg-sbk-surface text-sbk-fg',\r\n glass: 'sbk-glass rounded-none border-x-0 border-t-0 text-sbk-fg',\r\n};\r\n\r\nexport const Header = ({\r\n logoSrc,\r\n logoDarkSrc,\r\n logoAlt = 'SBK',\r\n logoVariant = 'sbk',\r\n title,\r\n subtitle,\r\n theme,\r\n navigation,\r\n onLogoClick,\r\n onMenuClick,\r\n menuExpanded,\r\n menuLabel = 'Abrir menu',\r\n rightContent,\r\n showMenuIcon = true,\r\n sticky = true,\r\n userInitials,\r\n variant = 'solid',\r\n className,\r\n}: HeaderProps) => {\r\n const [resolvedTheme, setResolvedTheme] = useState<Theme>(() => theme ?? detectTheme());\r\n\r\n useEffect(() => {\r\n if (theme) {\r\n setResolvedTheme(theme);\r\n return;\r\n }\r\n if (!logoDarkSrc || typeof MutationObserver === 'undefined') return;\r\n const sync = () => setResolvedTheme(detectTheme());\r\n sync();\r\n const observer = new MutationObserver(sync);\r\n observer.observe(document.documentElement, {\r\n attributes: true,\r\n attributeFilter: ['data-theme'],\r\n });\r\n return () => observer.disconnect();\r\n }, [theme, logoDarkSrc]);\r\n\r\n const customLogo = resolvedTheme === 'dark' && logoDarkSrc ? logoDarkSrc : logoSrc;\r\n const brand = (\r\n <>\r\n {customLogo ? (\r\n <img alt={logoAlt} className=\"h-8 w-auto shrink-0 object-contain\" src={customLogo} />\r\n ) : (\r\n <Logo color={variant === 'solid' ? 'white' : 'auto'} height={28} variant={logoVariant} />\r\n )}\r\n {(title || subtitle) && (\r\n <span className=\"grid min-w-0 gap-px text-left\">\r\n {title && (\r\n <span className=\"truncate text-base font-semibold leading-tight text-sbk-fg-heading\">\r\n {title}\r\n </span>\r\n )}\r\n {subtitle && (\r\n <span className=\"truncate text-xs font-light leading-tight text-sbk-fg-muted\">\r\n {subtitle}\r\n </span>\r\n )}\r\n </span>\r\n )}\r\n </>\r\n );\r\n\r\n return (\r\n <header\r\n className={cn(\r\n 'z-[var(--sbk-z-sticky)] box-border flex h-16 w-full shrink-0 items-center justify-between gap-4 px-4 md:px-8',\r\n sticky && 'sticky top-0',\r\n VARIANT_CLASS[variant],\r\n className,\r\n )}\r\n >\r\n <div className=\"flex min-w-0 items-center gap-3\">\r\n {showMenuIcon && (\r\n <button\r\n aria-expanded={menuExpanded}\r\n aria-label={menuLabel}\r\n className={cn(\r\n buttonReset,\r\n 'inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-sbk-sm text-sbk-fg hover:bg-sbk-surface-hover',\r\n focusRing,\r\n )}\r\n onClick={onMenuClick}\r\n type=\"button\"\r\n >\r\n <Menu aria-hidden=\"true\" className=\"size-5\" />\r\n </button>\r\n )}\r\n {onLogoClick ? (\r\n <button\r\n className={cn(\r\n buttonReset,\r\n 'flex min-w-0 cursor-pointer items-center gap-3 rounded-sbk-xs',\r\n focusRing,\r\n )}\r\n onClick={onLogoClick}\r\n type=\"button\"\r\n >\r\n {brand}\r\n </button>\r\n ) : (\r\n <div className=\"flex min-w-0 items-center gap-3\">{brand}</div>\r\n )}\r\n </div>\r\n\r\n {navigation && (\r\n <nav aria-label=\"Principal\" className=\"hidden min-w-0 flex-1 justify-center md:flex\">\r\n {navigation}\r\n </nav>\r\n )}\r\n\r\n <div className=\"flex shrink-0 items-center gap-2\">\r\n {rightContent}\r\n {userInitials && (\r\n <span\r\n aria-label={`Usuário: ${userInitials}`}\r\n className=\"inline-flex size-9 shrink-0 select-none items-center justify-center rounded-full bg-sbk-ciano text-[0.8125rem] font-semibold text-sbk-branco\"\r\n role=\"img\"\r\n >\r\n {userInitials}\r\n </span>\r\n )}\r\n </div>\r\n </header>\r\n );\r\n};\r\n\r\nHeader.displayName = 'Header';\r\n"],"names":["detectTheme","VARIANT_CLASS","inverseScope","Header","logoSrc","logoDarkSrc","logoAlt","logoVariant","title","subtitle","theme","navigation","onLogoClick","onMenuClick","menuExpanded","menuLabel","rightContent","showMenuIcon","sticky","userInitials","variant","className","resolvedTheme","setResolvedTheme","useState","useEffect","sync","observer","customLogo","brand","jsxs","Fragment","Logo","jsx","cn","buttonReset","focusRing","Menu"],"mappings":";;;;;;AA2CA,MAAMA,IAAc,MAClB,OAAO,WAAa,OAAe,SAAS,gBAAgB,aAAa,YAAY,MAAM,SACvF,SACA,SAEAC,IAA+C;AAAA,EACnD,OAAOC;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT,GAEaC,IAAS,CAAC;AAAA,EACrB,SAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,aAAAC,IAAc;AAAA,EACd,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,YAAAC;AAAA,EACA,aAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,cAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,QAAAC,IAAS;AAAA,EACT,cAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,WAAAC;AACF,MAAmB;AACjB,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAAgB,MAAMd,KAASV,GAAa;AAEtF,EAAAyB,EAAU,MAAM;AACd,QAAIf,GAAO;AACT,MAAAa,EAAiBb,CAAK;AACtB;AAAA,IACF;AACA,QAAI,CAACL,KAAe,OAAO,mBAAqB,IAAa;AAC7D,UAAMqB,IAAO,MAAMH,EAAiBvB,GAAa;AACjD,IAAA0B,EAAA;AACA,UAAMC,IAAW,IAAI,iBAAiBD,CAAI;AAC1C,WAAAC,EAAS,QAAQ,SAAS,iBAAiB;AAAA,MACzC,YAAY;AAAA,MACZ,iBAAiB,CAAC,YAAY;AAAA,IAAA,CAC/B,GACM,MAAMA,EAAS,WAAA;AAAA,EACxB,GAAG,CAACjB,GAAOL,CAAW,CAAC;AAEvB,QAAMuB,IAAaN,MAAkB,UAAUjB,IAAcA,IAAcD,GACrEyB,IACJ,gBAAAC,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAH,sBACE,OAAA,EAAI,KAAKtB,GAAS,WAAU,sCAAqC,KAAKsB,EAAA,CAAY,sBAElFI,GAAA,EAAK,OAAOZ,MAAY,UAAU,UAAU,QAAQ,QAAQ,IAAI,SAASb,GAAa;AAAA,KAEvFC,KAASC,MACT,gBAAAqB,EAAC,QAAA,EAAK,WAAU,iCACb,UAAA;AAAA,MAAAtB,KACC,gBAAAyB,EAAC,QAAA,EAAK,WAAU,sEACb,UAAAzB,GACH;AAAA,MAEDC,KACC,gBAAAwB,EAAC,QAAA,EAAK,WAAU,+DACb,UAAAxB,EAAA,CACH;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GAEJ;AAGF,SACE,gBAAAqB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWI;AAAA,QACT;AAAA,QACAhB,KAAU;AAAA,QACVjB,EAAcmB,CAAO;AAAA,QACrBC;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,gBAAAS,EAAC,OAAA,EAAI,WAAU,mCACZ,UAAA;AAAA,UAAAb,KACC,gBAAAgB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,iBAAenB;AAAA,cACf,cAAYC;AAAA,cACZ,WAAWmB;AAAA,gBACTC;AAAA,gBACA;AAAA,gBACAC;AAAA,cAAA;AAAA,cAEF,SAASvB;AAAA,cACT,MAAK;AAAA,cAEL,UAAA,gBAAAoB,EAACI,GAAA,EAAK,eAAY,QAAO,WAAU,SAAA,CAAS;AAAA,YAAA;AAAA,UAAA;AAAA,UAG/CzB,IACC,gBAAAqB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWC;AAAA,gBACTC;AAAA,gBACA;AAAA,gBACAC;AAAA,cAAA;AAAA,cAEF,SAASxB;AAAA,cACT,MAAK;AAAA,cAEJ,UAAAiB;AAAA,YAAA;AAAA,UAAA,IAGH,gBAAAI,EAAC,OAAA,EAAI,WAAU,mCAAmC,UAAAJ,EAAA,CAAM;AAAA,QAAA,GAE5D;AAAA,QAEClB,KACC,gBAAAsB,EAAC,OAAA,EAAI,cAAW,aAAY,WAAU,gDACnC,UAAAtB,GACH;AAAA,QAGF,gBAAAmB,EAAC,OAAA,EAAI,WAAU,oCACZ,UAAA;AAAA,UAAAd;AAAA,UACAG,KACC,gBAAAc;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,cAAY,YAAYd,CAAY;AAAA,cACpC,WAAU;AAAA,cACV,MAAK;AAAA,cAEJ,UAAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACH,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEAhB,EAAO,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Highlight.js","sources":["../../../src/components/Highlight/Highlight.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface HighlightProps extends React.HTMLAttributes<HTMLElement> {\n /** Ciano Escuro (padrão) ou Verde Claro, conforme o brand book. */\n tone?: 'ciano' | 'verde';\n}\n\n/**\n * Highlight de palavra-chave do brand book: bloco retangular atrás de palavras\n * estruturantes, sempre com texto branco. Use em poucas palavras por tela.\n */\nexport const Highlight = ({ tone = 'ciano', className, ...props }: HighlightProps) => (\n <mark\n className={cn(\n 'rounded-sbk-xs px-1.5 py-0.5 font-semibold text-sbk-branco [box-decoration-break:clone]',\n tone === 'ciano' ? 'bg-sbk-ciano-escuro' : 'bg-sbk-verde-claro',\n className,\n )}\n {...props}\n />\n);\n\nHighlight.displayName = 'Highlight';\n"],"names":["Highlight","tone","className","props","jsx","cn"],"mappings":";;AAYO,MAAMA,IAAY,CAAC,EAAE,MAAAC,IAAO,SAAS,WAAAC,GAAW,GAAGC,QACxD,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAJ,MAAS,UAAU,wBAAwB;AAAA,MAC3CC;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN;AAGFH,EAAU,cAAc;"}
1
+ {"version":3,"file":"Highlight.js","sources":["../../../src/components/Highlight/Highlight.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport interface HighlightProps extends React.HTMLAttributes<HTMLElement> {\r\n /** Ciano Escuro (padrão) ou Verde Claro, conforme o brand book. */\r\n tone?: 'ciano' | 'verde';\r\n}\r\n\r\n/**\r\n * Highlight de palavra-chave do brand book: bloco retangular atrás de palavras\r\n * estruturantes, sempre com texto branco. Use em poucas palavras por tela.\r\n */\r\nexport const Highlight = ({ tone = 'ciano', className, ...props }: HighlightProps) => (\r\n <mark\r\n className={cn(\r\n 'rounded-sbk-xs px-1.5 py-0.5 font-semibold text-sbk-branco [box-decoration-break:clone]',\r\n tone === 'ciano' ? 'bg-sbk-ciano-escuro' : 'bg-sbk-verde-claro',\r\n className,\r\n )}\r\n {...props}\r\n />\r\n);\r\n\r\nHighlight.displayName = 'Highlight';\r\n"],"names":["Highlight","tone","className","props","jsx","cn"],"mappings":";;AAYO,MAAMA,IAAY,CAAC,EAAE,MAAAC,IAAO,SAAS,WAAAC,GAAW,GAAGC,QACxD,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAJ,MAAS,UAAU,wBAAwB;AAAA,MAC3CC;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN;AAGFH,EAAU,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.js","sources":["../../../src/components/Icon/Icon.tsx"],"sourcesContent":["import type { LucideIcon, LucideProps } from 'lucide-react';\nimport { cn } from '../../utils/cn';\n\nexport type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface IconProps extends Omit<LucideProps, 'size' | 'ref'> {\n /** Componente de ícone do lucide-react (ex.: `import { Search } from 'lucide-react'`). */\n icon: LucideIcon;\n /**\n * Texto para leitores de tela. Sem label o ícone é decorativo (`aria-hidden`).\n * Informe sempre que o ícone for o único conteúdo com significado.\n */\n label?: string;\n size?: IconSize | number;\n}\n\nconst SIZE_PX: Record<IconSize, number> = { xs: 12, sm: 16, md: 20, lg: 24, xl: 32 };\n\n/**\n * Wrapper padronizado para ícones lucide-react.\n * Ícones herdam a cor do texto (currentColor), o que mantém a paleta da marca.\n * Traço 1.75 acompanha o peso Leve da tipografia.\n */\nexport const Icon = ({\n icon: IconComponent,\n label,\n size = 'md',\n strokeWidth = 1.75,\n className,\n ...props\n}: IconProps) => {\n const px = typeof size === 'number' ? size : SIZE_PX[size];\n return (\n <IconComponent\n aria-hidden={label ? undefined : true}\n aria-label={label}\n className={cn('shrink-0', className)}\n focusable=\"false\"\n height={px}\n role={label ? 'img' : undefined}\n strokeWidth={strokeWidth}\n width={px}\n {...props}\n />\n );\n};\n\nIcon.displayName = 'Icon';\n"],"names":["SIZE_PX","Icon","IconComponent","label","size","strokeWidth","className","props","px","jsx","cn"],"mappings":";;AAgBA,MAAMA,IAAoC,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAA,GAOnEC,IAAO,CAAC;AAAA,EACnB,MAAMC;AAAA,EACN,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,aAAAC,IAAc;AAAA,EACd,WAAAC;AAAA,EACA,GAAGC;AACL,MAAiB;AACf,QAAMC,IAAK,OAAOJ,KAAS,WAAWA,IAAOJ,EAAQI,CAAI;AACzD,SACE,gBAAAK;AAAA,IAACP;AAAA,IAAA;AAAA,MACC,eAAaC,IAAQ,SAAY;AAAA,MACjC,cAAYA;AAAA,MACZ,WAAWO,EAAG,YAAYJ,CAAS;AAAA,MACnC,WAAU;AAAA,MACV,QAAQE;AAAA,MACR,MAAML,IAAQ,QAAQ;AAAA,MACtB,aAAAE;AAAA,MACA,OAAOG;AAAA,MACN,GAAGD;AAAA,IAAA;AAAA,EAAA;AAGV;AAEAN,EAAK,cAAc;"}
1
+ {"version":3,"file":"Icon.js","sources":["../../../src/components/Icon/Icon.tsx"],"sourcesContent":["import type { LucideIcon, LucideProps } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n\r\nexport interface IconProps extends Omit<LucideProps, 'size' | 'ref'> {\r\n /** Componente de ícone do lucide-react (ex.: `import { Search } from 'lucide-react'`). */\r\n icon: LucideIcon;\r\n /**\r\n * Texto para leitores de tela. Sem label o ícone é decorativo (`aria-hidden`).\r\n * Informe sempre que o ícone for o único conteúdo com significado.\r\n */\r\n label?: string;\r\n size?: IconSize | number;\r\n}\r\n\r\nconst SIZE_PX: Record<IconSize, number> = { xs: 12, sm: 16, md: 20, lg: 24, xl: 32 };\r\n\r\n/**\r\n * Wrapper padronizado para ícones lucide-react.\r\n * Ícones herdam a cor do texto (currentColor), o que mantém a paleta da marca.\r\n * Traço 1.75 acompanha o peso Leve da tipografia.\r\n */\r\nexport const Icon = ({\r\n icon: IconComponent,\r\n label,\r\n size = 'md',\r\n strokeWidth = 1.75,\r\n className,\r\n ...props\r\n}: IconProps) => {\r\n const px = typeof size === 'number' ? size : SIZE_PX[size];\r\n return (\r\n <IconComponent\r\n aria-hidden={label ? undefined : true}\r\n aria-label={label}\r\n className={cn('shrink-0', className)}\r\n focusable=\"false\"\r\n height={px}\r\n role={label ? 'img' : undefined}\r\n strokeWidth={strokeWidth}\r\n width={px}\r\n {...props}\r\n />\r\n );\r\n};\r\n\r\nIcon.displayName = 'Icon';\r\n"],"names":["SIZE_PX","Icon","IconComponent","label","size","strokeWidth","className","props","px","jsx","cn"],"mappings":";;AAgBA,MAAMA,IAAoC,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAA,GAOnEC,IAAO,CAAC;AAAA,EACnB,MAAMC;AAAA,EACN,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,aAAAC,IAAc;AAAA,EACd,WAAAC;AAAA,EACA,GAAGC;AACL,MAAiB;AACf,QAAMC,IAAK,OAAOJ,KAAS,WAAWA,IAAOJ,EAAQI,CAAI;AACzD,SACE,gBAAAK;AAAA,IAACP;AAAA,IAAA;AAAA,MACC,eAAaC,IAAQ,SAAY;AAAA,MACjC,cAAYA;AAAA,MACZ,WAAWO,EAAG,YAAYJ,CAAS;AAAA,MACnC,WAAU;AAAA,MACV,QAAQE;AAAA,MACR,MAAML,IAAQ,QAAQ;AAAA,MACtB,aAAAE;AAAA,MACA,OAAOG;AAAA,MACN,GAAGD;AAAA,IAAA;AAAA,EAAA;AAGV;AAEAN,EAAK,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.js","sources":["../../../src/components/IconButton/IconButton.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\n\nexport type IconButtonVariant = 'primary' | 'secondary' | 'ghost' | 'outline' | 'inverse' | 'glass';\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Nome acessível obrigatório: o botão não tem texto visível. */\n 'aria-label': string;\n children: React.ReactNode;\n shape?: 'square' | 'circle';\n size?: 'sm' | 'md' | 'lg';\n variant?: IconButtonVariant;\n}\n\nconst SIZE_CLASS = {\n sm: 'size-8 [&_svg]:size-4',\n md: 'size-10 [&_svg]:size-5',\n lg: 'size-12 [&_svg]:size-6',\n} as const;\n\nconst VARIANT_CLASS: Record<IconButtonVariant, 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 ghost: 'bg-transparent text-sbk-fg-muted hover:bg-sbk-surface-hover hover:text-sbk-fg',\n outline: 'border-sbk-line-strong bg-sbk-surface text-sbk-fg hover:bg-sbk-surface-hover',\n inverse: 'bg-transparent text-sbk-branco hover:bg-sbk-branco/10',\n glass: 'sbk-glass text-sbk-fg',\n};\n\n/** Botão quadrado ou circular apenas com ícone. */\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n (\n {\n children,\n shape = 'square',\n size = 'md',\n variant = 'ghost',\n className,\n type = 'button',\n ...props\n },\n ref,\n ) => (\n <button\n ref={ref}\n className={cn(\n buttonReset,\n 'inline-flex shrink-0 cursor-pointer items-center justify-center border border-transparent disabled:cursor-not-allowed disabled:opacity-50',\n shape === 'circle' ? 'rounded-full' : 'rounded-sbk-sm',\n transitionColors,\n focusRing,\n SIZE_CLASS[size],\n VARIANT_CLASS[variant],\n className,\n )}\n type={type}\n {...props}\n >\n {children}\n </button>\n ),\n);\n\nIconButton.displayName = 'IconButton';\n"],"names":["SIZE_CLASS","VARIANT_CLASS","IconButton","React","children","shape","size","variant","className","type","props","ref","jsx","cn","buttonReset","transitionColors","focusRing"],"mappings":";;;;AAeA,MAAMA,IAAa;AAAA,EACjB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAAmD;AAAA,EACvD,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT,GAGaC,IAAaC,EAAM;AAAA,EAC9B,CACE;AAAA,IACE,UAAAC;AAAA,IACA,OAAAC,IAAQ;AAAA,IACR,MAAAC,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,WAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,GAAGC;AAAA,EAAA,GAELC,MAEA,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,WAAWE;AAAA,QACTC;AAAA,QACA;AAAA,QACAT,MAAU,WAAW,iBAAiB;AAAA,QACtCU;AAAA,QACAC;AAAA,QACAhB,EAAWM,CAAI;AAAA,QACfL,EAAcM,CAAO;AAAA,QACrBC;AAAA,MAAA;AAAA,MAEF,MAAAC;AAAA,MACC,GAAGC;AAAA,MAEH,UAAAN;AAAA,IAAA;AAAA,EAAA;AAGP;AAEAF,EAAW,cAAc;"}
1
+ {"version":3,"file":"IconButton.js","sources":["../../../src/components/IconButton/IconButton.tsx"],"sourcesContent":["import React from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\r\n\r\nexport type IconButtonVariant = 'primary' | 'secondary' | 'ghost' | 'outline' | 'inverse' | 'glass';\r\n\r\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n /** Nome acessível obrigatório: o botão não tem texto visível. */\r\n 'aria-label': string;\r\n children: React.ReactNode;\r\n shape?: 'square' | 'circle';\r\n size?: 'sm' | 'md' | 'lg';\r\n variant?: IconButtonVariant;\r\n}\r\n\r\nconst SIZE_CLASS = {\r\n sm: 'size-8 [&_svg]:size-4',\r\n md: 'size-10 [&_svg]:size-5',\r\n lg: 'size-12 [&_svg]:size-6',\r\n} as const;\r\n\r\nconst VARIANT_CLASS: Record<IconButtonVariant, 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 ghost: 'bg-transparent text-sbk-fg-muted hover:bg-sbk-surface-hover hover:text-sbk-fg',\r\n outline: 'border-sbk-line-strong bg-sbk-surface text-sbk-fg hover:bg-sbk-surface-hover',\r\n inverse: 'bg-transparent text-sbk-branco hover:bg-sbk-branco/10',\r\n glass: 'sbk-glass text-sbk-fg',\r\n};\r\n\r\n/** Botão quadrado ou circular apenas com ícone. */\r\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\r\n (\r\n {\r\n children,\r\n shape = 'square',\r\n size = 'md',\r\n variant = 'ghost',\r\n className,\r\n type = 'button',\r\n ...props\r\n },\r\n ref,\r\n ) => (\r\n <button\r\n ref={ref}\r\n className={cn(\r\n buttonReset,\r\n 'inline-flex shrink-0 cursor-pointer items-center justify-center border border-transparent disabled:cursor-not-allowed disabled:opacity-50',\r\n shape === 'circle' ? 'rounded-full' : 'rounded-sbk-sm',\r\n transitionColors,\r\n focusRing,\r\n SIZE_CLASS[size],\r\n VARIANT_CLASS[variant],\r\n className,\r\n )}\r\n type={type}\r\n {...props}\r\n >\r\n {children}\r\n </button>\r\n ),\r\n);\r\n\r\nIconButton.displayName = 'IconButton';\r\n"],"names":["SIZE_CLASS","VARIANT_CLASS","IconButton","React","children","shape","size","variant","className","type","props","ref","jsx","cn","buttonReset","transitionColors","focusRing"],"mappings":";;;;AAeA,MAAMA,IAAa;AAAA,EACjB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAAmD;AAAA,EACvD,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT,GAGaC,IAAaC,EAAM;AAAA,EAC9B,CACE;AAAA,IACE,UAAAC;AAAA,IACA,OAAAC,IAAQ;AAAA,IACR,MAAAC,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,WAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,GAAGC;AAAA,EAAA,GAELC,MAEA,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,WAAWE;AAAA,QACTC;AAAA,QACA;AAAA,QACAT,MAAU,WAAW,iBAAiB;AAAA,QACtCU;AAAA,QACAC;AAAA,QACAhB,EAAWM,CAAI;AAAA,QACfL,EAAcM,CAAO;AAAA,QACrBC;AAAA,MAAA;AAAA,MAEF,MAAAC;AAAA,MACC,GAAGC;AAAA,MAEH,UAAAN;AAAA,IAAA;AAAA,EAAA;AAGP;AAEAF,EAAW,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useId } from 'react';\nimport { cn } from '../../utils/cn';\nimport { describedBy, fieldControl, fieldSize, type FieldSize } from '../../utils/styles';\nimport { Field } from '../Field/Field';\n\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n error?: string;\n fullWidth?: boolean;\n helperText?: string;\n label?: React.ReactNode;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n size?: FieldSize;\n}\n\nconst iconSlot =\n 'pointer-events-none absolute z-[1] flex items-center text-sbk-fg-muted group-focus-within:text-sbk-primary [&_svg]:size-[1.125rem]';\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n label,\n error,\n helperText,\n leftIcon,\n rightIcon,\n fullWidth = false,\n size = 'md',\n className,\n id,\n required,\n ...props\n },\n ref,\n ) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n\n return (\n <Field\n className={cn(fullWidth && 'w-full')}\n error={error}\n helperText={helperText}\n id={inputId}\n label={label}\n required={required}\n >\n <div className=\"group relative flex w-full items-center\">\n {leftIcon && <span className={cn(iconSlot, 'left-3')}>{leftIcon}</span>}\n <input\n ref={ref}\n aria-describedby={describedBy(inputId, error, helperText)}\n aria-invalid={error ? true : undefined}\n className={cn(\n fieldControl,\n fieldSize[size],\n leftIcon && 'pl-10',\n rightIcon && 'pr-10',\n className,\n )}\n id={inputId}\n required={required}\n {...props}\n />\n {rightIcon && <span className={cn(iconSlot, 'right-3')}>{rightIcon}</span>}\n </div>\n </Field>\n );\n },\n);\n\nInput.displayName = 'Input';\n"],"names":["iconSlot","Input","React","label","error","helperText","leftIcon","rightIcon","fullWidth","size","className","id","required","props","ref","autoId","useId","inputId","jsx","Field","cn","jsxs","describedBy","fieldControl","fieldSize"],"mappings":";;;;;AAeA,MAAMA,IACJ,sIAEWC,IAAQC,EAAM;AAAA,EACzB,CACE;AAAA,IACE,OAAAC;AAAA,IACA,OAAAC;AAAA,IACA,YAAAC;AAAA,IACA,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,WAAAC,IAAY;AAAA,IACZ,MAAAC,IAAO;AAAA,IACP,WAAAC;AAAA,IACA,IAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAASC,EAAA,GACTC,IAAUN,KAAMI;AAEtB,WACE,gBAAAG;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAWC,EAAGZ,KAAa,QAAQ;AAAA,QACnC,OAAAJ;AAAA,QACA,YAAAC;AAAA,QACA,IAAIY;AAAA,QACJ,OAAAd;AAAA,QACA,UAAAS;AAAA,QAEA,UAAA,gBAAAS,EAAC,OAAA,EAAI,WAAU,2CACZ,UAAA;AAAA,UAAAf,uBAAa,QAAA,EAAK,WAAWc,EAAGpB,GAAU,QAAQ,GAAI,UAAAM,GAAS;AAAA,UAChE,gBAAAY;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAAJ;AAAA,cACA,oBAAkBQ,EAAYL,GAASb,GAAOC,CAAU;AAAA,cACxD,gBAAcD,IAAQ,KAAO;AAAA,cAC7B,WAAWgB;AAAA,gBACTG;AAAA,gBACAC,EAAUf,CAAI;AAAA,gBACdH,KAAY;AAAA,gBACZC,KAAa;AAAA,gBACbG;AAAA,cAAA;AAAA,cAEF,IAAIO;AAAA,cACJ,UAAAL;AAAA,cACC,GAAGC;AAAA,YAAA;AAAA,UAAA;AAAA,UAELN,uBAAc,QAAA,EAAK,WAAWa,EAAGpB,GAAU,SAAS,GAAI,UAAAO,EAAA,CAAU;AAAA,QAAA,EAAA,CACrE;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEAN,EAAM,cAAc;"}
1
+ {"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useId } from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { describedBy, fieldControl, fieldSize, type FieldSize } from '../../utils/styles';\r\nimport { Field } from '../Field/Field';\r\n\r\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\r\n error?: string;\r\n fullWidth?: boolean;\r\n helperText?: string;\r\n label?: React.ReactNode;\r\n leftIcon?: React.ReactNode;\r\n rightIcon?: React.ReactNode;\r\n size?: FieldSize;\r\n}\r\n\r\nconst iconSlot =\r\n 'pointer-events-none absolute z-[1] flex items-center text-sbk-fg-muted group-focus-within:text-sbk-primary [&_svg]:size-[1.125rem]';\r\n\r\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\r\n (\r\n {\r\n label,\r\n error,\r\n helperText,\r\n leftIcon,\r\n rightIcon,\r\n fullWidth = false,\r\n size = 'md',\r\n className,\r\n id,\r\n required,\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const autoId = useId();\r\n const inputId = id ?? autoId;\r\n\r\n return (\r\n <Field\r\n className={cn(fullWidth && 'w-full')}\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 className=\"group relative flex w-full items-center\">\r\n {leftIcon && <span className={cn(iconSlot, 'left-3')}>{leftIcon}</span>}\r\n <input\r\n ref={ref}\r\n aria-describedby={describedBy(inputId, error, helperText)}\r\n aria-invalid={error ? true : undefined}\r\n className={cn(\r\n fieldControl,\r\n fieldSize[size],\r\n leftIcon && 'pl-10',\r\n rightIcon && 'pr-10',\r\n className,\r\n )}\r\n id={inputId}\r\n required={required}\r\n {...props}\r\n />\r\n {rightIcon && <span className={cn(iconSlot, 'right-3')}>{rightIcon}</span>}\r\n </div>\r\n </Field>\r\n );\r\n },\r\n);\r\n\r\nInput.displayName = 'Input';\r\n"],"names":["iconSlot","Input","React","label","error","helperText","leftIcon","rightIcon","fullWidth","size","className","id","required","props","ref","autoId","useId","inputId","jsx","Field","cn","jsxs","describedBy","fieldControl","fieldSize"],"mappings":";;;;;AAeA,MAAMA,IACJ,sIAEWC,IAAQC,EAAM;AAAA,EACzB,CACE;AAAA,IACE,OAAAC;AAAA,IACA,OAAAC;AAAA,IACA,YAAAC;AAAA,IACA,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,WAAAC,IAAY;AAAA,IACZ,MAAAC,IAAO;AAAA,IACP,WAAAC;AAAA,IACA,IAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAASC,EAAA,GACTC,IAAUN,KAAMI;AAEtB,WACE,gBAAAG;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAWC,EAAGZ,KAAa,QAAQ;AAAA,QACnC,OAAAJ;AAAA,QACA,YAAAC;AAAA,QACA,IAAIY;AAAA,QACJ,OAAAd;AAAA,QACA,UAAAS;AAAA,QAEA,UAAA,gBAAAS,EAAC,OAAA,EAAI,WAAU,2CACZ,UAAA;AAAA,UAAAf,uBAAa,QAAA,EAAK,WAAWc,EAAGpB,GAAU,QAAQ,GAAI,UAAAM,GAAS;AAAA,UAChE,gBAAAY;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAAJ;AAAA,cACA,oBAAkBQ,EAAYL,GAASb,GAAOC,CAAU;AAAA,cACxD,gBAAcD,IAAQ,KAAO;AAAA,cAC7B,WAAWgB;AAAA,gBACTG;AAAA,gBACAC,EAAUf,CAAI;AAAA,gBACdH,KAAY;AAAA,gBACZC,KAAa;AAAA,gBACbG;AAAA,cAAA;AAAA,cAEF,IAAIO;AAAA,cACJ,UAAAL;AAAA,cACC,GAAGC;AAAA,YAAA;AAAA,UAAA;AAAA,UAELN,uBAAc,QAAA,EAAK,WAAWa,EAAGpB,GAAU,SAAS,GAAI,UAAAO,EAAA,CAAU;AAAA,QAAA,EAAA,CACrE;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEAN,EAAM,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Layout.js","sources":["../../../src/components/Layout/Layout.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n}\n\nexport const Container: React.FC<ContainerProps> = ({ size = 'lg', className, ...props }) => {\n const sizeClass = {\n sm: 'max-w-2xl',\n md: 'max-w-4xl',\n lg: 'max-w-6xl',\n xl: 'max-w-7xl',\n full: 'max-w-none',\n }[size];\n return <div className={cn('mx-auto w-full px-4', sizeClass, className)} {...props} />;\n};\n\nexport interface StackProps extends React.HTMLAttributes<HTMLDivElement> {\n gap?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n}\n\nexport const Stack: React.FC<StackProps> = ({ gap = 'md', className, ...props }) => {\n const gapClass = {\n xs: 'gap-1',\n sm: 'gap-2',\n md: 'gap-3',\n lg: 'gap-4',\n xl: 'gap-6',\n }[gap];\n return <div className={cn('flex flex-col', gapClass, className)} {...props} />;\n};\n\nexport interface GridProps extends React.HTMLAttributes<HTMLDivElement> {\n cols?: 1 | 2 | 3 | 4;\n gap?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n /** Empilha colunas em telas pequenas. Padrão: true. */\n responsive?: boolean;\n}\n\nexport const Grid: React.FC<GridProps> = ({\n cols = 2,\n gap = 'md',\n responsive = true,\n className,\n ...props\n}) => {\n const colsClass = {\n 1: 'grid-cols-1',\n 2: responsive ? 'grid-cols-1 sm:grid-cols-2' : 'grid-cols-2',\n 3: responsive ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3' : 'grid-cols-3',\n 4: responsive ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4' : 'grid-cols-4',\n }[cols];\n const gapClass = {\n xs: 'gap-1',\n sm: 'gap-2',\n md: 'gap-3',\n lg: 'gap-4',\n xl: 'gap-6',\n }[gap];\n return <div className={cn('grid', colsClass, gapClass, className)} {...props} />;\n};\n"],"names":["Container","size","className","props","sizeClass","jsx","cn","Stack","gap","gapClass","Grid","cols","responsive","colsClass"],"mappings":";;AAOO,MAAMA,IAAsC,CAAC,EAAE,MAAAC,IAAO,MAAM,WAAAC,GAAW,GAAGC,QAAY;AAC3F,QAAMC,IAAY;AAAA,IAChB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,EAAA,EACNH,CAAI;AACN,SAAO,gBAAAI,EAAC,SAAI,WAAWC,EAAG,uBAAuBF,GAAWF,CAAS,GAAI,GAAGC,GAAO;AACrF,GAMaI,IAA8B,CAAC,EAAE,KAAAC,IAAM,MAAM,WAAAN,GAAW,GAAGC,QAAY;AAClF,QAAMM,IAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,EACJD,CAAG;AACL,SAAO,gBAAAH,EAAC,SAAI,WAAWC,EAAG,iBAAiBG,GAAUP,CAAS,GAAI,GAAGC,GAAO;AAC9E,GASaO,IAA4B,CAAC;AAAA,EACxC,MAAAC,IAAO;AAAA,EACP,KAAAH,IAAM;AAAA,EACN,YAAAI,IAAa;AAAA,EACb,WAAAV;AAAA,EACA,GAAGC;AACL,MAAM;AACJ,QAAMU,IAAY;AAAA,IAChB,GAAG;AAAA,IACH,GAAGD,IAAa,+BAA+B;AAAA,IAC/C,GAAGA,IAAa,8CAA8C;AAAA,IAC9D,GAAGA,IAAa,8CAA8C;AAAA,EAAA,EAC9DD,CAAI,GACAF,IAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,EACJD,CAAG;AACL,SAAO,gBAAAH,EAAC,OAAA,EAAI,WAAWC,EAAG,QAAQO,GAAWJ,GAAUP,CAAS,GAAI,GAAGC,EAAA,CAAO;AAChF;"}
1
+ {"version":3,"file":"Layout.js","sources":["../../../src/components/Layout/Layout.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\r\n}\r\n\r\nexport const Container: React.FC<ContainerProps> = ({ size = 'lg', className, ...props }) => {\r\n const sizeClass = {\r\n sm: 'max-w-2xl',\r\n md: 'max-w-4xl',\r\n lg: 'max-w-6xl',\r\n xl: 'max-w-7xl',\r\n full: 'max-w-none',\r\n }[size];\r\n return <div className={cn('mx-auto w-full px-4', sizeClass, className)} {...props} />;\r\n};\r\n\r\nexport interface StackProps extends React.HTMLAttributes<HTMLDivElement> {\r\n gap?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n}\r\n\r\nexport const Stack: React.FC<StackProps> = ({ gap = 'md', className, ...props }) => {\r\n const gapClass = {\r\n xs: 'gap-1',\r\n sm: 'gap-2',\r\n md: 'gap-3',\r\n lg: 'gap-4',\r\n xl: 'gap-6',\r\n }[gap];\r\n return <div className={cn('flex flex-col', gapClass, className)} {...props} />;\r\n};\r\n\r\nexport interface GridProps extends React.HTMLAttributes<HTMLDivElement> {\r\n cols?: 1 | 2 | 3 | 4;\r\n gap?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n /** Empilha colunas em telas pequenas. Padrão: true. */\r\n responsive?: boolean;\r\n}\r\n\r\nexport const Grid: React.FC<GridProps> = ({\r\n cols = 2,\r\n gap = 'md',\r\n responsive = true,\r\n className,\r\n ...props\r\n}) => {\r\n const colsClass = {\r\n 1: 'grid-cols-1',\r\n 2: responsive ? 'grid-cols-1 sm:grid-cols-2' : 'grid-cols-2',\r\n 3: responsive ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3' : 'grid-cols-3',\r\n 4: responsive ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4' : 'grid-cols-4',\r\n }[cols];\r\n const gapClass = {\r\n xs: 'gap-1',\r\n sm: 'gap-2',\r\n md: 'gap-3',\r\n lg: 'gap-4',\r\n xl: 'gap-6',\r\n }[gap];\r\n return <div className={cn('grid', colsClass, gapClass, className)} {...props} />;\r\n};\r\n"],"names":["Container","size","className","props","sizeClass","jsx","cn","Stack","gap","gapClass","Grid","cols","responsive","colsClass"],"mappings":";;AAOO,MAAMA,IAAsC,CAAC,EAAE,MAAAC,IAAO,MAAM,WAAAC,GAAW,GAAGC,QAAY;AAC3F,QAAMC,IAAY;AAAA,IAChB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,EAAA,EACNH,CAAI;AACN,SAAO,gBAAAI,EAAC,SAAI,WAAWC,EAAG,uBAAuBF,GAAWF,CAAS,GAAI,GAAGC,GAAO;AACrF,GAMaI,IAA8B,CAAC,EAAE,KAAAC,IAAM,MAAM,WAAAN,GAAW,GAAGC,QAAY;AAClF,QAAMM,IAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,EACJD,CAAG;AACL,SAAO,gBAAAH,EAAC,SAAI,WAAWC,EAAG,iBAAiBG,GAAUP,CAAS,GAAI,GAAGC,GAAO;AAC9E,GASaO,IAA4B,CAAC;AAAA,EACxC,MAAAC,IAAO;AAAA,EACP,KAAAH,IAAM;AAAA,EACN,YAAAI,IAAa;AAAA,EACb,WAAAV;AAAA,EACA,GAAGC;AACL,MAAM;AACJ,QAAMU,IAAY;AAAA,IAChB,GAAG;AAAA,IACH,GAAGD,IAAa,+BAA+B;AAAA,IAC/C,GAAGA,IAAa,8CAA8C;AAAA,IAC9D,GAAGA,IAAa,8CAA8C;AAAA,EAAA,EAC9DD,CAAI,GACAF,IAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,EACJD,CAAG;AACL,SAAO,gBAAAH,EAAC,OAAA,EAAI,WAAWC,EAAG,QAAQO,GAAWJ,GAAUP,CAAS,GAAI,GAAGC,EAAA,CAAO;AAChF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Logo.js","sources":["../../../src/components/Logo/Logo.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport type LogoVariant = 'sbk' | 'sbk-ia';\n/**\n * - `auto`: cor de título do tema atual (verde escuro no claro, branco no escuro)\n * - `dark`: Verde Escuro, para fundos claros\n * - `white`: para fundos escuros\n * - `black`: monocromática\n */\nexport type LogoColor = 'auto' | 'dark' | 'white' | 'black';\n\nexport interface LogoProps extends Omit<React.SVGAttributes<SVGSVGElement>, 'color'> {\n /** Reserva a zona de respiro do brand book (espaço livre igual à altura do símbolo). */\n clearSpace?: boolean;\n color?: LogoColor;\n /** Altura em px. A largura acompanha a proporção oficial. */\n height?: number;\n /** Nome acessível. Padrão: \"SBK\" ou \"SBK IA\". */\n title?: string;\n variant?: LogoVariant;\n}\n\nconst COLOR_CLASS: Record<LogoColor, string> = {\n auto: 'text-sbk-fg-heading',\n dark: 'text-sbk-verde-escuro',\n white: 'text-sbk-branco',\n black: 'text-sbk-preto',\n};\n\n/** Cor do recorte do wordmark dentro do bloco da SBK IA. */\nconst KNOCKOUT: Record<LogoColor, string> = {\n auto: 'var(--sbk-color-surface)',\n dark: 'var(--sbk-branco)',\n white: 'var(--sbk-preto)',\n black: 'var(--sbk-branco)',\n};\n\nconst SBK_VIEWBOX = { x: 39.15, y: 180.84, w: 541.7, h: 258.08 };\nconst SBK_IA_VIEWBOX = { x: 48.06, y: 293.2, w: 405.56, h: 128.33 };\n\n/** Paths oficiais: ui/docs/SBK_logo_2026.svg */\nconst SbkMark = () => (\n <g fill=\"currentColor\" transform=\"translate(-49, 122)\">\n <g stroke=\"currentColor\" strokeMiterlimit={10} strokeWidth={2}>\n <path d=\"m225.13 266.26c-27.48 0-47.67-12.07-50.38-41.01h14.16c0.62 21.44 17.69 29.56 36.85 29.56 18.11 0 39.14-7.91 39.14-29.14 0-16.24-13.12-23.74-32.48-29.99l-11.03-3.53c-24.36-7.71-42.27-16.66-42.27-40.19 0-28.1 24.78-39.97 49.76-39.97 22.9 0 46.64 8.54 47.05 35.18h-13.95c-1.87-18.32-15.82-23.94-32.47-23.94-17.29 0-36.65 7.71-36.65 27.69 0 14.78 11.04 22.28 34.36 29.77l12.49 3.96c24.36 7.7 38.3 15.82 38.93 38.73 0 30.18-26.65 42.88-53.51 42.88z\" />\n <path\n d=\"m351.42 264.39h-41.43v-150.53h41.43c8.53 0 17.9-0.2 26.23 2.09 16.24 4.58 27.48 17.9 27.48 35.18 0 18.74-10.41 29.98-27.9 34.56 20.82 2.71 34.15 15.2 34.15 36.85 0 34.56-31.86 41.85-59.96 41.85zm8.12-138.45h-36.02v56.49h32.06c19.16 0 34.98-8.81 34.98-30.26 0-18.74-14.16-26.23-31.02-26.23zm-1.46 63.19h-34.56v63.18h26.65c21.86 0 46.84-1.45 46.84-29.98 0-24.77-18.11-33.2-38.93-33.2z\"\n fillRule=\"evenodd\"\n />\n <path d=\"m443.77 264.39v-150.53h13.53v150.53zm88.07 0l-73.7-81.61 67.03-68.92h18.12l-68.91 67.88 75.99 82.65z\" />\n </g>\n <path d=\"m99.09 118.17l-0.21 57.98-9.73 0.24 0.56-62.81c0.26-29.03 26.91-53.16 56.3-53.26l151.74-0.48c0.62 3.58 0.63 6.35 0.05 9.92l-150.35 0.22c-26.28 0.04-48.26 21.9-48.36 48.19z\" />\n <path d=\"m419.9 315.79l0.22-9.33 149.3-0.15c25.73-0.02 48.97-20.27 49.14-45.96l0.4-60.49q4.64-0.28 9.57-0.07l0.32 52.61c0.21 33.16-23.62 63.29-57.93 63.33l-135.88 0.19z\" />\n </g>\n);\n\n/** Paths oficiais: ui/docs/SBK_IA_logo_2026.svg (glyphs \"IA\" expandidos para evitar ids globais) */\nconst SbkIaMark = ({ knockout }: { knockout: string }) => (\n <g>\n <path\n d=\"M 0.00165 -0.00185625 L -341.502256 -0.00185625 C -357.81085 -0.00185625 -371.033506 13.2208 -371.033506 29.529394 L -371.033506 93.802831 C -371.033506 110.115331 -357.81085 123.334081 -341.502256 123.334081 L 0.00165 123.334081 C 16.310244 123.334081 29.5329 110.115331 29.5329 93.802831 L 29.5329 29.529394 C 29.5329 13.2208 16.310244 -0.00185625 0.00165 -0.00185625 Z\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeMiterlimit={10}\n strokeWidth={5}\n transform=\"matrix(1, 0, 0, -1, 421.5921, 419.0333)\"\n />\n <path\n d=\"M 280.578125 419.230469 L 80.089844 419.230469 C 63.78125 419.230469 50.558594 406.011719 50.558594 389.699219 L 50.558594 325.425781 C 50.558594 309.117188 63.78125 295.898438 80.089844 295.898438 L 280.578125 295.898438 C 296.886719 295.898438 310.109375 309.117188 310.109375 325.425781 L 310.109375 389.699219 C 310.109375 406.011719 296.886719 419.230469 280.578125 419.230469\"\n fill=\"currentColor\"\n />\n <g fill=\"currentColor\">\n <path\n d=\"M 17.8125 0 L 17.8125 -75.75 L 11 -75.75 L 11 0 Z\"\n transform=\"translate(327.5737, 394.627)\"\n />\n <path\n d=\"M 71.453125 0 L 39.28125 -75.75 L 32.0625 -75.75 L 1.15625 0 L 8.375 0 L 16.546875 -21.15625 L 54.890625 -21.15625 L 63.484375 0 Z M 52.484375 -26.8125 L 18.75 -26.8125 L 35.203125 -69.140625 Z\"\n transform=\"translate(356.385092, 394.627)\"\n />\n </g>\n <g fill={knockout} stroke={knockout} strokeMiterlimit={10}>\n <path d=\"M 114.230469 396.132812 C 100.488281 396.132812 90.390625 390.09375 89.039062 375.625 L 96.117188 375.625 C 96.429688 386.347656 104.964844 390.40625 114.542969 390.40625 C 123.597656 390.40625 134.113281 386.453125 134.113281 375.832031 C 134.113281 367.714844 127.554688 363.964844 117.871094 360.84375 L 112.355469 359.074219 C 100.175781 355.222656 91.222656 350.746094 91.222656 338.980469 C 91.222656 324.929688 103.613281 318.996094 116.105469 318.996094 C 127.554688 318.996094 139.421875 323.261719 139.628906 336.589844 L 132.65625 336.589844 C 131.71875 327.429688 124.742188 324.617188 116.414062 324.617188 C 107.777344 324.617188 98.09375 328.46875 98.09375 338.460938 C 98.09375 345.851562 103.613281 349.601562 115.269531 353.347656 L 121.515625 355.328125 C 133.695312 359.175781 140.671875 363.238281 140.984375 374.6875 C 140.984375 389.78125 127.660156 396.132812 114.230469 396.132812\" />\n <path d=\"M 180.703125 357.5625 L 163.421875 357.5625 L 163.421875 389.15625 L 176.746094 389.15625 C 187.679688 389.15625 200.167969 388.429688 200.167969 374.167969 C 200.167969 361.78125 191.113281 357.5625 180.703125 357.5625 M 181.433594 325.96875 L 163.421875 325.96875 L 163.421875 354.214844 L 179.453125 354.214844 C 189.03125 354.214844 196.941406 349.808594 196.941406 339.085938 C 196.941406 329.71875 189.863281 325.96875 181.433594 325.96875 M 177.371094 395.195312 L 156.65625 395.195312 L 156.65625 319.933594 L 177.371094 319.933594 C 181.640625 319.933594 186.324219 319.828125 190.488281 320.972656 C 198.609375 323.265625 204.230469 329.925781 204.230469 338.566406 C 204.230469 347.933594 199.023438 353.554688 190.28125 355.847656 C 200.691406 357.199219 207.351562 363.445312 207.351562 374.273438 C 207.351562 391.550781 191.425781 395.195312 177.371094 395.195312\" />\n <path\n d=\"M 0.00183125 0.0001875 L -36.849731 40.804875 L -3.3302 75.261906 L 5.724488 75.261906 L -28.732544 41.328312 L 9.26355 0.0001875 Z M -44.033325 75.261906 L -37.2677 75.261906 L -37.2677 0.0001875 L -44.033325 0.0001875 Z\"\n transform=\"matrix(1, 0, 0, -1, 267.5802, 395.1955)\"\n />\n </g>\n </g>\n);\n\n/**\n * Logo oficial SBK / SBK IA a partir dos SVGs do time de marca.\n * Não aplica sombras, gradientes, distorção ou rotação (usos indevidos do brand book).\n */\nexport const Logo = ({\n variant = 'sbk',\n color = 'auto',\n height = 32,\n clearSpace = false,\n title,\n className,\n style,\n ...props\n}: LogoProps) => {\n const box = variant === 'sbk' ? SBK_VIEWBOX : SBK_IA_VIEWBOX;\n const width = Math.round((height * box.w) / box.h);\n const accessibleName = title ?? (variant === 'sbk' ? 'SBK' : 'SBK IA');\n\n return (\n <svg\n aria-label={accessibleName}\n className={cn('inline-block shrink-0', COLOR_CLASS[color], className)}\n height={height}\n role=\"img\"\n style={{ ...(clearSpace ? { padding: height, boxSizing: 'content-box' } : null), ...style }}\n viewBox={`${box.x} ${box.y} ${box.w} ${box.h}`}\n width={width}\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <title>{accessibleName}</title>\n {variant === 'sbk' ? <SbkMark /> : <SbkIaMark knockout={KNOCKOUT[color]} />}\n </svg>\n );\n};\n\nLogo.displayName = 'Logo';\n"],"names":["COLOR_CLASS","KNOCKOUT","SBK_VIEWBOX","SBK_IA_VIEWBOX","SbkMark","jsxs","jsx","SbkIaMark","knockout","Logo","variant","color","height","clearSpace","title","className","style","props","box","width","accessibleName","cn"],"mappings":"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"}
1
+ {"version":3,"file":"Logo.js","sources":["../../../src/components/Logo/Logo.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport type LogoVariant = 'sbk' | 'sbk-ia';\r\n/**\r\n * - `auto`: cor de título do tema atual (verde escuro no claro, branco no escuro)\r\n * - `dark`: Verde Escuro, para fundos claros\r\n * - `white`: para fundos escuros\r\n * - `black`: monocromática\r\n */\r\nexport type LogoColor = 'auto' | 'dark' | 'white' | 'black';\r\n\r\nexport interface LogoProps extends Omit<React.SVGAttributes<SVGSVGElement>, 'color'> {\r\n /** Reserva a zona de respiro do brand book (espaço livre igual à altura do símbolo). */\r\n clearSpace?: boolean;\r\n color?: LogoColor;\r\n /** Altura em px. A largura acompanha a proporção oficial. */\r\n height?: number;\r\n /** Nome acessível. Padrão: \"SBK\" ou \"SBK IA\". */\r\n title?: string;\r\n variant?: LogoVariant;\r\n}\r\n\r\nconst COLOR_CLASS: Record<LogoColor, string> = {\r\n auto: 'text-sbk-fg-heading',\r\n dark: 'text-sbk-verde-escuro',\r\n white: 'text-sbk-branco',\r\n black: 'text-sbk-preto',\r\n};\r\n\r\n/** Cor do recorte do wordmark dentro do bloco da SBK IA. */\r\nconst KNOCKOUT: Record<LogoColor, string> = {\r\n auto: 'var(--sbk-color-surface)',\r\n dark: 'var(--sbk-branco)',\r\n white: 'var(--sbk-preto)',\r\n black: 'var(--sbk-branco)',\r\n};\r\n\r\nconst SBK_VIEWBOX = { x: 39.15, y: 180.84, w: 541.7, h: 258.08 };\r\nconst SBK_IA_VIEWBOX = { x: 48.06, y: 293.2, w: 405.56, h: 128.33 };\r\n\r\n/** Paths oficiais: ui/docs/SBK_logo_2026.svg */\r\nconst SbkMark = () => (\r\n <g fill=\"currentColor\" transform=\"translate(-49, 122)\">\r\n <g stroke=\"currentColor\" strokeMiterlimit={10} strokeWidth={2}>\r\n <path d=\"m225.13 266.26c-27.48 0-47.67-12.07-50.38-41.01h14.16c0.62 21.44 17.69 29.56 36.85 29.56 18.11 0 39.14-7.91 39.14-29.14 0-16.24-13.12-23.74-32.48-29.99l-11.03-3.53c-24.36-7.71-42.27-16.66-42.27-40.19 0-28.1 24.78-39.97 49.76-39.97 22.9 0 46.64 8.54 47.05 35.18h-13.95c-1.87-18.32-15.82-23.94-32.47-23.94-17.29 0-36.65 7.71-36.65 27.69 0 14.78 11.04 22.28 34.36 29.77l12.49 3.96c24.36 7.7 38.3 15.82 38.93 38.73 0 30.18-26.65 42.88-53.51 42.88z\" />\r\n <path\r\n d=\"m351.42 264.39h-41.43v-150.53h41.43c8.53 0 17.9-0.2 26.23 2.09 16.24 4.58 27.48 17.9 27.48 35.18 0 18.74-10.41 29.98-27.9 34.56 20.82 2.71 34.15 15.2 34.15 36.85 0 34.56-31.86 41.85-59.96 41.85zm8.12-138.45h-36.02v56.49h32.06c19.16 0 34.98-8.81 34.98-30.26 0-18.74-14.16-26.23-31.02-26.23zm-1.46 63.19h-34.56v63.18h26.65c21.86 0 46.84-1.45 46.84-29.98 0-24.77-18.11-33.2-38.93-33.2z\"\r\n fillRule=\"evenodd\"\r\n />\r\n <path d=\"m443.77 264.39v-150.53h13.53v150.53zm88.07 0l-73.7-81.61 67.03-68.92h18.12l-68.91 67.88 75.99 82.65z\" />\r\n </g>\r\n <path d=\"m99.09 118.17l-0.21 57.98-9.73 0.24 0.56-62.81c0.26-29.03 26.91-53.16 56.3-53.26l151.74-0.48c0.62 3.58 0.63 6.35 0.05 9.92l-150.35 0.22c-26.28 0.04-48.26 21.9-48.36 48.19z\" />\r\n <path d=\"m419.9 315.79l0.22-9.33 149.3-0.15c25.73-0.02 48.97-20.27 49.14-45.96l0.4-60.49q4.64-0.28 9.57-0.07l0.32 52.61c0.21 33.16-23.62 63.29-57.93 63.33l-135.88 0.19z\" />\r\n </g>\r\n);\r\n\r\n/** Paths oficiais: ui/docs/SBK_IA_logo_2026.svg (glyphs \"IA\" expandidos para evitar ids globais) */\r\nconst SbkIaMark = ({ knockout }: { knockout: string }) => (\r\n <g>\r\n <path\r\n d=\"M 0.00165 -0.00185625 L -341.502256 -0.00185625 C -357.81085 -0.00185625 -371.033506 13.2208 -371.033506 29.529394 L -371.033506 93.802831 C -371.033506 110.115331 -357.81085 123.334081 -341.502256 123.334081 L 0.00165 123.334081 C 16.310244 123.334081 29.5329 110.115331 29.5329 93.802831 L 29.5329 29.529394 C 29.5329 13.2208 16.310244 -0.00185625 0.00165 -0.00185625 Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeMiterlimit={10}\r\n strokeWidth={5}\r\n transform=\"matrix(1, 0, 0, -1, 421.5921, 419.0333)\"\r\n />\r\n <path\r\n d=\"M 280.578125 419.230469 L 80.089844 419.230469 C 63.78125 419.230469 50.558594 406.011719 50.558594 389.699219 L 50.558594 325.425781 C 50.558594 309.117188 63.78125 295.898438 80.089844 295.898438 L 280.578125 295.898438 C 296.886719 295.898438 310.109375 309.117188 310.109375 325.425781 L 310.109375 389.699219 C 310.109375 406.011719 296.886719 419.230469 280.578125 419.230469\"\r\n fill=\"currentColor\"\r\n />\r\n <g fill=\"currentColor\">\r\n <path\r\n d=\"M 17.8125 0 L 17.8125 -75.75 L 11 -75.75 L 11 0 Z\"\r\n transform=\"translate(327.5737, 394.627)\"\r\n />\r\n <path\r\n d=\"M 71.453125 0 L 39.28125 -75.75 L 32.0625 -75.75 L 1.15625 0 L 8.375 0 L 16.546875 -21.15625 L 54.890625 -21.15625 L 63.484375 0 Z M 52.484375 -26.8125 L 18.75 -26.8125 L 35.203125 -69.140625 Z\"\r\n transform=\"translate(356.385092, 394.627)\"\r\n />\r\n </g>\r\n <g fill={knockout} stroke={knockout} strokeMiterlimit={10}>\r\n <path d=\"M 114.230469 396.132812 C 100.488281 396.132812 90.390625 390.09375 89.039062 375.625 L 96.117188 375.625 C 96.429688 386.347656 104.964844 390.40625 114.542969 390.40625 C 123.597656 390.40625 134.113281 386.453125 134.113281 375.832031 C 134.113281 367.714844 127.554688 363.964844 117.871094 360.84375 L 112.355469 359.074219 C 100.175781 355.222656 91.222656 350.746094 91.222656 338.980469 C 91.222656 324.929688 103.613281 318.996094 116.105469 318.996094 C 127.554688 318.996094 139.421875 323.261719 139.628906 336.589844 L 132.65625 336.589844 C 131.71875 327.429688 124.742188 324.617188 116.414062 324.617188 C 107.777344 324.617188 98.09375 328.46875 98.09375 338.460938 C 98.09375 345.851562 103.613281 349.601562 115.269531 353.347656 L 121.515625 355.328125 C 133.695312 359.175781 140.671875 363.238281 140.984375 374.6875 C 140.984375 389.78125 127.660156 396.132812 114.230469 396.132812\" />\r\n <path d=\"M 180.703125 357.5625 L 163.421875 357.5625 L 163.421875 389.15625 L 176.746094 389.15625 C 187.679688 389.15625 200.167969 388.429688 200.167969 374.167969 C 200.167969 361.78125 191.113281 357.5625 180.703125 357.5625 M 181.433594 325.96875 L 163.421875 325.96875 L 163.421875 354.214844 L 179.453125 354.214844 C 189.03125 354.214844 196.941406 349.808594 196.941406 339.085938 C 196.941406 329.71875 189.863281 325.96875 181.433594 325.96875 M 177.371094 395.195312 L 156.65625 395.195312 L 156.65625 319.933594 L 177.371094 319.933594 C 181.640625 319.933594 186.324219 319.828125 190.488281 320.972656 C 198.609375 323.265625 204.230469 329.925781 204.230469 338.566406 C 204.230469 347.933594 199.023438 353.554688 190.28125 355.847656 C 200.691406 357.199219 207.351562 363.445312 207.351562 374.273438 C 207.351562 391.550781 191.425781 395.195312 177.371094 395.195312\" />\r\n <path\r\n d=\"M 0.00183125 0.0001875 L -36.849731 40.804875 L -3.3302 75.261906 L 5.724488 75.261906 L -28.732544 41.328312 L 9.26355 0.0001875 Z M -44.033325 75.261906 L -37.2677 75.261906 L -37.2677 0.0001875 L -44.033325 0.0001875 Z\"\r\n transform=\"matrix(1, 0, 0, -1, 267.5802, 395.1955)\"\r\n />\r\n </g>\r\n </g>\r\n);\r\n\r\n/**\r\n * Logo oficial SBK / SBK IA a partir dos SVGs do time de marca.\r\n * Não aplica sombras, gradientes, distorção ou rotação (usos indevidos do brand book).\r\n */\r\nexport const Logo = ({\r\n variant = 'sbk',\r\n color = 'auto',\r\n height = 32,\r\n clearSpace = false,\r\n title,\r\n className,\r\n style,\r\n ...props\r\n}: LogoProps) => {\r\n const box = variant === 'sbk' ? SBK_VIEWBOX : SBK_IA_VIEWBOX;\r\n const width = Math.round((height * box.w) / box.h);\r\n const accessibleName = title ?? (variant === 'sbk' ? 'SBK' : 'SBK IA');\r\n\r\n return (\r\n <svg\r\n aria-label={accessibleName}\r\n className={cn('inline-block shrink-0', COLOR_CLASS[color], className)}\r\n height={height}\r\n role=\"img\"\r\n style={{ ...(clearSpace ? { padding: height, boxSizing: 'content-box' } : null), ...style }}\r\n viewBox={`${box.x} ${box.y} ${box.w} ${box.h}`}\r\n width={width}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n {...props}\r\n >\r\n <title>{accessibleName}</title>\r\n {variant === 'sbk' ? <SbkMark /> : <SbkIaMark knockout={KNOCKOUT[color]} />}\r\n </svg>\r\n );\r\n};\r\n\r\nLogo.displayName = 'Logo';\r\n"],"names":["COLOR_CLASS","KNOCKOUT","SBK_VIEWBOX","SBK_IA_VIEWBOX","SbkMark","jsxs","jsx","SbkIaMark","knockout","Logo","variant","color","height","clearSpace","title","className","style","props","box","width","accessibleName","cn"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MiniCard.js","sources":["../../../src/components/MiniCard/MiniCard.tsx"],"sourcesContent":["import type React from 'react';\nimport { ArrowDownRight, ArrowRight, ArrowUpRight } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { inverseScope } from '../../utils/styles';\nimport { Icon } from '../Icon/Icon';\n\nexport type MiniCardTrend = 'up' | 'down' | 'neutral';\n\nexport interface MiniCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Variação exibida ao lado do valor (ex.: \"+12%\"). */\n delta?: React.ReactNode;\n /** Texto de apoio abaixo do valor. */\n description?: React.ReactNode;\n icon?: React.ReactNode;\n label: React.ReactNode;\n /** Direção da variação. `up` não significa \"bom\": ajuste `trendPositive` quando cair for positivo. */\n trend?: MiniCardTrend;\n /** Define se a tendência informada é positiva. Padrão: `up` positivo, `down` negativo. */\n trendPositive?: boolean;\n value: React.ReactNode;\n variant?: 'default' | 'inverse' | 'highlight' | 'glass';\n}\n\nconst VARIANT_CLASS: Record<NonNullable<MiniCardProps['variant']>, string> = {\n default: 'border border-sbk-line bg-sbk-surface text-sbk-fg',\n inverse: cn('border border-transparent', inverseScope),\n highlight: 'border border-transparent bg-sbk-highlight-bg text-sbk-highlight-fg',\n glass: 'sbk-glass text-sbk-fg',\n};\n\nconst TREND_ICON = { up: ArrowUpRight, down: ArrowDownRight, neutral: ArrowRight } as const;\nconst TREND_LABEL = { up: 'alta', down: 'queda', neutral: 'estável' } as const;\n\n/** Card compacto de indicador (KPI): rótulo, valor, variação e ícone. */\nexport const MiniCard = ({\n label,\n value,\n delta,\n trend,\n trendPositive,\n description,\n icon,\n variant = 'default',\n className,\n ...props\n}: MiniCardProps) => {\n const onColor = variant !== 'default' && variant !== 'glass';\n const positive = trendPositive ?? trend !== 'down';\n const trendColor =\n onColor || trend === 'neutral' || !trend\n ? ''\n : positive\n ? 'text-sbk-success-fg'\n : 'text-sbk-error-fg';\n\n return (\n <div\n className={cn(\n 'flex min-w-0 items-start gap-3 rounded-sbk-sm p-4',\n VARIANT_CLASS[variant],\n className,\n )}\n {...props}\n >\n <div className=\"grid min-w-0 flex-1 gap-1\">\n <span\n className={cn(\n 'truncate text-xs font-semibold uppercase tracking-wide',\n onColor ? 'opacity-80' : 'text-sbk-fg-muted',\n )}\n >\n {label}\n </span>\n <div className=\"flex flex-wrap items-baseline gap-2\">\n <span\n className={cn('text-2xl font-semibold leading-none', !onColor && 'text-sbk-fg-heading')}\n >\n {value}\n </span>\n {delta && (\n <span\n className={cn('inline-flex items-center gap-0.5 text-xs font-semibold', trendColor)}\n >\n {trend && <Icon icon={TREND_ICON[trend]} size=\"xs\" />}\n {delta}\n {trend && <span className=\"sr-only\">({TREND_LABEL[trend]})</span>}\n </span>\n )}\n </div>\n {description && (\n <span className={cn('text-xs font-light', onColor ? 'opacity-80' : 'text-sbk-fg-muted')}>\n {description}\n </span>\n )}\n </div>\n {icon && (\n <span\n aria-hidden=\"true\"\n className={cn(\n 'inline-flex size-9 shrink-0 items-center justify-center rounded-sbk-sm [&_svg]:size-5',\n onColor ? 'bg-sbk-branco/15' : 'bg-sbk-primary-subtle text-sbk-primary',\n )}\n >\n {icon}\n </span>\n )}\n </div>\n );\n};\n\nMiniCard.displayName = 'MiniCard';\n"],"names":["VARIANT_CLASS","cn","inverseScope","TREND_ICON","ArrowUpRight","ArrowDownRight","ArrowRight","TREND_LABEL","MiniCard","label","value","delta","trend","trendPositive","description","icon","variant","className","props","onColor","trendColor","jsxs","jsx","Icon"],"mappings":";;;;;AAuBA,MAAMA,IAAuE;AAAA,EAC3E,SAAS;AAAA,EACT,SAASC,EAAG,6BAA6BC,CAAY;AAAA,EACrD,WAAW;AAAA,EACX,OAAO;AACT,GAEMC,IAAa,EAAE,IAAIC,GAAc,MAAMC,GAAgB,SAASC,EAAA,GAChEC,IAAc,EAAE,IAAI,QAAQ,MAAM,SAAS,SAAS,UAAA,GAG7CC,IAAW,CAAC;AAAA,EACvB,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,WAAAC;AAAA,EACA,GAAGC;AACL,MAAqB;AACnB,QAAMC,IAAUH,MAAY,aAAaA,MAAY,SAE/CI,IACJD,KAAWP,MAAU,aAAa,CAACA,IAC/B,KAHWC,KAAiBD,MAAU,SAKpC,wBACA;AAER,SACE,gBAAAS;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWpB;AAAA,QACT;AAAA,QACAD,EAAcgB,CAAO;AAAA,QACrBC;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAG,EAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWrB;AAAA,gBACT;AAAA,gBACAkB,IAAU,eAAe;AAAA,cAAA;AAAA,cAG1B,UAAAV;AAAA,YAAA;AAAA,UAAA;AAAA,UAEH,gBAAAY,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,YAAA,gBAAAC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAWrB,EAAG,uCAAuC,CAACkB,KAAW,qBAAqB;AAAA,gBAErF,UAAAT;AAAA,cAAA;AAAA,YAAA;AAAA,YAEFC,KACC,gBAAAU;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAWpB,EAAG,0DAA0DmB,CAAU;AAAA,gBAEjF,UAAA;AAAA,kBAAAR,uBAAUW,GAAA,EAAK,MAAMpB,EAAWS,CAAK,GAAG,MAAK,MAAK;AAAA,kBAClDD;AAAA,kBACAC,KAAS,gBAAAS,EAAC,QAAA,EAAK,WAAU,WAAU,UAAA;AAAA,oBAAA;AAAA,oBAAEd,EAAYK,CAAK;AAAA,oBAAE;AAAA,kBAAA,EAAA,CAAC;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAC5D,GAEJ;AAAA,UACCE,KACC,gBAAAQ,EAAC,QAAA,EAAK,WAAWrB,EAAG,sBAAsBkB,IAAU,eAAe,mBAAmB,GACnF,UAAAL,EAAA,CACH;AAAA,QAAA,GAEJ;AAAA,QACCC,KACC,gBAAAO;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAWrB;AAAA,cACT;AAAA,cACAkB,IAAU,qBAAqB;AAAA,YAAA;AAAA,YAGhC,UAAAJ;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR;AAEAP,EAAS,cAAc;"}
1
+ {"version":3,"file":"MiniCard.js","sources":["../../../src/components/MiniCard/MiniCard.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { ArrowDownRight, ArrowRight, ArrowUpRight } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { inverseScope } from '../../utils/styles';\r\nimport { Icon } from '../Icon/Icon';\r\n\r\nexport type MiniCardTrend = 'up' | 'down' | 'neutral';\r\n\r\nexport interface MiniCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\r\n /** Variação exibida ao lado do valor (ex.: \"+12%\"). */\r\n delta?: React.ReactNode;\r\n /** Texto de apoio abaixo do valor. */\r\n description?: React.ReactNode;\r\n icon?: React.ReactNode;\r\n label: React.ReactNode;\r\n /** Direção da variação. `up` não significa \"bom\": ajuste `trendPositive` quando cair for positivo. */\r\n trend?: MiniCardTrend;\r\n /** Define se a tendência informada é positiva. Padrão: `up` positivo, `down` negativo. */\r\n trendPositive?: boolean;\r\n value: React.ReactNode;\r\n variant?: 'default' | 'inverse' | 'highlight' | 'glass';\r\n}\r\n\r\nconst VARIANT_CLASS: Record<NonNullable<MiniCardProps['variant']>, string> = {\r\n default: 'border border-sbk-line bg-sbk-surface text-sbk-fg',\r\n inverse: cn('border border-transparent', inverseScope),\r\n highlight: 'border border-transparent bg-sbk-highlight-bg text-sbk-highlight-fg',\r\n glass: 'sbk-glass text-sbk-fg',\r\n};\r\n\r\nconst TREND_ICON = { up: ArrowUpRight, down: ArrowDownRight, neutral: ArrowRight } as const;\r\nconst TREND_LABEL = { up: 'alta', down: 'queda', neutral: 'estável' } as const;\r\n\r\n/** Card compacto de indicador (KPI): rótulo, valor, variação e ícone. */\r\nexport const MiniCard = ({\r\n label,\r\n value,\r\n delta,\r\n trend,\r\n trendPositive,\r\n description,\r\n icon,\r\n variant = 'default',\r\n className,\r\n ...props\r\n}: MiniCardProps) => {\r\n const onColor = variant !== 'default' && variant !== 'glass';\r\n const positive = trendPositive ?? trend !== 'down';\r\n const trendColor =\r\n onColor || trend === 'neutral' || !trend\r\n ? ''\r\n : positive\r\n ? 'text-sbk-success-fg'\r\n : 'text-sbk-error-fg';\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'flex min-w-0 items-start gap-3 rounded-sbk-sm p-4',\r\n VARIANT_CLASS[variant],\r\n className,\r\n )}\r\n {...props}\r\n >\r\n <div className=\"grid min-w-0 flex-1 gap-1\">\r\n <span\r\n className={cn(\r\n 'truncate text-xs font-semibold uppercase tracking-wide',\r\n onColor ? 'opacity-80' : 'text-sbk-fg-muted',\r\n )}\r\n >\r\n {label}\r\n </span>\r\n <div className=\"flex flex-wrap items-baseline gap-2\">\r\n <span\r\n className={cn('text-2xl font-semibold leading-none', !onColor && 'text-sbk-fg-heading')}\r\n >\r\n {value}\r\n </span>\r\n {delta && (\r\n <span\r\n className={cn('inline-flex items-center gap-0.5 text-xs font-semibold', trendColor)}\r\n >\r\n {trend && <Icon icon={TREND_ICON[trend]} size=\"xs\" />}\r\n {delta}\r\n {trend && <span className=\"sr-only\">({TREND_LABEL[trend]})</span>}\r\n </span>\r\n )}\r\n </div>\r\n {description && (\r\n <span className={cn('text-xs font-light', onColor ? 'opacity-80' : 'text-sbk-fg-muted')}>\r\n {description}\r\n </span>\r\n )}\r\n </div>\r\n {icon && (\r\n <span\r\n aria-hidden=\"true\"\r\n className={cn(\r\n 'inline-flex size-9 shrink-0 items-center justify-center rounded-sbk-sm [&_svg]:size-5',\r\n onColor ? 'bg-sbk-branco/15' : 'bg-sbk-primary-subtle text-sbk-primary',\r\n )}\r\n >\r\n {icon}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nMiniCard.displayName = 'MiniCard';\r\n"],"names":["VARIANT_CLASS","cn","inverseScope","TREND_ICON","ArrowUpRight","ArrowDownRight","ArrowRight","TREND_LABEL","MiniCard","label","value","delta","trend","trendPositive","description","icon","variant","className","props","onColor","trendColor","jsxs","jsx","Icon"],"mappings":";;;;;AAuBA,MAAMA,IAAuE;AAAA,EAC3E,SAAS;AAAA,EACT,SAASC,EAAG,6BAA6BC,CAAY;AAAA,EACrD,WAAW;AAAA,EACX,OAAO;AACT,GAEMC,IAAa,EAAE,IAAIC,GAAc,MAAMC,GAAgB,SAASC,EAAA,GAChEC,IAAc,EAAE,IAAI,QAAQ,MAAM,SAAS,SAAS,UAAA,GAG7CC,IAAW,CAAC;AAAA,EACvB,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,WAAAC;AAAA,EACA,GAAGC;AACL,MAAqB;AACnB,QAAMC,IAAUH,MAAY,aAAaA,MAAY,SAE/CI,IACJD,KAAWP,MAAU,aAAa,CAACA,IAC/B,KAHWC,KAAiBD,MAAU,SAKpC,wBACA;AAER,SACE,gBAAAS;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWpB;AAAA,QACT;AAAA,QACAD,EAAcgB,CAAO;AAAA,QACrBC;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAG,EAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWrB;AAAA,gBACT;AAAA,gBACAkB,IAAU,eAAe;AAAA,cAAA;AAAA,cAG1B,UAAAV;AAAA,YAAA;AAAA,UAAA;AAAA,UAEH,gBAAAY,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,YAAA,gBAAAC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAWrB,EAAG,uCAAuC,CAACkB,KAAW,qBAAqB;AAAA,gBAErF,UAAAT;AAAA,cAAA;AAAA,YAAA;AAAA,YAEFC,KACC,gBAAAU;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAWpB,EAAG,0DAA0DmB,CAAU;AAAA,gBAEjF,UAAA;AAAA,kBAAAR,uBAAUW,GAAA,EAAK,MAAMpB,EAAWS,CAAK,GAAG,MAAK,MAAK;AAAA,kBAClDD;AAAA,kBACAC,KAAS,gBAAAS,EAAC,QAAA,EAAK,WAAU,WAAU,UAAA;AAAA,oBAAA;AAAA,oBAAEd,EAAYK,CAAK;AAAA,oBAAE;AAAA,kBAAA,EAAA,CAAC;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAC5D,GAEJ;AAAA,UACCE,KACC,gBAAAQ,EAAC,QAAA,EAAK,WAAWrB,EAAG,sBAAsBkB,IAAU,eAAe,mBAAmB,GACnF,UAAAL,EAAA,CACH;AAAA,QAAA,GAEJ;AAAA,QACCC,KACC,gBAAAO;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAWrB;AAAA,cACT;AAAA,cACAkB,IAAU,qBAAqB;AAAA,YAAA;AAAA,YAGhC,UAAAJ;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR;AAEAP,EAAS,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useId, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { X } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\n\nexport interface ModalProps {\n children: React.ReactNode;\n className?: string;\n closeOnEscape?: boolean;\n closeOnOverlayClick?: boolean;\n /** Rótulo do botão de fechar. Padrão: \"Fechar modal\". */\n closeLabel?: string;\n /** Rodapé fixo (ações). */\n footer?: React.ReactNode;\n isOpen: boolean;\n onClose: () => void;\n showCloseButton?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n subtitle?: React.ReactNode;\n title?: React.ReactNode;\n variant?: 'default' | 'glass';\n}\n\nconst SIZE_CLASS: Record<NonNullable<ModalProps['size']>, string> = {\n sm: 'max-w-[25rem]',\n md: 'max-w-[32rem]',\n lg: 'max-w-[44rem]',\n xl: 'max-w-[56rem]',\n full: 'max-w-[calc(100vw-2rem)] h-[calc(100dvh-2rem)]',\n};\n\nconst FOCUSABLE =\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Diálogo modal com focus trap, restauração de foco, Esc e bloqueio de rolagem.\n * Renderizado em portal no <body>.\n */\nexport const Modal = ({\n isOpen,\n onClose,\n title,\n subtitle,\n children,\n footer,\n size = 'md',\n variant = 'default',\n showCloseButton = true,\n closeOnOverlayClick = true,\n closeOnEscape = true,\n closeLabel = 'Fechar modal',\n className,\n}: ModalProps) => {\n const dialogRef = useRef<HTMLDivElement>(null);\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n const titleId = useId();\n const subtitleId = useId();\n\n useEffect(() => {\n if (!isOpen) return;\n const previouslyFocused = document.activeElement as HTMLElement | null;\n const previousOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n\n const frame = requestAnimationFrame(() => {\n const target = dialogRef.current?.querySelector<HTMLElement>(FOCUSABLE) ?? dialogRef.current;\n target?.focus();\n });\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && closeOnEscape) {\n e.stopPropagation();\n onCloseRef.current();\n return;\n }\n if (e.key !== 'Tab' || !dialogRef.current) return;\n const focusable = Array.from(dialogRef.current.querySelectorAll<HTMLElement>(FOCUSABLE));\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n cancelAnimationFrame(frame);\n document.removeEventListener('keydown', handleKeyDown);\n document.body.style.overflow = previousOverflow;\n previouslyFocused?.focus?.();\n };\n }, [isOpen, closeOnEscape]);\n\n if (!isOpen || typeof document === 'undefined') return null;\n\n const isGlass = variant === 'glass';\n\n return createPortal(\n <div\n className=\"fixed inset-0 z-[var(--sbk-z-modal)] flex items-center justify-center overflow-y-auto bg-sbk-overlay p-4 animate-sbk-fade-in\"\n data-testid=\"modal-overlay\"\n onMouseDown={(e) => {\n if (closeOnOverlayClick && e.target === e.currentTarget) onClose();\n }}\n >\n <div\n ref={dialogRef}\n aria-describedby={subtitle ? subtitleId : undefined}\n aria-labelledby={title ? titleId : undefined}\n aria-modal=\"true\"\n className={cn(\n 'relative flex max-h-[calc(100dvh-2rem)] w-full flex-col overflow-hidden rounded-sbk-lg text-sbk-fg outline-none animate-sbk-scale-in motion-reduce:animate-none',\n isGlass\n ? 'sbk-glass sbk-glass-strong'\n : 'border border-sbk-line bg-sbk-surface shadow-sbk-md',\n SIZE_CLASS[size],\n className,\n )}\n role=\"dialog\"\n tabIndex={-1}\n >\n {(title || subtitle || showCloseButton) && (\n <div\n className={cn(\n 'flex shrink-0 items-start justify-between gap-4 px-6 pb-4 pt-6',\n !isGlass && 'border-b border-sbk-line',\n )}\n >\n <div className=\"grid flex-1 gap-1\">\n {title && (\n <h2\n className=\"m-0 text-xl font-semibold leading-tight text-sbk-fg-heading\"\n id={titleId}\n >\n {title}\n </h2>\n )}\n {subtitle && (\n <p className=\"m-0 text-sm font-light text-sbk-fg-muted\" id={subtitleId}>\n {subtitle}\n </p>\n )}\n </div>\n {showCloseButton && (\n <button\n aria-label={closeLabel}\n className={cn(\n buttonReset,\n 'inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-sbk-sm text-sbk-fg-muted hover:bg-sbk-surface-hover hover:text-sbk-fg',\n transitionColors,\n focusRing,\n )}\n onClick={onClose}\n type=\"button\"\n >\n <X aria-hidden=\"true\" className=\"size-5\" />\n </button>\n )}\n </div>\n )}\n <div className=\"min-h-0 flex-1 overflow-y-auto px-6 py-5 font-light\">{children}</div>\n {footer && (\n <div\n className={cn(\n 'flex shrink-0 items-center justify-end gap-2 px-6 py-4',\n !isGlass && 'border-t border-sbk-line bg-sbk-surface-sunken',\n )}\n >\n {footer}\n </div>\n )}\n </div>\n </div>,\n document.body,\n );\n};\n\nModal.displayName = 'Modal';\n"],"names":["SIZE_CLASS","FOCUSABLE","Modal","isOpen","onClose","title","subtitle","children","footer","size","variant","showCloseButton","closeOnOverlayClick","closeOnEscape","closeLabel","className","dialogRef","useRef","onCloseRef","titleId","useId","subtitleId","useEffect","previouslyFocused","previousOverflow","frame","target","_a","handleKeyDown","focusable","first","last","isGlass","createPortal","jsx","e","jsxs","cn","buttonReset","transitionColors","focusRing","X"],"mappings":"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"}
1
+ {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { useEffect, useId, useRef } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { X } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, focusRing, transitionColors } from '../../utils/styles';\r\n\r\nexport interface ModalProps {\r\n children: React.ReactNode;\r\n className?: string;\r\n closeOnEscape?: boolean;\r\n closeOnOverlayClick?: boolean;\r\n /** Rótulo do botão de fechar. Padrão: \"Fechar modal\". */\r\n closeLabel?: string;\r\n /** Rodapé fixo (ações). */\r\n footer?: React.ReactNode;\r\n isOpen: boolean;\r\n onClose: () => void;\r\n showCloseButton?: boolean;\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\r\n subtitle?: React.ReactNode;\r\n title?: React.ReactNode;\r\n variant?: 'default' | 'glass';\r\n}\r\n\r\nconst SIZE_CLASS: Record<NonNullable<ModalProps['size']>, string> = {\r\n sm: 'max-w-[25rem]',\r\n md: 'max-w-[32rem]',\r\n lg: 'max-w-[44rem]',\r\n xl: 'max-w-[56rem]',\r\n full: 'max-w-[calc(100vw-2rem)] h-[calc(100dvh-2rem)]',\r\n};\r\n\r\nconst FOCUSABLE =\r\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\r\n\r\n/**\r\n * Diálogo modal com focus trap, restauração de foco, Esc e bloqueio de rolagem.\r\n * Renderizado em portal no <body>.\r\n */\r\nexport const Modal = ({\r\n isOpen,\r\n onClose,\r\n title,\r\n subtitle,\r\n children,\r\n footer,\r\n size = 'md',\r\n variant = 'default',\r\n showCloseButton = true,\r\n closeOnOverlayClick = true,\r\n closeOnEscape = true,\r\n closeLabel = 'Fechar modal',\r\n className,\r\n}: ModalProps) => {\r\n const dialogRef = useRef<HTMLDivElement>(null);\r\n const onCloseRef = useRef(onClose);\r\n onCloseRef.current = onClose;\r\n const titleId = useId();\r\n const subtitleId = useId();\r\n\r\n useEffect(() => {\r\n if (!isOpen) return;\r\n const previouslyFocused = document.activeElement as HTMLElement | null;\r\n const previousOverflow = document.body.style.overflow;\r\n document.body.style.overflow = 'hidden';\r\n\r\n const frame = requestAnimationFrame(() => {\r\n const target = dialogRef.current?.querySelector<HTMLElement>(FOCUSABLE) ?? dialogRef.current;\r\n target?.focus();\r\n });\r\n\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape' && closeOnEscape) {\r\n e.stopPropagation();\r\n onCloseRef.current();\r\n return;\r\n }\r\n if (e.key !== 'Tab' || !dialogRef.current) return;\r\n const focusable = Array.from(dialogRef.current.querySelectorAll<HTMLElement>(FOCUSABLE));\r\n if (focusable.length === 0) {\r\n e.preventDefault();\r\n return;\r\n }\r\n const first = focusable[0];\r\n const last = focusable[focusable.length - 1];\r\n if (e.shiftKey && document.activeElement === first) {\r\n e.preventDefault();\r\n last.focus();\r\n } else if (!e.shiftKey && document.activeElement === last) {\r\n e.preventDefault();\r\n first.focus();\r\n }\r\n };\r\n document.addEventListener('keydown', handleKeyDown);\r\n\r\n return () => {\r\n cancelAnimationFrame(frame);\r\n document.removeEventListener('keydown', handleKeyDown);\r\n document.body.style.overflow = previousOverflow;\r\n previouslyFocused?.focus?.();\r\n };\r\n }, [isOpen, closeOnEscape]);\r\n\r\n if (!isOpen || typeof document === 'undefined') return null;\r\n\r\n const isGlass = variant === 'glass';\r\n\r\n return createPortal(\r\n <div\r\n className=\"fixed inset-0 z-[var(--sbk-z-modal)] flex items-center justify-center overflow-y-auto bg-sbk-overlay p-4 animate-sbk-fade-in\"\r\n data-testid=\"modal-overlay\"\r\n onMouseDown={(e) => {\r\n if (closeOnOverlayClick && e.target === e.currentTarget) onClose();\r\n }}\r\n >\r\n <div\r\n ref={dialogRef}\r\n aria-describedby={subtitle ? subtitleId : undefined}\r\n aria-labelledby={title ? titleId : undefined}\r\n aria-modal=\"true\"\r\n className={cn(\r\n 'relative flex max-h-[calc(100dvh-2rem)] w-full flex-col overflow-hidden rounded-sbk-lg text-sbk-fg outline-none animate-sbk-scale-in motion-reduce:animate-none',\r\n isGlass\r\n ? 'sbk-glass sbk-glass-strong'\r\n : 'border border-sbk-line bg-sbk-surface shadow-sbk-md',\r\n SIZE_CLASS[size],\r\n className,\r\n )}\r\n role=\"dialog\"\r\n tabIndex={-1}\r\n >\r\n {(title || subtitle || showCloseButton) && (\r\n <div\r\n className={cn(\r\n 'flex shrink-0 items-start justify-between gap-4 px-6 pb-4 pt-6',\r\n !isGlass && 'border-b border-sbk-line',\r\n )}\r\n >\r\n <div className=\"grid flex-1 gap-1\">\r\n {title && (\r\n <h2\r\n className=\"m-0 text-xl font-semibold leading-tight text-sbk-fg-heading\"\r\n id={titleId}\r\n >\r\n {title}\r\n </h2>\r\n )}\r\n {subtitle && (\r\n <p className=\"m-0 text-sm font-light text-sbk-fg-muted\" id={subtitleId}>\r\n {subtitle}\r\n </p>\r\n )}\r\n </div>\r\n {showCloseButton && (\r\n <button\r\n aria-label={closeLabel}\r\n className={cn(\r\n buttonReset,\r\n 'inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-sbk-sm text-sbk-fg-muted hover:bg-sbk-surface-hover hover:text-sbk-fg',\r\n transitionColors,\r\n focusRing,\r\n )}\r\n onClick={onClose}\r\n type=\"button\"\r\n >\r\n <X aria-hidden=\"true\" className=\"size-5\" />\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n <div className=\"min-h-0 flex-1 overflow-y-auto px-6 py-5 font-light\">{children}</div>\r\n {footer && (\r\n <div\r\n className={cn(\r\n 'flex shrink-0 items-center justify-end gap-2 px-6 py-4',\r\n !isGlass && 'border-t border-sbk-line bg-sbk-surface-sunken',\r\n )}\r\n >\r\n {footer}\r\n </div>\r\n )}\r\n </div>\r\n </div>,\r\n document.body,\r\n );\r\n};\r\n\r\nModal.displayName = 'Modal';\r\n"],"names":["SIZE_CLASS","FOCUSABLE","Modal","isOpen","onClose","title","subtitle","children","footer","size","variant","showCloseButton","closeOnOverlayClick","closeOnEscape","closeLabel","className","dialogRef","useRef","onCloseRef","titleId","useId","subtitleId","useEffect","previouslyFocused","previousOverflow","frame","target","_a","handleKeyDown","focusable","first","last","isGlass","createPortal","jsx","e","jsxs","cn","buttonReset","transitionColors","focusRing","X"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Navigation.js","sources":["../../../src/components/Navigation/Navigation.tsx"],"sourcesContent":["import type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface SidebarProps extends React.HTMLAttributes<HTMLElement> {}\n/** Container lateral simples. Para menu de navegação completo, use SideNav. */\nexport const Sidebar: React.FC<SidebarProps> = ({ className, ...props }) => (\n <aside\n className={cn(\n 'h-full rounded-sbk-md border border-sbk-line bg-sbk-surface p-4 text-sbk-fg',\n className,\n )}\n {...props}\n />\n);\n\nexport interface TopbarProps extends React.HTMLAttributes<HTMLElement> {}\nexport const Topbar: React.FC<TopbarProps> = ({ className, ...props }) => (\n <header\n className={cn(\n 'flex min-h-14 items-center justify-between gap-4 border-b border-sbk-line bg-sbk-surface px-4 text-sbk-fg',\n className,\n )}\n {...props}\n />\n);\n"],"names":["Sidebar","className","props","jsx","cn","Topbar"],"mappings":";;AAKO,MAAMA,IAAkC,CAAC,EAAE,WAAAC,GAAW,GAAGC,QAC9D,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN,GAIWG,IAAgC,CAAC,EAAE,WAAAJ,GAAW,GAAGC,QAC5D,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN;"}
1
+ {"version":3,"file":"Navigation.js","sources":["../../../src/components/Navigation/Navigation.tsx"],"sourcesContent":["import type React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport interface SidebarProps extends React.HTMLAttributes<HTMLElement> {}\r\n/** Container lateral simples. Para menu de navegação completo, use SideNav. */\r\nexport const Sidebar: React.FC<SidebarProps> = ({ className, ...props }) => (\r\n <aside\r\n className={cn(\r\n 'h-full rounded-sbk-md border border-sbk-line bg-sbk-surface p-4 text-sbk-fg',\r\n className,\r\n )}\r\n {...props}\r\n />\r\n);\r\n\r\nexport interface TopbarProps extends React.HTMLAttributes<HTMLElement> {}\r\nexport const Topbar: React.FC<TopbarProps> = ({ className, ...props }) => (\r\n <header\r\n className={cn(\r\n 'flex min-h-14 items-center justify-between gap-4 border-b border-sbk-line bg-sbk-surface px-4 text-sbk-fg',\r\n className,\r\n )}\r\n {...props}\r\n />\r\n);\r\n"],"names":["Sidebar","className","props","jsx","cn","Topbar"],"mappings":";;AAKO,MAAMA,IAAkC,CAAC,EAAE,WAAAC,GAAW,GAAGC,QAC9D,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN,GAIWG,IAAgC,CAAC,EAAE,WAAAJ,GAAW,GAAGC,QAC5D,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN;"}
@@ -1 +1 @@
1
- {"version":3,"file":"NumberInput.js","sources":["../../../src/components/NumberInput/NumberInput.tsx"],"sourcesContent":["import React, { useId } from 'react';\nimport { Minus, Plus } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { buttonReset, describedBy, focusRing, transitionColors } from '../../utils/styles';\nimport { Field } from '../Field/Field';\n\nexport interface NumberInputProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'size' | 'onChange' | 'value' | 'defaultValue'\n> {\n defaultValue?: number;\n error?: string;\n helperText?: string;\n label?: React.ReactNode;\n max?: number;\n min?: number;\n onChange?: (value: number | null) => void;\n size?: 'sm' | 'md' | 'lg';\n step?: number;\n value?: number | null;\n}\n\nconst HEIGHT = { sm: 'min-h-8 text-sm', md: 'min-h-10 text-base', lg: 'min-h-12 text-lg' } as const;\nconst STEPPER = {\n sm: 'w-8 [&_svg]:size-3.5',\n md: 'w-10 [&_svg]:size-4',\n lg: 'w-12 [&_svg]:size-5',\n} as const;\n\nconst clamp = (n: number, min?: number, max?: number) =>\n Math.min(max ?? Number.POSITIVE_INFINITY, Math.max(min ?? Number.NEGATIVE_INFINITY, n));\n\n/** Campo numérico com botões de incremento. Controlado via `value` + `onChange`. */\nexport const NumberInput = React.forwardRef<HTMLInputElement, NumberInputProps>(\n (\n {\n label,\n error,\n helperText,\n size = 'md',\n min,\n max,\n step = 1,\n onChange,\n className,\n id,\n value,\n defaultValue,\n disabled,\n required,\n ...props\n },\n ref,\n ) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n const current = value ?? defaultValue ?? 0;\n\n const stepBy = (dir: 1 | -1) => onChange?.(clamp(current + dir * step, min, max));\n\n const stepperClass = cn(\n 'flex shrink-0 cursor-pointer items-center justify-center bg-sbk-surface-sunken text-sbk-fg-muted hover:bg-sbk-surface-hover hover:text-sbk-fg disabled:cursor-not-allowed disabled:opacity-50',\n transitionColors,\n focusRing,\n STEPPER[size],\n );\n\n return (\n <Field error={error} helperText={helperText} id={inputId} label={label} required={required}>\n <div\n className={cn(\n 'inline-flex overflow-hidden rounded-sbk-sm border border-sbk-line-strong bg-sbk-surface',\n 'focus-within:border-sbk-primary',\n error && 'border-sbk-error',\n disabled && 'opacity-60',\n )}\n >\n <button\n aria-controls={inputId}\n aria-label=\"Diminuir\"\n className={cn(buttonReset, stepperClass, 'border-r border-sbk-line')}\n disabled={disabled || (min !== undefined && current <= min)}\n onClick={() => stepBy(-1)}\n tabIndex={-1}\n type=\"button\"\n >\n <Minus aria-hidden=\"true\" />\n </button>\n <input\n ref={ref}\n aria-describedby={describedBy(inputId, error, helperText)}\n aria-invalid={error ? true : undefined}\n className={cn(\n 'w-full min-w-0 bg-transparent px-3 text-center font-light text-sbk-fg outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none',\n HEIGHT[size],\n className,\n )}\n defaultValue={value === undefined ? defaultValue : undefined}\n disabled={disabled}\n id={inputId}\n inputMode=\"decimal\"\n max={max}\n min={min}\n onChange={(e) => onChange?.(e.target.value === '' ? null : Number(e.target.value))}\n required={required}\n step={step}\n type=\"number\"\n value={value === undefined ? undefined : (value ?? '')}\n {...props}\n />\n <button\n aria-controls={inputId}\n aria-label=\"Aumentar\"\n className={cn(buttonReset, stepperClass, 'border-l border-sbk-line')}\n disabled={disabled || (max !== undefined && current >= max)}\n onClick={() => stepBy(1)}\n tabIndex={-1}\n type=\"button\"\n >\n <Plus aria-hidden=\"true\" />\n </button>\n </div>\n </Field>\n );\n },\n);\n\nNumberInput.displayName = 'NumberInput';\n"],"names":["HEIGHT","STEPPER","clamp","n","min","max","NumberInput","React","label","error","helperText","size","step","onChange","className","id","value","defaultValue","disabled","required","props","ref","autoId","useId","inputId","current","stepBy","dir","stepperClass","cn","transitionColors","focusRing","Field","jsxs","jsx","buttonReset","Minus","describedBy","e","Plus"],"mappings":"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"}
1
+ {"version":3,"file":"NumberInput.js","sources":["../../../src/components/NumberInput/NumberInput.tsx"],"sourcesContent":["import React, { useId } from 'react';\r\nimport { Minus, Plus } from 'lucide-react';\r\nimport { cn } from '../../utils/cn';\r\nimport { buttonReset, describedBy, focusRing, transitionColors } from '../../utils/styles';\r\nimport { Field } from '../Field/Field';\r\n\r\nexport interface NumberInputProps extends Omit<\r\n React.InputHTMLAttributes<HTMLInputElement>,\r\n 'type' | 'size' | 'onChange' | 'value' | 'defaultValue'\r\n> {\r\n defaultValue?: number;\r\n error?: string;\r\n helperText?: string;\r\n label?: React.ReactNode;\r\n max?: number;\r\n min?: number;\r\n onChange?: (value: number | null) => void;\r\n size?: 'sm' | 'md' | 'lg';\r\n step?: number;\r\n value?: number | null;\r\n}\r\n\r\nconst HEIGHT = { sm: 'min-h-8 text-sm', md: 'min-h-10 text-base', lg: 'min-h-12 text-lg' } as const;\r\nconst STEPPER = {\r\n sm: 'w-8 [&_svg]:size-3.5',\r\n md: 'w-10 [&_svg]:size-4',\r\n lg: 'w-12 [&_svg]:size-5',\r\n} as const;\r\n\r\nconst clamp = (n: number, min?: number, max?: number) =>\r\n Math.min(max ?? Number.POSITIVE_INFINITY, Math.max(min ?? Number.NEGATIVE_INFINITY, n));\r\n\r\n/** Campo numérico com botões de incremento. Controlado via `value` + `onChange`. */\r\nexport const NumberInput = React.forwardRef<HTMLInputElement, NumberInputProps>(\r\n (\r\n {\r\n label,\r\n error,\r\n helperText,\r\n size = 'md',\r\n min,\r\n max,\r\n step = 1,\r\n onChange,\r\n className,\r\n id,\r\n value,\r\n defaultValue,\r\n disabled,\r\n required,\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const autoId = useId();\r\n const inputId = id ?? autoId;\r\n const current = value ?? defaultValue ?? 0;\r\n\r\n const stepBy = (dir: 1 | -1) => onChange?.(clamp(current + dir * step, min, max));\r\n\r\n const stepperClass = cn(\r\n 'flex shrink-0 cursor-pointer items-center justify-center bg-sbk-surface-sunken text-sbk-fg-muted hover:bg-sbk-surface-hover hover:text-sbk-fg disabled:cursor-not-allowed disabled:opacity-50',\r\n transitionColors,\r\n focusRing,\r\n STEPPER[size],\r\n );\r\n\r\n return (\r\n <Field error={error} helperText={helperText} id={inputId} label={label} required={required}>\r\n <div\r\n className={cn(\r\n 'inline-flex overflow-hidden rounded-sbk-sm border border-sbk-line-strong bg-sbk-surface',\r\n 'focus-within:border-sbk-primary',\r\n error && 'border-sbk-error',\r\n disabled && 'opacity-60',\r\n )}\r\n >\r\n <button\r\n aria-controls={inputId}\r\n aria-label=\"Diminuir\"\r\n className={cn(buttonReset, stepperClass, 'border-r border-sbk-line')}\r\n disabled={disabled || (min !== undefined && current <= min)}\r\n onClick={() => stepBy(-1)}\r\n tabIndex={-1}\r\n type=\"button\"\r\n >\r\n <Minus aria-hidden=\"true\" />\r\n </button>\r\n <input\r\n ref={ref}\r\n aria-describedby={describedBy(inputId, error, helperText)}\r\n aria-invalid={error ? true : undefined}\r\n className={cn(\r\n 'w-full min-w-0 bg-transparent px-3 text-center font-light text-sbk-fg outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none',\r\n HEIGHT[size],\r\n className,\r\n )}\r\n defaultValue={value === undefined ? defaultValue : undefined}\r\n disabled={disabled}\r\n id={inputId}\r\n inputMode=\"decimal\"\r\n max={max}\r\n min={min}\r\n onChange={(e) => onChange?.(e.target.value === '' ? null : Number(e.target.value))}\r\n required={required}\r\n step={step}\r\n type=\"number\"\r\n value={value === undefined ? undefined : (value ?? '')}\r\n {...props}\r\n />\r\n <button\r\n aria-controls={inputId}\r\n aria-label=\"Aumentar\"\r\n className={cn(buttonReset, stepperClass, 'border-l border-sbk-line')}\r\n disabled={disabled || (max !== undefined && current >= max)}\r\n onClick={() => stepBy(1)}\r\n tabIndex={-1}\r\n type=\"button\"\r\n >\r\n <Plus aria-hidden=\"true\" />\r\n </button>\r\n </div>\r\n </Field>\r\n );\r\n },\r\n);\r\n\r\nNumberInput.displayName = 'NumberInput';\r\n"],"names":["HEIGHT","STEPPER","clamp","n","min","max","NumberInput","React","label","error","helperText","size","step","onChange","className","id","value","defaultValue","disabled","required","props","ref","autoId","useId","inputId","current","stepBy","dir","stepperClass","cn","transitionColors","focusRing","Field","jsxs","jsx","buttonReset","Minus","describedBy","e","Plus"],"mappings":"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"}