@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.
- package/README.md +115 -115
- package/dist/components/Accordion/Accordion.js +56 -0
- package/dist/components/Accordion/Accordion.js.map +1 -0
- package/dist/components/Accordion/Accordion.stories.d.ts +7 -0
- package/dist/components/Alert/Alert.js +32 -0
- package/dist/components/Alert/Alert.js.map +1 -0
- package/dist/components/Alert/Alert.stories.d.ts +8 -0
- package/dist/components/Badge/Badge.js +35 -0
- package/dist/components/Badge/Badge.js.map +1 -0
- package/dist/components/Badge/Badge.stories.d.ts +8 -0
- package/dist/components/Breadcrumb/Breadcrumb.d.ts +10 -0
- package/dist/components/Breadcrumb/Breadcrumb.js +26 -0
- package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -0
- package/dist/components/Breadcrumb/Breadcrumb.stories.d.ts +8 -0
- package/dist/components/Button/Button.js +122 -0
- package/dist/components/Button/Button.js.map +1 -0
- package/dist/components/Card/Card.js +33 -0
- package/dist/components/Card/Card.js.map +1 -0
- package/dist/components/Card/Card.stories.d.ts +8 -0
- package/dist/components/Checkbox/Checkbox.d.ts +2 -2
- package/dist/components/Checkbox/Checkbox.js +36 -0
- package/dist/components/Checkbox/Checkbox.js.map +1 -0
- package/dist/components/Checkbox/Checkbox.stories.d.ts +7 -0
- package/dist/components/Chip/Chip.js +19 -0
- package/dist/components/Chip/Chip.js.map +1 -0
- package/dist/components/Combobox/Combobox.d.ts +17 -0
- package/dist/components/Combobox/Combobox.js +143 -0
- package/dist/components/Combobox/Combobox.js.map +1 -0
- package/dist/components/Combobox/Combobox.stories.d.ts +9 -0
- package/dist/components/Divider/Divider.js +22 -0
- package/dist/components/Divider/Divider.js.map +1 -0
- package/dist/components/EmptyState/EmptyState.js +29 -0
- package/dist/components/EmptyState/EmptyState.js.map +1 -0
- package/dist/components/FileUpload/FileUpload.d.ts +13 -0
- package/dist/components/FileUpload/FileUpload.js +116 -0
- package/dist/components/FileUpload/FileUpload.js.map +1 -0
- package/dist/components/FileUpload/FileUpload.stories.d.ts +10 -0
- package/dist/components/Footer/Footer.js +54 -0
- package/dist/components/Footer/Footer.js.map +1 -0
- package/dist/components/Header/Header.js +114 -0
- package/dist/components/Header/Header.js.map +1 -0
- package/dist/components/Input/Input.d.ts +2 -2
- package/dist/components/Input/Input.js +78 -0
- package/dist/components/Input/Input.js.map +1 -0
- package/dist/components/Input/Input.stories.d.ts +9 -0
- package/dist/components/Layout/Layout.js +41 -0
- package/dist/components/Layout/Layout.js.map +1 -0
- package/dist/components/Modal/Modal.js +113 -0
- package/dist/components/Modal/Modal.js.map +1 -0
- package/dist/components/Modal/Modal.stories.d.ts +8 -0
- package/dist/components/Navigation/Navigation.js +26 -0
- package/dist/components/Navigation/Navigation.js.map +1 -0
- package/dist/components/NumberInput/NumberInput.d.ts +12 -0
- package/dist/components/NumberInput/NumberInput.js +135 -0
- package/dist/components/NumberInput/NumberInput.js.map +1 -0
- package/dist/components/NumberInput/NumberInput.stories.d.ts +8 -0
- package/dist/components/PageHeader/PageHeader.js +29 -0
- package/dist/components/PageHeader/PageHeader.js.map +1 -0
- package/dist/components/Pagination/Pagination.js +50 -0
- package/dist/components/Pagination/Pagination.js.map +1 -0
- package/dist/components/Pagination/Pagination.stories.d.ts +8 -0
- package/dist/components/Paragraph/Paragraph.js +41 -0
- package/dist/components/Paragraph/Paragraph.js.map +1 -0
- package/dist/components/Popover/Popover.js +57 -0
- package/dist/components/Popover/Popover.js.map +1 -0
- package/dist/components/Radio/Radio.d.ts +2 -2
- package/dist/components/Radio/Radio.js +36 -0
- package/dist/components/Radio/Radio.js.map +1 -0
- package/dist/components/Radio/Radio.stories.d.ts +7 -0
- package/dist/components/SectionHeader/SectionHeader.js +19 -0
- package/dist/components/SectionHeader/SectionHeader.js.map +1 -0
- package/dist/components/Select/Select.d.ts +2 -2
- package/dist/components/Select/Select.js +45 -0
- package/dist/components/Select/Select.js.map +1 -0
- package/dist/components/Select/Select.stories.d.ts +8 -0
- package/dist/components/Skeleton/Skeleton.js +25 -0
- package/dist/components/Skeleton/Skeleton.js.map +1 -0
- package/dist/components/Stepper/Stepper.d.ts +13 -0
- package/dist/components/Stepper/Stepper.js +97 -0
- package/dist/components/Stepper/Stepper.js.map +1 -0
- package/dist/components/Stepper/Stepper.stories.d.ts +8 -0
- package/dist/components/Subtitle/Subtitle.js +40 -0
- package/dist/components/Subtitle/Subtitle.js.map +1 -0
- package/dist/components/Switch/Switch.d.ts +2 -2
- package/dist/components/Switch/Switch.js +37 -0
- package/dist/components/Switch/Switch.js.map +1 -0
- package/dist/components/Switch/Switch.stories.d.ts +8 -0
- package/dist/components/Table/Table.js +17 -0
- package/dist/components/Table/Table.js.map +1 -0
- package/dist/components/Tabs/Tabs.js +62 -0
- package/dist/components/Tabs/Tabs.js.map +1 -0
- package/dist/components/Tabs/Tabs.stories.d.ts +8 -0
- package/dist/components/Tag/Tag.js +29 -0
- package/dist/components/Tag/Tag.js.map +1 -0
- package/dist/components/Textarea/Textarea.d.ts +2 -2
- package/dist/components/Textarea/Textarea.js +46 -0
- package/dist/components/Textarea/Textarea.js.map +1 -0
- package/dist/components/Textarea/Textarea.stories.d.ts +7 -0
- package/dist/components/Title/Title.js +47 -0
- package/dist/components/Title/Title.js.map +1 -0
- package/dist/components/Toast/Toast.js +110 -0
- package/dist/components/Toast/Toast.js.map +1 -0
- package/dist/components/Toast/Toast.stories.d.ts +8 -0
- package/dist/components/Tooltip/Tooltip.js +36 -0
- package/dist/components/Tooltip/Tooltip.js.map +1 -0
- package/dist/index.d.ts +10 -5
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/dist/oficios-ui.css +1 -1
- package/dist/oficios-ui.umd.cjs +1 -1
- package/dist/oficios-ui.umd.cjs.map +1 -1
- package/dist/theme/ThemeProvider.d.ts +1 -1
- package/dist/theme/ThemeProvider.js +22 -0
- package/dist/theme/ThemeProvider.js.map +1 -0
- package/dist/theme.css +54 -64
- package/dist/utils/cn.d.ts +7 -1
- package/dist/utils/cn.js +7 -0
- package/dist/utils/cn.js.map +1 -0
- package/package.json +50 -15
- package/dist/oficios-ui.js +0 -1386
- 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
|
|
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.
|
|
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
|