@sbkbs/ui 1.0.3 → 1.0.5

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 (121) hide show
  1. package/README.md +115 -115
  2. package/dist/components/Accordion/Accordion.js +56 -0
  3. package/dist/components/Accordion/Accordion.js.map +1 -0
  4. package/dist/components/Accordion/Accordion.stories.d.ts +7 -0
  5. package/dist/components/Alert/Alert.js +32 -0
  6. package/dist/components/Alert/Alert.js.map +1 -0
  7. package/dist/components/Alert/Alert.stories.d.ts +8 -0
  8. package/dist/components/Badge/Badge.js +35 -0
  9. package/dist/components/Badge/Badge.js.map +1 -0
  10. package/dist/components/Badge/Badge.stories.d.ts +8 -0
  11. package/dist/components/Breadcrumb/Breadcrumb.d.ts +10 -0
  12. package/dist/components/Breadcrumb/Breadcrumb.js +26 -0
  13. package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -0
  14. package/dist/components/Breadcrumb/Breadcrumb.stories.d.ts +8 -0
  15. package/dist/components/Button/Button.js +122 -0
  16. package/dist/components/Button/Button.js.map +1 -0
  17. package/dist/components/Card/Card.js +33 -0
  18. package/dist/components/Card/Card.js.map +1 -0
  19. package/dist/components/Card/Card.stories.d.ts +8 -0
  20. package/dist/components/Checkbox/Checkbox.d.ts +2 -2
  21. package/dist/components/Checkbox/Checkbox.js +36 -0
  22. package/dist/components/Checkbox/Checkbox.js.map +1 -0
  23. package/dist/components/Checkbox/Checkbox.stories.d.ts +7 -0
  24. package/dist/components/Chip/Chip.js +19 -0
  25. package/dist/components/Chip/Chip.js.map +1 -0
  26. package/dist/components/Combobox/Combobox.d.ts +17 -0
  27. package/dist/components/Combobox/Combobox.js +143 -0
  28. package/dist/components/Combobox/Combobox.js.map +1 -0
  29. package/dist/components/Combobox/Combobox.stories.d.ts +9 -0
  30. package/dist/components/Divider/Divider.js +22 -0
  31. package/dist/components/Divider/Divider.js.map +1 -0
  32. package/dist/components/EmptyState/EmptyState.js +29 -0
  33. package/dist/components/EmptyState/EmptyState.js.map +1 -0
  34. package/dist/components/FileUpload/FileUpload.d.ts +13 -0
  35. package/dist/components/FileUpload/FileUpload.js +116 -0
  36. package/dist/components/FileUpload/FileUpload.js.map +1 -0
  37. package/dist/components/FileUpload/FileUpload.stories.d.ts +10 -0
  38. package/dist/components/Footer/Footer.js +54 -0
  39. package/dist/components/Footer/Footer.js.map +1 -0
  40. package/dist/components/Header/Header.js +114 -0
  41. package/dist/components/Header/Header.js.map +1 -0
  42. package/dist/components/Input/Input.d.ts +2 -2
  43. package/dist/components/Input/Input.js +78 -0
  44. package/dist/components/Input/Input.js.map +1 -0
  45. package/dist/components/Input/Input.stories.d.ts +9 -0
  46. package/dist/components/Layout/Layout.js +41 -0
  47. package/dist/components/Layout/Layout.js.map +1 -0
  48. package/dist/components/Modal/Modal.js +113 -0
  49. package/dist/components/Modal/Modal.js.map +1 -0
  50. package/dist/components/Modal/Modal.stories.d.ts +8 -0
  51. package/dist/components/Navigation/Navigation.js +26 -0
  52. package/dist/components/Navigation/Navigation.js.map +1 -0
  53. package/dist/components/NumberInput/NumberInput.d.ts +12 -0
  54. package/dist/components/NumberInput/NumberInput.js +135 -0
  55. package/dist/components/NumberInput/NumberInput.js.map +1 -0
  56. package/dist/components/NumberInput/NumberInput.stories.d.ts +8 -0
  57. package/dist/components/PageHeader/PageHeader.js +29 -0
  58. package/dist/components/PageHeader/PageHeader.js.map +1 -0
  59. package/dist/components/Pagination/Pagination.js +50 -0
  60. package/dist/components/Pagination/Pagination.js.map +1 -0
  61. package/dist/components/Pagination/Pagination.stories.d.ts +8 -0
  62. package/dist/components/Paragraph/Paragraph.js +41 -0
  63. package/dist/components/Paragraph/Paragraph.js.map +1 -0
  64. package/dist/components/Popover/Popover.js +57 -0
  65. package/dist/components/Popover/Popover.js.map +1 -0
  66. package/dist/components/Radio/Radio.d.ts +2 -2
  67. package/dist/components/Radio/Radio.js +36 -0
  68. package/dist/components/Radio/Radio.js.map +1 -0
  69. package/dist/components/Radio/Radio.stories.d.ts +7 -0
  70. package/dist/components/SectionHeader/SectionHeader.js +19 -0
  71. package/dist/components/SectionHeader/SectionHeader.js.map +1 -0
  72. package/dist/components/Select/Select.d.ts +2 -2
  73. package/dist/components/Select/Select.js +45 -0
  74. package/dist/components/Select/Select.js.map +1 -0
  75. package/dist/components/Select/Select.stories.d.ts +8 -0
  76. package/dist/components/Skeleton/Skeleton.js +25 -0
  77. package/dist/components/Skeleton/Skeleton.js.map +1 -0
  78. package/dist/components/Stepper/Stepper.d.ts +13 -0
  79. package/dist/components/Stepper/Stepper.js +97 -0
  80. package/dist/components/Stepper/Stepper.js.map +1 -0
  81. package/dist/components/Stepper/Stepper.stories.d.ts +8 -0
  82. package/dist/components/Subtitle/Subtitle.js +40 -0
  83. package/dist/components/Subtitle/Subtitle.js.map +1 -0
  84. package/dist/components/Switch/Switch.d.ts +2 -2
  85. package/dist/components/Switch/Switch.js +37 -0
  86. package/dist/components/Switch/Switch.js.map +1 -0
  87. package/dist/components/Switch/Switch.stories.d.ts +8 -0
  88. package/dist/components/Table/Table.js +17 -0
  89. package/dist/components/Table/Table.js.map +1 -0
  90. package/dist/components/Tabs/Tabs.js +62 -0
  91. package/dist/components/Tabs/Tabs.js.map +1 -0
  92. package/dist/components/Tabs/Tabs.stories.d.ts +8 -0
  93. package/dist/components/Tag/Tag.js +29 -0
  94. package/dist/components/Tag/Tag.js.map +1 -0
  95. package/dist/components/Textarea/Textarea.d.ts +2 -2
  96. package/dist/components/Textarea/Textarea.js +46 -0
  97. package/dist/components/Textarea/Textarea.js.map +1 -0
  98. package/dist/components/Textarea/Textarea.stories.d.ts +7 -0
  99. package/dist/components/Title/Title.js +47 -0
  100. package/dist/components/Title/Title.js.map +1 -0
  101. package/dist/components/Toast/Toast.js +110 -0
  102. package/dist/components/Toast/Toast.js.map +1 -0
  103. package/dist/components/Toast/Toast.stories.d.ts +8 -0
  104. package/dist/components/Tooltip/Tooltip.js +36 -0
  105. package/dist/components/Tooltip/Tooltip.js.map +1 -0
  106. package/dist/index.d.ts +10 -5
  107. package/dist/index.js +88 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/oficios-ui.css +1 -1
  110. package/dist/oficios-ui.umd.cjs +1 -1
  111. package/dist/oficios-ui.umd.cjs.map +1 -1
  112. package/dist/theme/ThemeProvider.d.ts +1 -1
  113. package/dist/theme/ThemeProvider.js +22 -0
  114. package/dist/theme/ThemeProvider.js.map +1 -0
  115. package/dist/theme.css +54 -64
  116. package/dist/utils/cn.d.ts +7 -1
  117. package/dist/utils/cn.js +7 -0
  118. package/dist/utils/cn.js.map +1 -0
  119. package/package.json +50 -15
  120. package/dist/oficios-ui.js +0 -1386
  121. package/dist/oficios-ui.js.map +0 -1
