feat(lib-core): biblioteca atomica @pulse-libs/core v1.0.0-beta.1
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)
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import * as react_jsx_runtime from 'react/jsx-runtime';
|
||||
export { cn } from '../utils/index.mjs';
|
||||
|
||||
/**
|
||||
* Componentes atômicos — Receptor de className sempre no topo,
|
||||
* spread de props SEMPRE por último.
|
||||
*/
|
||||
type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'success';
|
||||
type ButtonSize = 'sm' | 'md' | 'lg';
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: ButtonVariant;
|
||||
size?: ButtonSize;
|
||||
loading?: boolean;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
}
|
||||
declare function Button({ className, variant, size, loading, leftIcon, rightIcon, children, disabled, ...rest }: ButtonProps): react_jsx_runtime.JSX.Element;
|
||||
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
label?: string;
|
||||
error?: string;
|
||||
hint?: string;
|
||||
}
|
||||
declare function Input({ className, label, error, hint, id, ...rest }: InputProps): react_jsx_runtime.JSX.Element;
|
||||
type AlertVariant = 'info' | 'success' | 'warning' | 'error';
|
||||
interface AlertProps {
|
||||
variant?: AlertVariant;
|
||||
title?: string;
|
||||
children: React.ReactNode;
|
||||
onClose?: () => void;
|
||||
}
|
||||
declare function Alert({ variant, title, children, onClose }: AlertProps): react_jsx_runtime.JSX.Element;
|
||||
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
declare const Card: React.FC<CardProps>;
|
||||
declare const CardHeader: React.FC<CardProps>;
|
||||
declare const CardTitle: React.FC<{
|
||||
children: React.ReactNode;
|
||||
}>;
|
||||
declare const CardBody: React.FC<CardProps>;
|
||||
declare function Spinner({ size, className }: {
|
||||
size?: number;
|
||||
className?: string;
|
||||
}): react_jsx_runtime.JSX.Element;
|
||||
|
||||
export { Alert, Button, Card, CardBody, CardHeader, CardTitle, Input, Spinner };
|
||||
@@ -0,0 +1,46 @@
|
||||
import * as react_jsx_runtime from 'react/jsx-runtime';
|
||||
export { cn } from '../utils/index.js';
|
||||
|
||||
/**
|
||||
* Componentes atômicos — Receptor de className sempre no topo,
|
||||
* spread de props SEMPRE por último.
|
||||
*/
|
||||
type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'success';
|
||||
type ButtonSize = 'sm' | 'md' | 'lg';
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: ButtonVariant;
|
||||
size?: ButtonSize;
|
||||
loading?: boolean;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
}
|
||||
declare function Button({ className, variant, size, loading, leftIcon, rightIcon, children, disabled, ...rest }: ButtonProps): react_jsx_runtime.JSX.Element;
|
||||
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
label?: string;
|
||||
error?: string;
|
||||
hint?: string;
|
||||
}
|
||||
declare function Input({ className, label, error, hint, id, ...rest }: InputProps): react_jsx_runtime.JSX.Element;
|
||||
type AlertVariant = 'info' | 'success' | 'warning' | 'error';
|
||||
interface AlertProps {
|
||||
variant?: AlertVariant;
|
||||
title?: string;
|
||||
children: React.ReactNode;
|
||||
onClose?: () => void;
|
||||
}
|
||||
declare function Alert({ variant, title, children, onClose }: AlertProps): react_jsx_runtime.JSX.Element;
|
||||
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
declare const Card: React.FC<CardProps>;
|
||||
declare const CardHeader: React.FC<CardProps>;
|
||||
declare const CardTitle: React.FC<{
|
||||
children: React.ReactNode;
|
||||
}>;
|
||||
declare const CardBody: React.FC<CardProps>;
|
||||
declare function Spinner({ size, className }: {
|
||||
size?: number;
|
||||
className?: string;
|
||||
}): react_jsx_runtime.JSX.Element;
|
||||
|
||||
export { Alert, Button, Card, CardBody, CardHeader, CardTitle, Input, Spinner };
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
"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
|
||||
File diff suppressed because one or more lines are too long
+112
@@ -0,0 +1,112 @@
|
||||
import {
|
||||
cn
|
||||
} from "../chunk-RL4ANBQD.mjs";
|
||||
|
||||
// src/components/index.tsx
|
||||
import { jsx, jsxs } from "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__ */ 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__ */ 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__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
||||
label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "text-sm font-medium text-gray-700", children: label }),
|
||||
/* @__PURE__ */ 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__ */ jsx("span", { className: "text-xs text-red-500", children: error }),
|
||||
hint && !error && /* @__PURE__ */ 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__ */ jsxs("div", { className: cn("flex items-start gap-2 rounded-lg border px-4 py-3", s.container), children: [
|
||||
/* @__PURE__ */ jsx("span", { className: "text-base leading-none", children: s.icon }),
|
||||
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
||||
title && /* @__PURE__ */ jsx("p", { className: "font-semibold text-sm", children: title }),
|
||||
/* @__PURE__ */ jsx("p", { className: "text-sm", children })
|
||||
] }),
|
||||
onClose && /* @__PURE__ */ jsx("button", { onClick: onClose, className: "ml-auto text-lg leading-none opacity-50 hover:opacity-100", children: "\xD7" })
|
||||
] });
|
||||
}
|
||||
var Card = ({ className, children, ...rest }) => /* @__PURE__ */ jsx("div", { className: cn("rounded-xl border border-gray-200 bg-white shadow-sm", className), ...rest, children });
|
||||
var CardHeader = ({ className, children, ...rest }) => /* @__PURE__ */ jsx("div", { className: cn("px-5 py-4 border-b border-gray-100", className), ...rest, children });
|
||||
var CardTitle = ({ children }) => /* @__PURE__ */ jsx("h3", { className: "font-semibold text-gray-900 text-base", children });
|
||||
var CardBody = ({ className, children, ...rest }) => /* @__PURE__ */ jsx("div", { className: cn("px-5 py-4", className), ...rest, children });
|
||||
function Spinner({ size = 16, className = "" }) {
|
||||
return /* @__PURE__ */ jsxs("svg", { className: cn("animate-spin", className), width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: [
|
||||
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
||||
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
||||
] });
|
||||
}
|
||||
export {
|
||||
Alert,
|
||||
Button,
|
||||
Card,
|
||||
CardBody,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
Input,
|
||||
Spinner,
|
||||
cn
|
||||
};
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user