chore(release): snapshot 1.4.2
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { ButtonHTMLAttributes, forwardRef } from "react";
|
||||
import { ButtonHTMLAttributes, forwardRef, ReactNode } from "react";
|
||||
|
||||
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: "primary" | "secondary" | "outline" | "ghost";
|
||||
size?: "sm" | "md" | "lg";
|
||||
isLoading?: boolean;
|
||||
leftIcon?: string;
|
||||
rightIcon?: string;
|
||||
leftIcon?: string | ReactNode;
|
||||
rightIcon?: string | ReactNode;
|
||||
}
|
||||
|
||||
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
@@ -55,11 +55,19 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
<i className="ri-loader-4-line animate-spin mr-2 text-[20px]" />
|
||||
)}
|
||||
{!isLoading && leftIcon && (
|
||||
<i className={`${leftIcon} mr-2 text-[20px]`} />
|
||||
typeof leftIcon === 'string' ? (
|
||||
<i className={`${leftIcon} mr-2 text-[20px]`} />
|
||||
) : (
|
||||
<div className="w-5 h-5 mr-2">{leftIcon}</div>
|
||||
)
|
||||
)}
|
||||
{children}
|
||||
{!isLoading && rightIcon && (
|
||||
<i className={`${rightIcon} ml-2 text-[20px]`} />
|
||||
typeof rightIcon === 'string' ? (
|
||||
<i className={`${rightIcon} ml-2 text-[20px]`} />
|
||||
) : (
|
||||
<div className="w-5 h-5 ml-2">{rightIcon}</div>
|
||||
)
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { InputHTMLAttributes, forwardRef, useState, ReactNode } from "react";
|
||||
import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline';
|
||||
|
||||
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
||||
label?: string;
|
||||
error?: string;
|
||||
helperText?: ReactNode;
|
||||
leftIcon?: string;
|
||||
rightIcon?: string;
|
||||
leftIcon?: string | ReactNode;
|
||||
rightIcon?: string | ReactNode;
|
||||
onRightIconClick?: () => void;
|
||||
}
|
||||
|
||||
@@ -41,9 +42,13 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
)}
|
||||
<div className="relative">
|
||||
{leftIcon && (
|
||||
<i
|
||||
className={`${leftIcon} absolute left-3.5 top-1/2 -translate-y-1/2 text-[#7D7D7D] dark:text-gray-400 text-[20px]`}
|
||||
/>
|
||||
<div className="absolute left-3.5 top-1/2 -translate-y-1/2 text-zinc-400 dark:text-gray-400">
|
||||
{typeof leftIcon === 'string' ? (
|
||||
<i className={`${leftIcon} text-[20px]`} />
|
||||
) : (
|
||||
<div className="w-5 h-5">{leftIcon}</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
ref={ref}
|
||||
@@ -69,21 +74,23 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
className="absolute right-3.5 top-1/2 -translate-y-1/2 text-zinc-500 hover:text-zinc-900 transition-colors cursor-pointer"
|
||||
className="absolute right-3.5 top-1/2 -translate-y-1/2 text-zinc-500 hover:text-zinc-900 dark:text-gray-400 dark:hover:text-white transition-colors cursor-pointer"
|
||||
>
|
||||
<i
|
||||
className={`${showPassword ? "ri-eye-off-line" : "ri-eye-line"} text-[20px]`}
|
||||
/>
|
||||
{showPassword ? (
|
||||
<EyeSlashIcon className="w-5 h-5" />
|
||||
) : (
|
||||
<EyeIcon className="w-5 h-5" />
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{!isPassword && rightIcon && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onRightIconClick}
|
||||
className="absolute right-3.5 top-1/2 -translate-y-1/2 text-zinc-500 hover:text-zinc-900 transition-colors cursor-pointer"
|
||||
>
|
||||
<i className={`${rightIcon} text-[20px]`} />
|
||||
</button>
|
||||
<div className="absolute right-3.5 top-1/2 -translate-y-1/2 text-zinc-400 dark:text-gray-400">
|
||||
{typeof rightIcon === 'string' ? (
|
||||
<i className={`${rightIcon} text-[20px]`} />
|
||||
) : (
|
||||
<div className="w-5 h-5">{rightIcon}</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{error && (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { SelectHTMLAttributes, forwardRef, useState, useRef, useEffect } from "react";
|
||||
import { SelectHTMLAttributes, forwardRef, useState, useRef, useEffect, ReactNode } from "react";
|
||||
|
||||
interface SelectOption {
|
||||
value: string;
|
||||
@@ -11,7 +11,7 @@ interface SearchableSelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElem
|
||||
label?: string;
|
||||
error?: string;
|
||||
helperText?: string;
|
||||
leftIcon?: string;
|
||||
leftIcon?: string | ReactNode;
|
||||
options: SelectOption[];
|
||||
placeholder?: string;
|
||||
onChange?: (value: string) => void;
|
||||
@@ -115,9 +115,13 @@ const SearchableSelect = forwardRef<HTMLSelectElement, SearchableSelectProps>(
|
||||
|
||||
<div ref={containerRef} className="relative">
|
||||
{leftIcon && (
|
||||
<i
|
||||
className={`${leftIcon} absolute left-3.5 top-1/2 -translate-y-1/2 text-zinc-500 dark:text-zinc-400 text-[20px] pointer-events-none z-10`}
|
||||
/>
|
||||
<div className="absolute left-3.5 top-1/2 -translate-y-1/2 text-zinc-400 dark:text-gray-400 pointer-events-none z-10">
|
||||
{typeof leftIcon === 'string' ? (
|
||||
<i className={`${leftIcon} text-[20px]`} />
|
||||
) : (
|
||||
<div className="w-5 h-5">{leftIcon}</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Custom trigger */}
|
||||
|
||||
102
front-end-dash.aggios.app/components/ui/Tabs.tsx
Normal file
102
front-end-dash.aggios.app/components/ui/Tabs.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
'use client';
|
||||
|
||||
import { Tab } from '@headlessui/react';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
function classNames(...classes: string[]) {
|
||||
return classes.filter(Boolean).join(' ');
|
||||
}
|
||||
|
||||
export interface TabItem {
|
||||
name: string;
|
||||
icon?: React.ComponentType<{ className?: string }>;
|
||||
content: ReactNode;
|
||||
}
|
||||
|
||||
interface TabsProps {
|
||||
tabs: TabItem[];
|
||||
defaultIndex?: number;
|
||||
onChange?: (index: number) => void;
|
||||
variant?: 'card' | 'modal'; // Novo: variante para diferentes contextos
|
||||
}
|
||||
|
||||
export default function Tabs({ tabs, defaultIndex = 0, onChange, variant = 'card' }: TabsProps) {
|
||||
if (variant === 'modal') {
|
||||
// Versão para modais - sem card wrapper
|
||||
return (
|
||||
<Tab.Group defaultIndex={defaultIndex} onChange={onChange}>
|
||||
<Tab.List className="flex border-b border-zinc-200 dark:border-zinc-700 px-6">
|
||||
{tabs.map((tab) => (
|
||||
<Tab
|
||||
key={tab.name}
|
||||
className={({ selected }) =>
|
||||
classNames(
|
||||
'px-4 py-3 text-sm font-medium border-b-2 transition-colors focus:outline-none whitespace-nowrap',
|
||||
selected
|
||||
? 'border-[var(--brand-color)] text-[var(--brand-color)]'
|
||||
: 'border-transparent text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300'
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
{tab.icon && <tab.icon className="w-4 h-4 flex-shrink-0" />}
|
||||
{tab.name}
|
||||
</div>
|
||||
</Tab>
|
||||
))}
|
||||
</Tab.List>
|
||||
|
||||
<Tab.Panels className="p-6">
|
||||
{tabs.map((tab, idx) => (
|
||||
<Tab.Panel
|
||||
key={idx}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
{tab.content}
|
||||
</Tab.Panel>
|
||||
))}
|
||||
</Tab.Panels>
|
||||
</Tab.Group>
|
||||
);
|
||||
}
|
||||
|
||||
// Versão padrão para páginas - com card wrapper
|
||||
return (
|
||||
<Tab.Group defaultIndex={defaultIndex} onChange={onChange}>
|
||||
<div className="bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-800 overflow-hidden">
|
||||
<Tab.List className="flex space-x-1 rounded-t-xl bg-zinc-100 dark:bg-zinc-800/50 p-1 overflow-x-auto scrollbar-hide">
|
||||
{tabs.map((tab) => (
|
||||
<Tab
|
||||
key={tab.name}
|
||||
className={({ selected }) =>
|
||||
classNames(
|
||||
'w-full rounded-lg py-2 sm:py-2.5 px-3 sm:px-4 text-xs sm:text-sm font-medium leading-5 transition-all duration-200 whitespace-nowrap',
|
||||
'focus:outline-none',
|
||||
selected
|
||||
? 'bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white shadow'
|
||||
: 'text-zinc-500 hover:bg-white/[0.12] hover:text-zinc-700 dark:hover:text-zinc-300'
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="flex items-center justify-center gap-1.5 sm:gap-2">
|
||||
{tab.icon && <tab.icon className="w-3.5 h-3.5 sm:w-4 sm:h-4 flex-shrink-0" />}
|
||||
{tab.name}
|
||||
</div>
|
||||
</Tab>
|
||||
))}
|
||||
</Tab.List>
|
||||
|
||||
<Tab.Panels className="p-4 sm:p-6">
|
||||
{tabs.map((tab, idx) => (
|
||||
<Tab.Panel
|
||||
key={idx}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
{tab.content}
|
||||
</Tab.Panel>
|
||||
))}
|
||||
</Tab.Panels>
|
||||
</div>
|
||||
</Tab.Group>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user