@@ -0,0 +1,114 @@
1
+ import { jsxs as a, jsx as r } from "react/jsx-runtime";
2
+ import { useState as u, useEffect as x } from "react";
3
+ const v = () => typeof document > "u" ? "light" : document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light", M = ({
4
+ logoSrc: h,
5
+ logoDarkSrc: i,
6
+ logoAlt: p = "Logo",
7
+ title: l,
8
+ subtitle: d,
9
+ theme: s,
10
+ onLogoClick: e,
11
+ rightContent: m,
12
+ className: b = ""
13
+ }) => {
14
+ const [o, w] = u(!1), [y, c] = u(() => s ?? v()), f = y === "dark" && i ? i : h;
15
+ x(() => {
16
+ const t = () => w(window.scrollY > 10);
17
+ return window.addEventListener("scroll", t, { passive: !0 }), () => window.removeEventListener("scroll", t);
18
+ }, []), x(() => {
19
+ if (s) {
20
+ c(s);
21
+ return;
22
+ }
23
+ const t = () => c(v());
24
+ if (t(), typeof MutationObserver > "u")
25
+ return;
26
+ const n = new MutationObserver(t);
27
+ return n.observe(document.documentElement, {
28
+ attributes: !0,
29
+ attributeFilter: ["data-theme"]
30
+ }), () => n.disconnect();
31
+ }, [s]);
32
+ const N = () => e == null ? void 0 : e(), E = (t) => {
33
+ t.key === "Enter" && (e == null || e());
34
+ };
35
+ return /* @__PURE__ */ a(
36
+ "header",
37
+ {
38
+ className: ["fixed inset-x-0 top-0 z-[1000] w-full backdrop-blur-[12px]", b].filter(Boolean).join(" "),
39
+ children: [
40
+ /* @__PURE__ */ r("div", { className: "h-0.5 w-full bg-[var(--md-primary)]" }),
41
+ /* @__PURE__ */ a(
42
+ "div",
43
+ {
44
+ className: "flex items-center justify-between px-6 py-2 shadow-[var(--shadow-sm)] max-md:flex-col max-md:gap-3 max-md:px-4 max-md:py-3",
45
+ style: {
46
+ color: "var(--md-on-surface)",
47
+ background: `color-mix(in srgb, var(--md-surface) ${o ? "14%" : "18%"}, transparent)`,
48
+ borderBottom: `1px solid color-mix(in srgb, var(--md-outline-variant) ${o ? "22%" : "30%"}, transparent)`
49
+ },
50
+ children: [
51
+ /* @__PURE__ */ a(
52
+ "div",
53
+ {
54
+ className: "flex cursor-pointer items-center gap-3 transition-opacity duration-200 ease-in-out hover:opacity-80",
55
+ onClick: e ? N : void 0,
56
+ onKeyDown: e ? E : void 0,
57
+ role: e ? "button" : void 0,
58
+ tabIndex: e ? 0 : void 0,
59
+ children: [
60
+ f && /* @__PURE__ */ a("div", { className: "flex h-16 w-16 shrink-0 items-center justify-center", children: [
61
+ /* @__PURE__ */ r(
62
+ "img",
63
+ {
64
+ alt: p,
65
+ className: "h-full w-full object-contain",
66
+ onError: (t) => {
67
+ t.target.style.display = "none";
68
+ const n = t.target.nextElementSibling;
69
+ n && (n.style.display = "block");
70
+ },
71
+ src: f
72
+ }
73
+ ),
74
+ /* @__PURE__ */ a(
75
+ "svg",
76
+ {
77
+ className: "hidden h-full w-full",
78
+ fill: "none",
79
+ stroke: "currentColor",
80
+ strokeWidth: "2",
81
+ viewBox: "0 0 24 24",
82
+ children: [
83
+ /* @__PURE__ */ r("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
84
+ /* @__PURE__ */ r("path", { d: "M2 17l10 5 10-5M2 12l10 5 10-5" })
85
+ ]
86
+ }
87
+ )
88
+ ] }),
89
+ (l || d) && /* @__PURE__ */ a("div", { className: "flex flex-col gap-1", children: [
90
+ l && /* @__PURE__ */ r(
91
+ "h1",
92
+ {
93
+ className: "m-0 inline-flex items-baseline text-[1.375rem] font-bold leading-[1.2] tracking-[0.05em] text-[var(--md-on-surface)] max-md:text-xl",
94
+ style: { fontFamily: "var(--font-logo)" },
95
+ children: l
96
+ }
97
+ ),
98
+ d && /* @__PURE__ */ r("p", { className: "m-0 text-[0.8125rem] font-normal text-[var(--md-on-surface-variant)] max-md:text-xs", children: d })
99
+ ] })
100
+ ]
101
+ }
102
+ ),
103
+ m && /* @__PURE__ */ r("div", { className: "flex shrink-0 items-center gap-3 max-md:w-full max-md:flex-wrap max-md:justify-between", children: m })
104
+ ]
105
+ }
106
+ )
107
+ ]
108
+ }
109
+ );
110
+ };
111
+ export {
112
+ M as Header
113
+ };
114
+ //# sourceMappingURL=Header.js.map
@@ -0,0 +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 type { Theme } from '../../theme/ThemeProvider';\n\nexport interface HeaderProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** URL da imagem do logo (tema escuro). Se não informado, usa logoSrc. */\n logoDarkSrc?: string;\n /** URL da imagem do logo (tema claro) */\n logoSrc?: string;\n /** Callback ao clicar na área do logo/título */\n onLogoClick?: () => void;\n /** Conteúdo da área direita (ex.: seletor de idioma, toggle tema, menu usuário) */\n rightContent?: React.ReactNode;\n /** Subtítulo abaixo do título */\n subtitle?: React.ReactNode;\n /** Tema opcional para escolher o logo correto sem depender do ThemeProvider do UI */\n theme?: Theme;\n /** Título exibido ao lado do logo (ex.: \"OFÍCIO.IA\") */\n title?: React.ReactNode;\n}\n\nconst detectTheme = (): Theme => {\n if (typeof document === 'undefined') {\n return 'light';\n }\n\n return document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';\n};\n\nexport const Header: React.FC<HeaderProps> = ({\n logoSrc,\n logoDarkSrc,\n logoAlt = 'Logo',\n title,\n subtitle,\n theme,\n onLogoClick,\n rightContent,\n className = '',\n}) => {\n const [isScrolled, setIsScrolled] = useState(false);\n const [resolvedTheme, setResolvedTheme] = useState<Theme>(() => theme ?? detectTheme());\n\n const logoSrcResolved = resolvedTheme === 'dark' && logoDarkSrc ? logoDarkSrc : logoSrc;\n\n useEffect(() => {\n const handleScroll = () => setIsScrolled(window.scrollY > 10);\n window.addEventListener('scroll', handleScroll, { passive: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, []);\n\n useEffect(() => {\n if (theme) {\n setResolvedTheme(theme);\n return;\n }\n\n const syncTheme = () => setResolvedTheme(detectTheme());\n syncTheme();\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(syncTheme);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-theme'],\n });\n\n return () => observer.disconnect();\n }, [theme]);\n\n const handleClick = () => onLogoClick?.();\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n onLogoClick?.();\n }\n };\n\n return (\n <header\n className={['fixed inset-x-0 top-0 z-[1000] w-full backdrop-blur-[12px]', className]\n .filter(Boolean)\n .join(' ')}\n >\n <div className=\"h-0.5 w-full bg-[var(--md-primary)]\" />\n <div\n className=\"flex items-center justify-between px-6 py-2 shadow-[var(--shadow-sm)] max-md:flex-col max-md:gap-3 max-md:px-4 max-md:py-3\"\n style={{\n color: 'var(--md-on-surface)',\n background: `color-mix(in srgb, var(--md-surface) ${\n isScrolled ? '14%' : '18%'\n }, transparent)`,\n borderBottom: `1px solid color-mix(in srgb, var(--md-outline-variant) ${\n isScrolled ? '22%' : '30%'\n }, transparent)`,\n }}\n >\n <div\n className=\"flex cursor-pointer items-center gap-3 transition-opacity duration-200 ease-in-out hover:opacity-80\"\n onClick={onLogoClick ? handleClick : undefined}\n onKeyDown={onLogoClick ? handleKeyDown : undefined}\n role={onLogoClick ? 'button' : undefined}\n tabIndex={onLogoClick ? 0 : undefined}\n >\n {logoSrcResolved && (\n <div className=\"flex h-16 w-16 shrink-0 items-center justify-center\">\n <img\n alt={logoAlt}\n className=\"h-full w-full object-contain\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = 'none';\n const next = (e.target as HTMLElement).nextElementSibling as HTMLElement;\n if (next) {\n next.style.display = 'block';\n }\n }}\n src={logoSrcResolved}\n />\n <svg\n className=\"hidden h-full w-full\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\" />\n <path d=\"M2 17l10 5 10-5M2 12l10 5 10-5\" />\n </svg>\n </div>\n )}\n {(title || subtitle) && (\n <div className=\"flex flex-col gap-1\">\n {title && (\n <h1\n className=\"m-0 inline-flex items-baseline text-[1.375rem] font-bold leading-[1.2] tracking-[0.05em] text-[var(--md-on-surface)] max-md:text-xl\"\n style={{ fontFamily: 'var(--font-logo)' }}\n >\n {title}\n </h1>\n )}\n {subtitle && (\n <p className=\"m-0 text-[0.8125rem] font-normal text-[var(--md-on-surface-variant)] max-md:text-xs\">\n {subtitle}\n </p>\n )}\n </div>\n )}\n </div>\n {rightContent && (\n <div className=\"flex shrink-0 items-center gap-3 max-md:w-full max-md:flex-wrap max-md:justify-between\">\n {rightContent}\n </div>\n )}\n </div>\n </header>\n );\n};\n"],"names":["detectTheme","Header","logoSrc","logoDarkSrc","logoAlt","title","subtitle","theme","onLogoClick","rightContent","className","isScrolled","setIsScrolled","useState","resolvedTheme","setResolvedTheme","logoSrcResolved","useEffect","handleScroll","syncTheme","observer","handleClick","handleKeyDown","e","jsxs","jsx","next"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type React from 'react';
1
+ import React from 'react';
2
2
  export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
3
3
  error?: string;
4
4
  fullWidth?: boolean;
@@ -8,4 +8,4 @@ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElem
8
8
  rightIcon?: React.ReactNode;
9
9
  size?: 'sm' | 'md' | 'lg';
10
10
  }
