bbdb68a6de
Esta commit conteudo a estrutura atomica completa:
- types: Result<T,E>, AsyncState<T>, Paginated<T>, SortConfig<T>
- utils: date, str, num, cn, debounce, throttle, storage, arr, obj
- validators: Zod schemas — email, password, uuid, url, phone, CPF/CNPJ, sanitizedStr, safeParse
- hooks: useToggle, useAsync, useDebounce, useLocalStorage, useMedia, useInterval, useOnClickOutside, useClipboard, useFetch
- components: Button, Input, Alert, Card, Spinner (atomic design pattern)
- build: tsup v8 ESM+CJS + DTS + sourcemaps — 0 erros
- tests: 57 testes 100% usuarios
- docker: multi-stage Dockerfile (node 20-alpine)
- config: vitest, tsup, tsconfig strict, .npmignore
Filosofia atomica:/utils ← /types ← /validators ← /hooks ← /components
Build: npm run build | Test: npm test | Publish: npm publish
🤖 Generated with Pulse (openclaw + nova-self-improver)
149 lines
6.6 KiB
JavaScript
149 lines
6.6 KiB
JavaScript
"use strict";
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
|
|
// src/components/index.tsx
|
|
var components_exports = {};
|
|
__export(components_exports, {
|
|
Alert: () => Alert,
|
|
Button: () => Button,
|
|
Card: () => Card,
|
|
CardBody: () => CardBody,
|
|
CardHeader: () => CardHeader,
|
|
CardTitle: () => CardTitle,
|
|
Input: () => Input,
|
|
Spinner: () => Spinner,
|
|
cn: () => cn
|
|
});
|
|
module.exports = __toCommonJS(components_exports);
|
|
|
|
// src/utils/index.ts
|
|
var CLEAN_CLASSES_REGEX = /\s+/g;
|
|
function cn(...inputs) {
|
|
return inputs.flat(2).filter(Boolean).join(" ").replace(CLEAN_CLASSES_REGEX, " ").trim();
|
|
}
|
|
|
|
// src/components/index.tsx
|
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
var variantStyles = {
|
|
primary: "bg-indigo-600 text-white hover:bg-indigo-700 active:bg-indigo-800 disabled:bg-indigo-300",
|
|
secondary: "border border-gray-300 text-gray-700 bg-white hover:bg-gray-50 active:bg-gray-100",
|
|
ghost: "text-gray-600 hover:bg-gray-100 active:bg-gray-200",
|
|
danger: "bg-red-600 text-white hover:bg-red-700 active:bg-red-800",
|
|
success: "bg-emerald-600 text-white hover:bg-emerald-700 active:bg-emerald-800"
|
|
};
|
|
var sizeStyles = {
|
|
sm: "px-2.5 py-1 text-xs rounded",
|
|
md: "px-4 py-2 text-sm rounded-md",
|
|
lg: "px-6 py-3 text-base rounded-lg"
|
|
};
|
|
function Button({
|
|
className,
|
|
variant = "primary",
|
|
size = "md",
|
|
loading,
|
|
leftIcon,
|
|
rightIcon,
|
|
children,
|
|
disabled,
|
|
...rest
|
|
}) {
|
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
"button",
|
|
{
|
|
className: cn(
|
|
"inline-flex items-center justify-center gap-2 font-medium transition-colors",
|
|
"focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2",
|
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
variantStyles[variant],
|
|
sizeStyles[size],
|
|
className
|
|
),
|
|
disabled: disabled || loading,
|
|
...rest,
|
|
children: [
|
|
loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { size: 16 }) : leftIcon ?? null,
|
|
children,
|
|
!loading && rightIcon
|
|
]
|
|
}
|
|
);
|
|
}
|
|
function Input({ className, label, error, hint, id, ...rest }) {
|
|
const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
|
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: inputId, className: "text-sm font-medium text-gray-700", children: label }),
|
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
"input",
|
|
{
|
|
id: inputId,
|
|
className: cn(
|
|
"w-full rounded-md border border-gray-300 px-3 py-2 text-sm",
|
|
"placeholder:text-gray-400",
|
|
"focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500",
|
|
"disabled:bg-gray-100 disabled:cursor-not-allowed",
|
|
error && "border-red-500 focus:ring-red-500 focus:border-red-500",
|
|
className
|
|
),
|
|
...rest
|
|
}
|
|
),
|
|
error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs text-red-500", children: error }),
|
|
hint && !error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs text-gray-400", children: hint })
|
|
] });
|
|
}
|
|
var alertStyles = {
|
|
info: { container: "bg-blue-50 border-blue-200 text-blue-800", icon: "\u2139\uFE0F" },
|
|
success: { container: "bg-emerald-50 border-emerald-200 text-emerald-800", icon: "\u2705" },
|
|
warning: { container: "bg-amber-50 border-amber-200 text-amber-800", icon: "\u26A0\uFE0F" },
|
|
error: { container: "bg-red-50 border-red-200 text-red-800", icon: "\u274C" }
|
|
};
|
|
function Alert({ variant = "info", title, children, onClose }) {
|
|
const s = alertStyles[variant];
|
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cn("flex items-start gap-2 rounded-lg border px-4 py-3", s.container), children: [
|
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-base leading-none", children: s.icon }),
|
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex-1", children: [
|
|
title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "font-semibold text-sm", children: title }),
|
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm", children })
|
|
] }),
|
|
onClose && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: onClose, className: "ml-auto text-lg leading-none opacity-50 hover:opacity-100", children: "\xD7" })
|
|
] });
|
|
}
|
|
var Card = ({ className, children, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("rounded-xl border border-gray-200 bg-white shadow-sm", className), ...rest, children });
|
|
var CardHeader = ({ className, children, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("px-5 py-4 border-b border-gray-100", className), ...rest, children });
|
|
var CardTitle = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "font-semibold text-gray-900 text-base", children });
|
|
var CardBody = ({ className, children, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("px-5 py-4", className), ...rest, children });
|
|
function Spinner({ size = 16, className = "" }) {
|
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { className: cn("animate-spin", className), width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: [
|
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
] });
|
|
}
|
|
// Annotate the CommonJS export names for ESM import in node:
|
|
0 && (module.exports = {
|
|
Alert,
|
|
Button,
|
|
Card,
|
|
CardBody,
|
|
CardHeader,
|
|
CardTitle,
|
|
Input,
|
|
Spinner,
|
|
cn
|
|
});
|
|
//# sourceMappingURL=index.js.map
|