11
- export declare const Input: React.FC<InputProps>;
11
+ export declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,78 @@
1
+ import { jsxs as d, jsx as a } from "react/jsx-runtime";
2
+ import g from "react";
3
+ import { cn as c } from "../../utils/cn.js";
4
+ const b = g.forwardRef(
5
+ ({
6
+ label: i,
7
+ error: e,
8
+ helperText: s,
9
+ leftIcon: t,
10
+ rightIcon: o,
11
+ fullWidth: l = !1,
12
+ size: m = "md",
13
+ className: v,
14
+ id: p,
15
+ ...f
16
+ }, u) => {
17
+ const r = p || `input-${Math.random().toString(36).substring(2, 9)}`, n = !!e, x = c(
18
+ "w-full rounded-[var(--border-radius-md)] border border-[var(--md-outline-variant)] bg-[var(--md-surface)] font-inherit text-[var(--md-on-surface)] outline-none transition-[var(--transition-all)] placeholder:text-[var(--md-on-surface-variant)] placeholder:opacity-70 hover:not-disabled:not-focus:border-[var(--border-color-hover)] focus:border-[var(--border-color-focus)] focus:[box-shadow:0_0_0_0.1875rem_rgba(47,93,140,0.15)] disabled:cursor-not-allowed disabled:bg-[var(--md-surface-container-high)] disabled:opacity-60",
19
+ n && "border-[var(--md-error)] focus:border-[var(--md-error)] focus:[box-shadow:0_0_0_0.1875rem_rgba(186,26,26,0.2)]",
20
+ {
21
+ sm: "min-h-8 px-[var(--spacing-md)] py-[var(--spacing-sm)] text-[var(--font-size-sm)]",
22
+ md: "min-h-10 px-[var(--spacing-lg)] py-[var(--spacing-md)] text-[var(--font-size-base)]",
23
+ lg: "min-h-12 px-[var(--spacing-xl)] py-[var(--spacing-lg)] text-[var(--font-size-lg)]"
24
+ }[m],
25
+ // icon padding vem depois do sizeClassMap para não ser sobrescrito pelo px-* do tamanho
26
+ t && "pl-10",
27
+ o && "pr-10",
28
+ v
29
+ );
30
+ return /* @__PURE__ */ d("div", { className: c("flex flex-col gap-[var(--spacing-xs)]", l && "w-full"), children: [
31
+ i && /* @__PURE__ */ a(
32
+ "label",
33
+ {
34
+ className: "text-[var(--font-size-sm)] font-[var(--font-weight-semibold)] text-[var(--md-on-surface)]",
35
+ htmlFor: r,
36
+ children: i
37
+ }
38
+ ),
39
+ /* @__PURE__ */ d("div", { className: "group relative flex w-full items-center", children: [
40
+ t && /* @__PURE__ */ a("span", { className: "pointer-events-none absolute left-[var(--spacing-md)] z-[1] flex items-center justify-center text-[var(--md-on-surface-variant)] group-focus-within:text-[var(--md-primary)] [&_svg]:h-[1.125rem] [&_svg]:w-[1.125rem]", children: t }),
41
+ /* @__PURE__ */ a(
42
+ "input",
43
+ {
44
+ ref: u,
45
+ "aria-describedby": e ? `${r}-error` : s ? `${r}-helper` : void 0,
46
+ "aria-invalid": n ? !0 : void 0,
47
+ className: x,
48
+ id: r,
49
+ ...f
50
+ }
51
+ ),
52
+ o && /* @__PURE__ */ a("span", { className: "pointer-events-none absolute right-[var(--spacing-md)] z-[1] flex items-center justify-center text-[var(--md-on-surface-variant)] group-focus-within:text-[var(--md-primary)] [&_svg]:h-[1.125rem] [&_svg]:w-[1.125rem]", children: o })
53
+ ] }),
54
+ e && /* @__PURE__ */ a(
55
+ "span",
56
+ {
57
+ className: "mt-[var(--spacing-xs)] block text-[var(--font-size-xs)] text-[var(--md-error)]",
58
+ id: `${r}-error`,
59
+ role: "alert",
60
+ children: e
61
+ }
62
+ ),
63
+ s && !e && /* @__PURE__ */ a(
64
+ "span",
65
+ {
66
+ className: "mt-[var(--spacing-xs)] block text-[var(--font-size-xs)] text-[var(--md-on-surface-variant)]",
67
+ id: `${r}-helper`,
68
+ children: s
69
+ }
70
+ )
71
+ ] });
72
+ }
73
+ );
74
+ b.displayName = "Input";
75
+ export {
76
+ b as Input
77
+ };
78
+ //# sourceMappingURL=Input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n error?: string;\n fullWidth?: boolean;\n helperText?: string;\n label?: string;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n size?: 'sm' | 'md' | 'lg';\n}\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 ...props\n },\n ref,\n ) => {\n const inputId = id || `input-${Math.random().toString(36).substring(2, 9)}`;\n const hasError = !!error;\n\n const sizeClassMap: Record<NonNullable<InputProps['size']>, string> = {\n sm: 'min-h-8 px-[var(--spacing-md)] py-[var(--spacing-sm)] text-[var(--font-size-sm)]',\n md: 'min-h-10 px-[var(--spacing-lg)] py-[var(--spacing-md)] text-[var(--font-size-base)]',\n lg: 'min-h-12 px-[var(--spacing-xl)] py-[var(--spacing-lg)] text-[var(--font-size-lg)]',\n };\n\n const combinedClass = cn(\n 'w-full rounded-[var(--border-radius-md)] border border-[var(--md-outline-variant)] bg-[var(--md-surface)] font-inherit text-[var(--md-on-surface)] outline-none transition-[var(--transition-all)] placeholder:text-[var(--md-on-surface-variant)] placeholder:opacity-70 hover:not-disabled:not-focus:border-[var(--border-color-hover)] focus:border-[var(--border-color-focus)] focus:[box-shadow:0_0_0_0.1875rem_rgba(47,93,140,0.15)] disabled:cursor-not-allowed disabled:bg-[var(--md-surface-container-high)] disabled:opacity-60',\n hasError &&\n 'border-[var(--md-error)] focus:border-[var(--md-error)] focus:[box-shadow:0_0_0_0.1875rem_rgba(186,26,26,0.2)]',\n sizeClassMap[size],\n // icon padding vem depois do sizeClassMap para não ser sobrescrito pelo px-* do tamanho\n leftIcon && 'pl-10',\n rightIcon && 'pr-10',\n className,\n );\n\n return (\n <div className={cn('flex flex-col gap-[var(--spacing-xs)]', fullWidth && 'w-full')}>\n {label && (\n <label\n className=\"text-[var(--font-size-sm)] font-[var(--font-weight-semibold)] text-[var(--md-on-surface)]\"\n htmlFor={inputId}\n >\n {label}\n </label>\n )}\n <div className=\"group relative flex w-full items-center\">\n {leftIcon && (\n <span className=\"pointer-events-none absolute left-[var(--spacing-md)] z-[1] flex items-center justify-center text-[var(--md-on-surface-variant)] group-focus-within:text-[var(--md-primary)] [&_svg]:h-[1.125rem] [&_svg]:w-[1.125rem]\">\n {leftIcon}\n </span>\n )}\n <input\n ref={ref}\n aria-describedby={\n error ? `${inputId}-error` : helperText ? `${inputId}-helper` : undefined\n }\n aria-invalid={hasError ? true : undefined}\n className={combinedClass}\n id={inputId}\n {...props}\n />\n {rightIcon && (\n <span className=\"pointer-events-none absolute right-[var(--spacing-md)] z-[1] flex items-center justify-center text-[var(--md-on-surface-variant)] group-focus-within:text-[var(--md-primary)] [&_svg]:h-[1.125rem] [&_svg]:w-[1.125rem]\">\n {rightIcon}\n </span>\n )}\n </div>\n {error && (\n <span\n className=\"mt-[var(--spacing-xs)] block text-[var(--font-size-xs)] text-[var(--md-error)]\"\n id={`${inputId}-error`}\n role=\"alert\"\n >\n {error}\n </span>\n )}\n {helperText && !error && (\n <span\n className=\"mt-[var(--spacing-xs)] block text-[var(--font-size-xs)] text-[var(--md-on-surface-variant)]\"\n id={`${inputId}-helper`}\n >\n {helperText}\n </span>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = 'Input';\n"],"names":["Input","React","label","error","helperText","leftIcon","rightIcon","fullWidth","size","className","id","props","ref","inputId","hasError","combinedClass","cn","jsx","jsxs"],"mappings":";;;AAaO,MAAMA,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,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAAUH,KAAM,SAAS,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC,IACnEI,IAAW,CAAC,CAACX,GAQbY,IAAgBC;AAAA,MACpB;AAAA,MACAF,KACE;AAAA,MATkE;AAAA,QACpE,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA,EAOSN,CAAI;AAAA;AAAA,MAEjBH,KAAY;AAAA,MACZC,KAAa;AAAA,MACbG;AAAA,IAAA;AAGF,6BACG,OAAA,EAAI,WAAWO,EAAG,yCAAyCT,KAAa,QAAQ,GAC9E,UAAA;AAAA,MAAAL,KACC,gBAAAe;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,SAASJ;AAAA,UAER,UAAAX;AAAA,QAAA;AAAA,MAAA;AAAA,MAGL,gBAAAgB,EAAC,OAAA,EAAI,WAAU,2CACZ,UAAA;AAAA,QAAAb,KACC,gBAAAY,EAAC,QAAA,EAAK,WAAU,0NACb,UAAAZ,GACH;AAAA,QAEF,gBAAAY;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAAL;AAAA,YACA,oBACET,IAAQ,GAAGU,CAAO,WAAWT,IAAa,GAAGS,CAAO,YAAY;AAAA,YAElE,gBAAcC,IAAW,KAAO;AAAA,YAChC,WAAWC;AAAA,YACX,IAAIF;AAAA,YACH,GAAGF;AAAA,UAAA;AAAA,QAAA;AAAA,QAELL,KACC,gBAAAW,EAAC,QAAA,EAAK,WAAU,2NACb,UAAAX,EAAA,CACH;AAAA,MAAA,GAEJ;AAAA,MACCH,KACC,gBAAAc;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,IAAI,GAAGJ,CAAO;AAAA,UACd,MAAK;AAAA,UAEJ,UAAAV;AAAA,QAAA;AAAA,MAAA;AAAA,MAGJC,KAAc,CAACD,KACd,gBAAAc;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,IAAI,GAAGJ,CAAO;AAAA,UAEb,UAAAT;AAAA,QAAA;AAAA,MAAA;AAAA,IACH,GAEJ;AAAA,EAEJ;AACF;AAEAJ,EAAM,cAAc;"}
@@ -0,0 +1,9 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Input } from './Input';
3
+ declare const meta: Meta<typeof Input>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof Input>;
6
+ export declare const Playground: Story;
7
+ export declare const States: Story;
8
+ export declare const Sizes: Story;
9
+ export declare const WithIcons: Story;
@@ -0,0 +1,41 @@
1
+ import { jsx as m } from "react/jsx-runtime";
2
+ import { cn as o } from "../../utils/cn.js";
3
+ const t = ({ size: s = "lg", className: a, ...l }) => {
4
+ const g = {
5
+ sm: "max-w-2xl",
6
+ md: "max-w-4xl",
7
+ lg: "max-w-6xl",
8
+ xl: "max-w-7xl",
9
+ full: "max-w-none"
10
+ }[s];
11
+ return /* @__PURE__ */ m("div", { className: o("mx-auto w-full px-4", g, a), ...l });
12
+ }, n = ({ gap: s = "md", className: a, ...l }) => {
13
+ const g = {
14
+ xs: "gap-1",
15
+ sm: "gap-2",
16
+ md: "gap-3",
17
+ lg: "gap-4",
18
+ xl: "gap-6"
19
+ }[s];
20
+ return /* @__PURE__ */ m("div", { className: o("flex flex-col", g, a), ...l });
21
+ }, d = ({ cols: s = 2, gap: a = "md", className: l, ...g }) => {
22
+ const x = {
23
+ 1: "grid-cols-1",
24
+ 2: "grid-cols-2",
25
+ 3: "grid-cols-3",
26
+ 4: "grid-cols-4"
27
+ }[s], c = {
28
+ xs: "gap-1",
29
+ sm: "gap-2",
30
+ md: "gap-3",
31
+ lg: "gap-4",
32
+ xl: "gap-6"
33
+ }[a];
34
+ return /* @__PURE__ */ m("div", { className: o("grid", x, c, l), ...g });
35
+ };
36
+ export {
37
+ t as Container,
38
+ d as Grid,
39
+ n as Stack
40
+ };
41
+ //# sourceMappingURL=Layout.js.map
@@ -0,0 +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}\n\nexport const Grid: React.FC<GridProps> = ({ cols = 2, gap = 'md', className, ...props }) => {\n const colsClass = {\n 1: 'grid-cols-1',\n 2: 'grid-cols-2',\n 3: 'grid-cols-3',\n 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","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,GAOaO,IAA4B,CAAC,EAAE,MAAAC,IAAO,GAAG,KAAAH,IAAM,MAAM,WAAAN,GAAW,GAAGC,QAAY;AAC1F,QAAMS,IAAY;AAAA,IAChB,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EAAA,EACHD,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,QAAQM,GAAWH,GAAUP,CAAS,GAAI,GAAGC,EAAA,CAAO;AAChF;"}
@@ -0,0 +1,113 @@
1
+ import { jsx as n, jsxs as c } from "react/jsx-runtime";
2
+ import { useRef as b, useEffect as y } from "react";
3
+ const K = ({
4
+ isOpen: t,
5
+ onClose: o,
6
+ title: l,
7
+ subtitle: i,
8
+ children: g,
9
+ size: w = "md",
10
+ showCloseButton: m = !0,
11
+ closeOnOverlayClick: u = !0,
12
+ className: p = ""
13
+ }) => {
14
+ const d = b(null), s = b(null);
15
+ if (y(() => (t ? (s.current = document.activeElement, document.body.style.overflow = "hidden") : document.body.style.overflow = "", () => {
16
+ document.body.style.overflow = "", s.current && s.current.focus();
17
+ }), [t]), y(() => {
18
+ const r = (e) => {
19
+ e.key === "Escape" && t && o();
20
+ }, f = (e) => {
21
+ if (e.key !== "Tab" || !d.current || !t)
22
+ return;
23
+ const a = d.current.querySelectorAll(
24
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
25
+ );
26
+ if (a.length === 0) {
27
+ e.preventDefault();
28
+ return;
29
+ }
30
+ const v = a[0], x = a[a.length - 1], h = document.activeElement;
31
+ e.shiftKey && h === v ? (e.preventDefault(), x.focus()) : !e.shiftKey && h === x && (e.preventDefault(), v.focus());
32
+ };
33
+ return t && (document.addEventListener("keydown", r), document.addEventListener("keydown", f), requestAnimationFrame(() => {
34
+ var a;
35
+ const e = ((a = d.current) == null ? void 0 : a.querySelector(
36
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
37
+ )) ?? d.current;
38
+ e == null || e.focus();
39
+ })), () => {
40
+ document.removeEventListener("keydown", r), document.removeEventListener("keydown", f);
41
+ };
42
+ }, [t, o]), !t)
43
+ return null;
44
+ const k = (r) => {
45
+ u && r.target === r.currentTarget && o();
46
+ }, E = (r) => {
47
+ u && (r.key === "Enter" || r.key === " ") && r.target === r.currentTarget && o();
48
+ }, N = [
49
+ "relative z-[var(--z-index-modal)] m-auto flex w-full max-h-[90vh] max-w-full flex-col overflow-hidden rounded-[var(--border-radius-2xl)] border border-[var(--md-outline-variant)] bg-[var(--md-surface)] shadow-[var(--shadow-2xl)]",
50
+ {
51
+ sm: "max-w-[25rem]",
52
+ md: "max-w-[31.25rem]",
53
+ lg: "max-w-[43.75rem]",
54
+ xl: "max-w-[56.25rem]",
55
+ full: "max-h-[90vh] max-w-[90vw]"
56
+ }[w],
57
+ p
58
+ ].filter(Boolean).join(" ");
59
+ return /* @__PURE__ */ n(
60
+ "div",
61
+ {
62
+ "aria-labelledby": l ? "modal-title" : void 0,
63
+ "aria-modal": "true",
64
+ className: "fixed inset-0 z-[var(--z-index-modal-backdrop)] flex min-h-[100dvh] items-center justify-center overflow-y-auto bg-black/50 p-[var(--spacing-lg)] backdrop-blur-[8px]",
65
+ onClick: k,
66
+ onKeyDown: E,
67
+ role: "dialog",
68
+ children: /* @__PURE__ */ c("div", { className: N, ref: d, tabIndex: -1, children: [
69
+ (l || i || m) && /* @__PURE__ */ c("div", { className: "flex shrink-0 items-start justify-between gap-[var(--spacing-lg)] border-b border-[var(--md-outline-variant)] p-[var(--spacing-2xl)]", children: [
70
+ (l || i) && /* @__PURE__ */ c("div", { className: "flex-1", children: [
71
+ l && /* @__PURE__ */ n(
72
+ "h2",
73
+ {
74
+ className: "mb-[var(--spacing-xs)] mt-0 text-[var(--font-size-2xl)] font-[var(--font-weight-semibold)] leading-[var(--line-height-tight)] text-[var(--md-on-surface)]",
75
+ id: "modal-title",
76
+ children: l
77
+ }
78
+ ),
79
+ i && /* @__PURE__ */ n("p", { className: "m-0 text-[var(--font-size-base)] leading-[var(--line-height-normal)] text-[var(--md-on-surface-variant)]", children: i })
80
+ ] }),
81
+ m && /* @__PURE__ */ n(
82
+ "button",
83
+ {
84
+ "aria-label": "Fechar modal",
85
+ className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-[var(--border-radius-md)] border-0 bg-[var(--md-surface-container-high)] text-[var(--md-on-surface)] transition-[var(--transition-all)] hover:bg-[color:color-mix(in_srgb,var(--md-error)_15%,var(--md-surface))] hover:text-[var(--md-error)]",
86
+ onClick: o,
87
+ type: "button",
88
+ children: /* @__PURE__ */ c(
89
+ "svg",
90
+ {
91
+ fill: "none",
92
+ className: "h-5 w-5",
93
+ stroke: "currentColor",
94
+ strokeWidth: "2",
95
+ viewBox: "0 0 24 24",
96
+ children: [
97
+ /* @__PURE__ */ n("line", { x1: "18", x2: "6", y1: "6", y2: "18" }),
98
+ /* @__PURE__ */ n("line", { x1: "6", x2: "18", y1: "6", y2: "18" })
99
+ ]
100
+ }
101
+ )
102
+ }
103
+ )
104
+ ] }),
105
+ /* @__PURE__ */ n("div", { className: "flex min-h-0 flex-1 flex-col overflow-x-hidden overflow-y-auto p-[var(--spacing-2xl)]", children: g })
106
+ ] })
107
+ }
108
+ );
109
+ };
110
+ export {
111
+ K as Modal
112
+ };
113
+ //# sourceMappingURL=Modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useRef } from 'react';\n\nexport interface ModalProps {\n children: React.ReactNode;\n className?: string;\n closeOnOverlayClick?: boolean;\n isOpen: boolean;\n onClose: () => void;\n showCloseButton?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n subtitle?: string;\n title?: string | React.ReactNode;\n}\n\nexport const Modal: React.FC<ModalProps> = ({\n isOpen,\n onClose,\n title,\n subtitle,\n children,\n size = 'md',\n showCloseButton = true,\n closeOnOverlayClick = true,\n className = '',\n}) => {\n const dialogRef = useRef<HTMLDivElement | null>(null);\n const lastFocusedElementRef = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (isOpen) {\n lastFocusedElementRef.current = document.activeElement as HTMLElement | null;\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = '';\n }\n return () => {\n document.body.style.overflow = '';\n if (lastFocusedElementRef.current) {\n lastFocusedElementRef.current.focus();\n }\n };\n }, [isOpen]);\n\n useEffect(() => {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen) {\n onClose();\n }\n };\n const handleTabTrap = (e: KeyboardEvent) => {\n if (e.key !== 'Tab' || !dialogRef.current || !isOpen) {\n return;\n }\n\n const focusable = dialogRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement as HTMLElement | null;\n\n if (e.shiftKey && active === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n if (isOpen) {\n document.addEventListener('keydown', handleEscape);\n document.addEventListener('keydown', handleTabTrap);\n requestAnimationFrame(() => {\n const initialTarget =\n dialogRef.current?.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n ) ?? dialogRef.current;\n initialTarget?.focus();\n });\n }\n return () => {\n document.removeEventListener('keydown', handleEscape);\n document.removeEventListener('keydown', handleTabTrap);\n };\n }, [isOpen, onClose]);\n\n if (!isOpen) {\n return null;\n }\n\n const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (closeOnOverlayClick && e.target === e.currentTarget) {\n onClose();\n }\n };\n\n const handleOverlayKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (\n closeOnOverlayClick &&\n (e.key === 'Enter' || e.key === ' ') &&\n e.target === e.currentTarget\n ) {\n onClose();\n }\n };\n\n const sizeClassMap: Record<NonNullable<ModalProps['size']>, string> = {\n sm: 'max-w-[25rem]',\n md: 'max-w-[31.25rem]',\n lg: 'max-w-[43.75rem]',\n xl: 'max-w-[56.25rem]',\n full: 'max-h-[90vh] max-w-[90vw]',\n };\n const combinedClass = [\n 'relative z-[var(--z-index-modal)] m-auto flex w-full max-h-[90vh] max-w-full flex-col overflow-hidden rounded-[var(--border-radius-2xl)] border border-[var(--md-outline-variant)] bg-[var(--md-surface)] shadow-[var(--shadow-2xl)]',\n sizeClassMap[size],\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div\n aria-labelledby={title ? 'modal-title' : undefined}\n aria-modal=\"true\"\n className=\"fixed inset-0 z-[var(--z-index-modal-backdrop)] flex min-h-[100dvh] items-center justify-center overflow-y-auto bg-black/50 p-[var(--spacing-lg)] backdrop-blur-[8px]\"\n onClick={handleOverlayClick}\n onKeyDown={handleOverlayKeyDown}\n role=\"dialog\"\n >\n <div className={combinedClass} ref={dialogRef} tabIndex={-1}>\n {(title || subtitle || showCloseButton) && (\n <div className=\"flex shrink-0 items-start justify-between gap-[var(--spacing-lg)] border-b border-[var(--md-outline-variant)] p-[var(--spacing-2xl)]\">\n {(title || subtitle) && (\n <div className=\"flex-1\">\n {title && (\n <h2\n className=\"mb-[var(--spacing-xs)] mt-0 text-[var(--font-size-2xl)] font-[var(--font-weight-semibold)] leading-[var(--line-height-tight)] text-[var(--md-on-surface)]\"\n id=\"modal-title\"\n >\n {title}\n </h2>\n )}\n {subtitle && (\n <p className=\"m-0 text-[var(--font-size-base)] leading-[var(--line-height-normal)] text-[var(--md-on-surface-variant)]\">\n {subtitle}\n </p>\n )}\n </div>\n )}\n {showCloseButton && (\n <button\n aria-label=\"Fechar modal\"\n className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-[var(--border-radius-md)] border-0 bg-[var(--md-surface-container-high)] text-[var(--md-on-surface)] transition-[var(--transition-all)] hover:bg-[color:color-mix(in_srgb,var(--md-error)_15%,var(--md-surface))] hover:text-[var(--md-error)]\"\n onClick={onClose}\n type=\"button\"\n >\n <svg\n fill=\"none\"\n className=\"h-5 w-5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <line x1=\"18\" x2=\"6\" y1=\"6\" y2=\"18\" />\n <line x1=\"6\" x2=\"18\" y1=\"6\" y2=\"18\" />\n </svg>\n </button>\n )}\n </div>\n )}\n <div className=\"flex min-h-0 flex-1 flex-col overflow-x-hidden overflow-y-auto p-[var(--spacing-2xl)]\">\n {children}\n </div>\n </div>\n </div>\n );\n};\n"],"names":["Modal","isOpen","onClose","title","subtitle","children","size","showCloseButton","closeOnOverlayClick","className","dialogRef","useRef","lastFocusedElementRef","useEffect","handleEscape","handleTabTrap","focusable","first","last","active","initialTarget","_a","handleOverlayClick","e","handleOverlayKeyDown","combinedClass","jsx","jsxs"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Modal } from './Modal';
3
+ declare const meta: Meta<typeof Modal>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof Modal>;
6
+ export declare const Playground: Story;
7
+ export declare const Sizes: Story;
8
+ export declare const WithForm: Story;
@@ -0,0 +1,26 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import { cn as a } from "../../utils/cn.js";
3
+ const s = ({ className: r, ...e }) => /* @__PURE__ */ o(
4
+ "aside",
5
+ {
6
+ className: a(
7
+ "h-full rounded-[var(--border-radius-lg)] border border-[var(--border-color)] bg-[var(--bg-secondary)] p-4",
8
+ r
9
+ ),
10
+ ...e
11
+ }
12
+ ), c = ({ className: r, ...e }) => /* @__PURE__ */ o(
13
+ "header",
14
+ {
15
+ className: a(
16
+ "flex min-h-14 items-center justify-between border-b border-[var(--border-color)] bg-[var(--bg-secondary)] px-4",
17
+ r
18
+ ),
19
+ ...e
20
+ }
21
+ );
22
+ export {
23
+ s as Sidebar,
24
+ c as Topbar
25
+ };
26
+ //# sourceMappingURL=Navigation.js.map
@@ -0,0 +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> {}\nexport const Sidebar: React.FC<SidebarProps> = ({ className, ...props }) => (\n <aside\n className={cn(\n 'h-full rounded-[var(--border-radius-lg)] border border-[var(--border-color)] bg-[var(--bg-secondary)] p-4',\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 border-b border-[var(--border-color)] bg-[var(--bg-secondary)] px-4',\n className,\n )}\n {...props}\n />\n);\n"],"names":["Sidebar","className","props","jsx","cn","Topbar"],"mappings":";;AAIO,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;"}
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'size' | 'onChange'> {
3
+ error?: string;
4
+ helperText?: string;
5
+ label?: string;
6
+ max?: number;
7
+ min?: number;
8
+ onChange?: (value: number | null) => void;
9
+ size?: 'sm' | 'md' | 'lg';
10
+ step?: number;
11
+ }
12
+ export declare const NumberInput: React.ForwardRefExoticComponent<NumberInputProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,135 @@
1
+ import { jsxs as N, jsx as o } from "react/jsx-runtime";
2
+ import _ from "react";
3
+ import { cn as l } from "../../utils/cn.js";
4
+ const M = _.forwardRef(
5
+ ({
6
+ label: x,
7
+ error: i,
8
+ helperText: v,
9
+ size: u = "md",
10
+ min: s,
11
+ max: n,
12
+ step: m = 1,
13
+ onChange: r,
14
+ className: w,
15
+ id: y,
16
+ value: b,
17
+ defaultValue: a,
18
+ disabled: c,
19
+ ...g
20
+ }, z) => {
21
+ const e = y || `number-input-${Math.random().toString(36).slice(2, 9)}`, p = !!i, $ = {
22
+ sm: "min-h-8 text-[var(--font-size-sm)]",
23
+ md: "min-h-10 text-[var(--font-size-base)]",
24
+ lg: "min-h-12 text-[var(--font-size-lg)]"
25
+ }, h = {
26
+ sm: "h-8 w-7 text-sm",
27
+ md: "h-10 w-8 text-base",
28
+ lg: "h-12 w-9 text-lg"
29
+ }, d = b !== void 0 ? Number(b) : void 0, j = () => {
30
+ const t = (d ?? (a !== void 0 ? Number(a) : 0)) - m;
31
+ (s === void 0 || t >= s) && (r == null || r(t));
32
+ }, k = () => {
33
+ const t = (d ?? (a !== void 0 ? Number(a) : 0)) + m;
34
+ (n === void 0 || t <= n) && (r == null || r(t));
35
+ }, I = (f) => {
36
+ const t = f.target.value;
37
+ r == null || r(t === "" ? null : Number(t));
38
+ };
39
+ return /* @__PURE__ */ N("div", { className: "flex flex-col gap-[var(--spacing-xs)]", children: [
40
+ x && /* @__PURE__ */ o(
41
+ "label",
42
+ {
43
+ className: "text-[var(--font-size-sm)] font-[var(--font-weight-semibold)] text-[var(--md-on-surface)]",
44
+ htmlFor: e,
45
+ children: x
46
+ }
47
+ ),
48
+ /* @__PURE__ */ N(
49
+ "div",
50
+ {
51
+ className: l(
52
+ "inline-flex overflow-hidden rounded-[var(--border-radius-md)] border border-[var(--md-outline-variant)] bg-[var(--md-surface)] transition focus-within:border-[var(--border-color-focus)] focus-within:[box-shadow:0_0_0_0.1875rem_rgba(47,93,140,0.15)]",
53
+ p && "border-[var(--md-error)] focus-within:border-[var(--md-error)]",
54
+ c && "cursor-not-allowed opacity-60"
55
+ ),
56
+ children: [
57
+ /* @__PURE__ */ o(
58
+ "button",
59
+ {
60
+ "aria-label": "Diminuir",
61
+ className: l(
62
+ "flex shrink-0 items-center justify-center border-r border-[var(--md-outline-variant)] bg-[var(--bg-tertiary)] text-[var(--text-secondary)] transition hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--border-color-focus)]",
63
+ h[u]
64
+ ),
65
+ disabled: c || s !== void 0 && (d ?? 0) <= s,
66
+ onClick: j,
67
+ type: "button",
68
+ children: "−"
69
+ }
70
+ ),
71
+ /* @__PURE__ */ o(
72
+ "input",
73
+ {
74
+ ref: z,
75
+ "aria-describedby": i ? `${e}-error` : v ? `${e}-helper` : void 0,
76
+ "aria-invalid": p ? !0 : void 0,
77
+ className: l(
78
+ "w-full min-w-0 bg-transparent px-3 text-center text-[var(--md-on-surface)] outline-none",
79
+ $[u],
80
+ w
81
+ ),
82
+ defaultValue: a,
83
+ disabled: c,
84
+ id: e,
85
+ max: n,
86
+ min: s,
87
+ step: m,
88
+ type: "number",
89
+ value: b,
90
+ onChange: I,
91
+ ...g
92
+ }
93
+ ),
94
+ /* @__PURE__ */ o(
95
+ "button",
96
+ {
97
+ "aria-label": "Aumentar",
98
+ className: l(
99
+ "flex shrink-0 items-center justify-center border-l border-[var(--md-outline-variant)] bg-[var(--bg-tertiary)] text-[var(--text-secondary)] transition hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--border-color-focus)]",
100
+ h[u]
101
+ ),
102
+ disabled: c || n !== void 0 && (d ?? 0) >= n,
103
+ onClick: k,
104
+ type: "button",
105
+ children: "+"
106
+ }
107
+ )
108
+ ]
109
+ }
110
+ ),
111
+ i && /* @__PURE__ */ o(
112
+ "span",
113
+ {
114
+ className: "text-[var(--font-size-xs)] text-[var(--md-error)]",
115
+ id: `${e}-error`,
116
+ role: "alert",
117
+ children: i
118
+ }
119
+ ),
120
+ v && !i && /* @__PURE__ */ o(
121
+ "span",
122
+ {
123
+ className: "text-[var(--font-size-xs)] text-[var(--md-on-surface-variant)]",
124
+ id: `${e}-helper`,
125
+ children: v
126
+ }
127
+ )
128
+ ] });
129
+ }
130
+ );
131
+ M.displayName = "NumberInput";
132
+ export {
133
+ M as NumberInput
134
+ };
135
+ //# sourceMappingURL=NumberInput.js.map