[WEB-5459] feat(codemods): add function declaration transformer with tests (#8137)
- Add jscodeshift-based codemod to convert arrow function components to function declarations - Support React.FC, observer-wrapped, and forwardRef components - Include comprehensive test suite covering edge cases - Add npm script to run transformer across codebase - Target only .tsx files in source directories, excluding node_modules and declaration files * [WEB-5459] chore: updates after running codemod --------- Co-authored-by: sriramveeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
parent
90866fb925
commit
83fdebf64d
1771 changed files with 17003 additions and 13856 deletions
|
|
@ -15,7 +15,7 @@ export interface AuthConfirmPasswordInputProps
|
|||
onPasswordMatchChange?: (matches: boolean) => void;
|
||||
}
|
||||
|
||||
export const AuthConfirmPasswordInput: React.FC<AuthConfirmPasswordInputProps> = ({
|
||||
export function AuthConfirmPasswordInput({
|
||||
password,
|
||||
label = "Confirm Password",
|
||||
error,
|
||||
|
|
@ -27,7 +27,7 @@ export const AuthConfirmPasswordInput: React.FC<AuthConfirmPasswordInputProps> =
|
|||
onChange,
|
||||
onPasswordMatchChange,
|
||||
...props
|
||||
}) => {
|
||||
}: AuthConfirmPasswordInputProps) {
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
|
||||
const confirmPassword = value as string;
|
||||
|
|
@ -74,4 +74,4 @@ export const AuthConfirmPasswordInput: React.FC<AuthConfirmPasswordInputProps> =
|
|||
{confirmPassword && passwordsMatch && <p className="text-sm text-green-500">Passwords match</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ export interface AuthForgotPasswordProps {
|
|||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const AuthForgotPassword: React.FC<AuthForgotPasswordProps> = ({
|
||||
export function AuthForgotPassword({
|
||||
onForgotPassword,
|
||||
className = "",
|
||||
text = "Forgot your password?",
|
||||
disabled = false,
|
||||
}) => {
|
||||
}: AuthForgotPasswordProps) {
|
||||
const handleClick = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
if (!disabled && onForgotPassword) {
|
||||
|
|
@ -38,4 +38,4 @@ export const AuthForgotPassword: React.FC<AuthForgotPasswordProps> = ({
|
|||
{text}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export interface AuthFormProps {
|
|||
alternateModeButtonText?: string;
|
||||
}
|
||||
|
||||
export const AuthForm: React.FC<AuthFormProps> = ({
|
||||
export function AuthForm({
|
||||
mode,
|
||||
initialData = {},
|
||||
onSubmit,
|
||||
|
|
@ -52,7 +52,7 @@ export const AuthForm: React.FC<AuthFormProps> = ({
|
|||
submitButtonText,
|
||||
alternateModeText,
|
||||
alternateModeButtonText,
|
||||
}) => {
|
||||
}: AuthFormProps) {
|
||||
const [formData, setFormData] = useState<AuthFormData>({
|
||||
email: initialData.email || "",
|
||||
password: initialData.password || "",
|
||||
|
|
@ -204,4 +204,4 @@ export const AuthForm: React.FC<AuthFormProps> = ({
|
|||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export interface AuthInputProps extends Omit<React.InputHTMLAttributes<HTMLInput
|
|||
|
||||
const baseContainerClassName = "flex flex-col gap-1.5";
|
||||
|
||||
export const AuthInput: React.FC<AuthInputProps> = ({
|
||||
export function AuthInput({
|
||||
label,
|
||||
error,
|
||||
showPasswordToggle = false,
|
||||
|
|
@ -21,7 +21,7 @@ export const AuthInput: React.FC<AuthInputProps> = ({
|
|||
className = "",
|
||||
type = "text",
|
||||
...props
|
||||
}) => {
|
||||
}: AuthInputProps) {
|
||||
const { id } = props;
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const isPasswordType = type === "password";
|
||||
|
|
@ -63,4 +63,4 @@ export const AuthInput: React.FC<AuthInputProps> = ({
|
|||
{error && <p className={cn("text-sm text-red-500", errorClassName)}>{error}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export interface AuthPasswordInputProps extends Omit<React.InputHTMLAttributes<H
|
|||
onPasswordStrengthChange?: (strength: E_PASSWORD_STRENGTH) => void;
|
||||
}
|
||||
|
||||
export const AuthPasswordInput: React.FC<AuthPasswordInputProps> = ({
|
||||
export function AuthPasswordInput({
|
||||
label = "Password",
|
||||
error,
|
||||
showPasswordStrength = true,
|
||||
|
|
@ -29,7 +29,7 @@ export const AuthPasswordInput: React.FC<AuthPasswordInputProps> = ({
|
|||
onPasswordChange,
|
||||
onPasswordStrengthChange,
|
||||
...props
|
||||
}) => {
|
||||
}: AuthPasswordInputProps) {
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
|
|
@ -74,4 +74,4 @@ export const AuthPasswordInput: React.FC<AuthPasswordInputProps> = ({
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ type Props = {
|
|||
size?: TAvatarSize;
|
||||
};
|
||||
|
||||
export const AvatarGroup: React.FC<Props> = (props) => {
|
||||
export function AvatarGroup(props: Props) {
|
||||
const { children, max = 2, showTooltip = true, size = "md" } = props;
|
||||
|
||||
// calculate total length of avatars inside the group
|
||||
|
|
@ -88,4 +88,4 @@ export const AvatarGroup: React.FC<Props> = (props) => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ export const getBorderRadius = (shape: "circle" | "square") => {
|
|||
*/
|
||||
export const isAValidNumber = (value: any) => typeof value === "number" && !isNaN(value);
|
||||
|
||||
export const Avatar: React.FC<Props> = (props) => {
|
||||
export function Avatar(props: Props) {
|
||||
const {
|
||||
name,
|
||||
fallbackBackgroundColor,
|
||||
|
|
@ -166,4 +166,4 @@ export const Avatar: React.FC<Props> = (props) => {
|
|||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export interface BadgeProps extends React.ButtonHTMLAttributes<HTMLButtonElement
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Badge = React.forwardRef<HTMLButtonElement, BadgeProps>((props, ref) => {
|
||||
const Badge = React.forwardRef(function Badge(props: BadgeProps, ref: React.ForwardedRef<HTMLButtonElement>) {
|
||||
const {
|
||||
variant = "primary",
|
||||
size = "md",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ type TBreadcrumbBlockProps = {
|
|||
};
|
||||
|
||||
// TODO: remove this component and use web Link component
|
||||
const BreadcrumbBlock: React.FC<TBreadcrumbBlockProps> = (props) => {
|
||||
function BreadcrumbBlock(props: TBreadcrumbBlockProps) {
|
||||
const { label, icon, disableTooltip = false } = props;
|
||||
|
||||
return (
|
||||
|
|
@ -30,7 +30,7 @@ const BreadcrumbBlock: React.FC<TBreadcrumbBlockProps> = (props) => {
|
|||
</Breadcrumbs.ItemWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Breadcrumbs>;
|
||||
|
|
|
|||
|
|
@ -10,16 +10,18 @@ type BreadcrumbsProps = {
|
|||
isLoading?: boolean;
|
||||
};
|
||||
|
||||
export const BreadcrumbItemLoader = () => (
|
||||
<div className="flex items-center gap-2 h-7 animate-pulse">
|
||||
<div className="group h-full flex items-center gap-2 rounded px-2 py-1 text-sm font-medium">
|
||||
<span className="h-full w-5 bg-custom-background-80 rounded" />
|
||||
<span className="h-full w-16 bg-custom-background-80 rounded" />
|
||||
export function BreadcrumbItemLoader() {
|
||||
return (
|
||||
<div className="flex items-center gap-2 h-7 animate-pulse">
|
||||
<div className="group h-full flex items-center gap-2 rounded px-2 py-1 text-sm font-medium">
|
||||
<span className="h-full w-5 bg-custom-background-80 rounded" />
|
||||
<span className="h-full w-16 bg-custom-background-80 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
const Breadcrumbs = ({ className, children, onBack, isLoading = false }: BreadcrumbsProps) => {
|
||||
function Breadcrumbs({ className, children, onBack, isLoading = false }: BreadcrumbsProps) {
|
||||
const [isSmallScreen, setIsSmallScreen] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
|
@ -82,7 +84,7 @@ const Breadcrumbs = ({ className, children, onBack, isLoading = false }: Breadcr
|
|||
{isSmallScreen && childrenArray.length === 1 && childrenArray}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// breadcrumb item
|
||||
type BreadcrumbItemProps = {
|
||||
|
|
@ -91,7 +93,7 @@ type BreadcrumbItemProps = {
|
|||
isLast?: boolean;
|
||||
};
|
||||
|
||||
const BreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) => {
|
||||
function BreadcrumbItem(props: BreadcrumbItemProps) {
|
||||
const { component, showSeparator = true, isLast = false } = props;
|
||||
return (
|
||||
<div className="flex items-center gap-0.5 h-6">
|
||||
|
|
@ -99,7 +101,7 @@ const BreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) => {
|
|||
{showSeparator && !isLast && <BreadcrumbSeparator />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// breadcrumb icon
|
||||
type BreadcrumbIconProps = {
|
||||
|
|
@ -107,10 +109,10 @@ type BreadcrumbIconProps = {
|
|||
className?: string;
|
||||
};
|
||||
|
||||
const BreadcrumbIcon: React.FC<BreadcrumbIconProps> = (props) => {
|
||||
function BreadcrumbIcon(props: BreadcrumbIconProps) {
|
||||
const { children, className } = props;
|
||||
return <div className={cn("flex size-4 items-center justify-start overflow-hidden", className)}>{children}</div>;
|
||||
};
|
||||
}
|
||||
|
||||
// breadcrumb label
|
||||
type BreadcrumbLabelProps = {
|
||||
|
|
@ -118,14 +120,14 @@ type BreadcrumbLabelProps = {
|
|||
className?: string;
|
||||
};
|
||||
|
||||
const BreadcrumbLabel: React.FC<BreadcrumbLabelProps> = (props) => {
|
||||
function BreadcrumbLabel(props: BreadcrumbLabelProps) {
|
||||
const { children, className } = props;
|
||||
return (
|
||||
<div className={cn("relative line-clamp-1 block max-w-[150px] overflow-hidden truncate", className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// breadcrumb separator
|
||||
type BreadcrumbSeparatorProps = {
|
||||
|
|
@ -135,7 +137,7 @@ type BreadcrumbSeparatorProps = {
|
|||
showDivider?: boolean;
|
||||
};
|
||||
|
||||
const BreadcrumbSeparator: React.FC<BreadcrumbSeparatorProps> = (props) => {
|
||||
function BreadcrumbSeparator(props: BreadcrumbSeparatorProps) {
|
||||
const { className, containerClassName, iconClassName, showDivider = false } = props;
|
||||
return (
|
||||
<div className={cn("relative flex items-center justify-center h-full px-1.5 py-1", className)}>
|
||||
|
|
@ -150,7 +152,7 @@ const BreadcrumbSeparator: React.FC<BreadcrumbSeparatorProps> = (props) => {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// breadcrumb wrapper
|
||||
type BreadcrumbItemWrapperProps = {
|
||||
|
|
@ -162,7 +164,7 @@ type BreadcrumbItemWrapperProps = {
|
|||
isLast?: boolean;
|
||||
};
|
||||
|
||||
const BreadcrumbItemWrapper: React.FC<BreadcrumbItemWrapperProps> = (props) => {
|
||||
function BreadcrumbItemWrapper(props: BreadcrumbItemWrapperProps) {
|
||||
const { label, disableTooltip = false, children, className, type = "link", isLast = false } = props;
|
||||
return (
|
||||
<Tooltip tooltipContent={label} position="bottom" disabled={!label || label === "" || disableTooltip}>
|
||||
|
|
@ -179,7 +181,7 @@ const BreadcrumbItemWrapper: React.FC<BreadcrumbItemWrapperProps> = (props) => {
|
|||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Breadcrumbs.Item = BreadcrumbItem;
|
||||
Breadcrumbs.Icon = BreadcrumbIcon;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ type TBreadcrumbNavigationDropdownProps = {
|
|||
isLast?: boolean;
|
||||
};
|
||||
|
||||
export const BreadcrumbNavigationDropdown = (props: TBreadcrumbNavigationDropdownProps) => {
|
||||
export function BreadcrumbNavigationDropdown(props: TBreadcrumbNavigationDropdownProps) {
|
||||
const { selectedItemKey, navigationItems, navigationDisabled = false, handleOnClick, isLast = false } = props;
|
||||
const [isOpen, setIsOpen] = React.useState(false);
|
||||
// derived values
|
||||
|
|
@ -29,31 +29,33 @@ export const BreadcrumbNavigationDropdown = (props: TBreadcrumbNavigationDropdow
|
|||
// if no selected item, return null
|
||||
if (!selectedItem) return null;
|
||||
|
||||
const NavigationButton = () => (
|
||||
<Tooltip tooltipContent={selectedItem.title} position="bottom" disabled={isOpen}>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
if (!isLast) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleOnClick?.();
|
||||
}
|
||||
}}
|
||||
className={cn(
|
||||
"group h-full flex items-center gap-2 px-1.5 py-1 text-sm font-medium text-custom-text-300 cursor-pointer rounded rounded-r-none",
|
||||
{
|
||||
"hover:bg-custom-background-80 hover:text-custom-text-100": !isLast,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<div className="flex @4xl:hidden text-custom-text-300">...</div>
|
||||
<div className="hidden @4xl:flex gap-2">
|
||||
{selectedItemIcon && <Breadcrumbs.Icon>{selectedItemIcon}</Breadcrumbs.Icon>}
|
||||
<Breadcrumbs.Label>{selectedItem.title}</Breadcrumbs.Label>
|
||||
</div>
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
function NavigationButton() {
|
||||
return (
|
||||
<Tooltip tooltipContent={selectedItem.title} position="bottom" disabled={isOpen}>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
if (!isLast) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleOnClick?.();
|
||||
}
|
||||
}}
|
||||
className={cn(
|
||||
"group h-full flex items-center gap-2 px-1.5 py-1 text-sm font-medium text-custom-text-300 cursor-pointer rounded rounded-r-none",
|
||||
{
|
||||
"hover:bg-custom-background-80 hover:text-custom-text-100": !isLast,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<div className="flex @4xl:hidden text-custom-text-300">...</div>
|
||||
<div className="hidden @4xl:flex gap-2">
|
||||
{selectedItemIcon && <Breadcrumbs.Icon>{selectedItemIcon}</Breadcrumbs.Icon>}
|
||||
<Breadcrumbs.Label>{selectedItem.title}</Breadcrumbs.Label>
|
||||
</div>
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
if (navigationDisabled) {
|
||||
return <NavigationButton />;
|
||||
|
|
@ -133,4 +135,4 @@ export const BreadcrumbNavigationDropdown = (props: TBreadcrumbNavigationDropdow
|
|||
})}
|
||||
</CustomMenu>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ type TBreadcrumbNavigationSearchDropdownProps = {
|
|||
shouldTruncate?: boolean;
|
||||
};
|
||||
|
||||
export const BreadcrumbNavigationSearchDropdown: React.FC<TBreadcrumbNavigationSearchDropdownProps> = (props) => {
|
||||
export function BreadcrumbNavigationSearchDropdown(props: TBreadcrumbNavigationSearchDropdownProps) {
|
||||
const {
|
||||
icon,
|
||||
title,
|
||||
|
|
@ -102,4 +102,4 @@ export const BreadcrumbNavigationSearchDropdown: React.FC<TBreadcrumbNavigationS
|
|||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElemen
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
|
||||
const Button = React.forwardRef(function Button(props: ButtonProps, ref: React.ForwardedRef<HTMLButtonElement>) {
|
||||
const {
|
||||
variant = "primary",
|
||||
size = "md",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ interface IToggleSwitchProps {
|
|||
className?: string;
|
||||
}
|
||||
|
||||
const ToggleSwitch: React.FC<IToggleSwitchProps> = (props) => {
|
||||
function ToggleSwitch(props: IToggleSwitchProps) {
|
||||
const { value, onChange, label, size = "sm", disabled, className } = props;
|
||||
|
||||
return (
|
||||
|
|
@ -49,7 +49,7 @@ const ToggleSwitch: React.FC<IToggleSwitchProps> = (props) => {
|
|||
/>
|
||||
</Switch>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
ToggleSwitch.displayName = "plane-ui-toggle-switch";
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Card = React.forwardRef<HTMLDivElement, CardProps>((props, ref) => {
|
||||
const Card = React.forwardRef(function Card(props: CardProps, ref: React.ForwardedRef<HTMLDivElement>) {
|
||||
const {
|
||||
variant = ECardVariant.WITH_SHADOW,
|
||||
direction = ECardDirection.COLUMN,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ type Props = {
|
|||
ChevronIcon?: React.FC<ISvgIcons>;
|
||||
};
|
||||
|
||||
export const CollapsibleButton: FC<Props> = (props) => {
|
||||
export function CollapsibleButton(props: Props) {
|
||||
const {
|
||||
isOpen,
|
||||
title,
|
||||
|
|
@ -49,4 +49,4 @@ export const CollapsibleButton: FC<Props> = (props) => {
|
|||
{actionItemElement && isOpen && actionItemElement}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export type TCollapsibleProps = {
|
|||
defaultOpen?: boolean;
|
||||
};
|
||||
|
||||
export const Collapsible: FC<TCollapsibleProps> = (props) => {
|
||||
export function Collapsible(props: TCollapsibleProps) {
|
||||
const { title, children, buttonRef, className, buttonClassName, isOpen, onToggle, defaultOpen } = props;
|
||||
// state
|
||||
const [localIsOpen, setLocalIsOpen] = useState<boolean>(isOpen || defaultOpen ? true : false);
|
||||
|
|
@ -51,4 +51,4 @@ export const Collapsible: FC<TCollapsibleProps> = (props) => {
|
|||
</Transition>
|
||||
</Disclosure>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ interface ColorPickerProps {
|
|||
className?: string;
|
||||
}
|
||||
|
||||
export const ColorPicker: React.FC<ColorPickerProps> = (props) => {
|
||||
export function ColorPicker(props: ColorPickerProps) {
|
||||
const { value, onChange, className = "" } = props;
|
||||
// refs
|
||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||
|
|
@ -35,4 +35,4 @@ export const ColorPicker: React.FC<ColorPickerProps> = (props) => {
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ export interface ContentWrapperProps extends React.HTMLAttributes<HTMLDivElement
|
|||
}
|
||||
const DEFAULT_STYLE = "flex flex-col vertical-scrollbar scrollbar-lg h-full w-full overflow-y-auto";
|
||||
|
||||
const ContentWrapper = React.forwardRef<HTMLDivElement, ContentWrapperProps>((props, ref) => {
|
||||
const ContentWrapper = React.forwardRef(function ContentWrapper(
|
||||
props: ContentWrapperProps,
|
||||
ref: React.ForwardedRef<HTMLDivElement>
|
||||
) {
|
||||
const { variant = ERowVariant.REGULAR, className = "", children, ...rest } = props;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ export type TControlLink = React.AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|||
draggable?: boolean;
|
||||
};
|
||||
|
||||
export const ControlLink = React.forwardRef<HTMLAnchorElement, TControlLink>((props, ref) => {
|
||||
export const ControlLink = React.forwardRef(function ControlLink(
|
||||
props: TControlLink,
|
||||
ref: React.ForwardedRef<HTMLAnchorElement>
|
||||
) {
|
||||
const { href, onClick, children, target = "_blank", disabled = false, className, draggable = false, ...rest } = props;
|
||||
const LEFT_CLICK_EVENT_CODE = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ interface IDragHandle {
|
|||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const DragHandle = forwardRef<HTMLButtonElement | null, IDragHandle>((props, ref) => {
|
||||
export const DragHandle = forwardRef(function DragHandle(
|
||||
props: IDragHandle,
|
||||
ref: React.ForwardedRef<HTMLButtonElement | null>
|
||||
) {
|
||||
const { className, disabled = false } = props;
|
||||
|
||||
if (disabled) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ type Props = {
|
|||
classNames?: string;
|
||||
};
|
||||
|
||||
export const DropIndicator = (props: Props) => {
|
||||
export function DropIndicator(props: Props) {
|
||||
const { isVisible, classNames = "" } = props;
|
||||
|
||||
return (
|
||||
|
|
@ -22,4 +22,4 @@ export const DropIndicator = (props: Props) => {
|
|||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import React, { Fragment } from "react";
|
|||
import { cn } from "../../utils";
|
||||
import type { IMultiSelectDropdownButton, ISingleSelectDropdownButton } from "../dropdown";
|
||||
|
||||
export const DropdownButton: React.FC<IMultiSelectDropdownButton | ISingleSelectDropdownButton> = (props) => {
|
||||
export function DropdownButton(props: IMultiSelectDropdownButton | ISingleSelectDropdownButton) {
|
||||
const {
|
||||
isOpen,
|
||||
buttonContent,
|
||||
|
|
@ -34,4 +34,4 @@ export const DropdownButton: React.FC<IMultiSelectDropdownButton | ISingleSelect
|
|||
</button>
|
||||
</Combobox.Button>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ interface IInputSearch {
|
|||
isMobile: boolean;
|
||||
}
|
||||
|
||||
export const InputSearch: FC<IInputSearch> = (props) => {
|
||||
export function InputSearch(props: IInputSearch) {
|
||||
const { isOpen, query, updateQuery, inputIcon, inputContainerClassName, inputClassName, inputPlaceholder, isMobile } =
|
||||
props;
|
||||
|
||||
|
|
@ -58,4 +58,4 @@ export const InputSearch: FC<IInputSearch> = (props) => {
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import { range } from "lodash-es";
|
||||
import React from "react";
|
||||
|
||||
export const DropdownOptionsLoader = () => (
|
||||
<div className="flex flex-col gap-1 animate-pulse">
|
||||
{range(6).map((index) => (
|
||||
<div key={index} className="flex h-[1.925rem] w-full rounded px-1 py-1.5 bg-custom-background-90" />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
export function DropdownOptionsLoader() {
|
||||
return (
|
||||
<div className="flex flex-col gap-1 animate-pulse">
|
||||
{range(6).map((index) => (
|
||||
<div key={index} className="flex h-[1.925rem] w-full rounded px-1 py-1.5 bg-custom-background-90" />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import type { IMultiSelectDropdownOptions, ISingleSelectDropdownOptions } from "
|
|||
// components
|
||||
import { DropdownOptionsLoader, InputSearch } from ".";
|
||||
|
||||
export const DropdownOptions: React.FC<IMultiSelectDropdownOptions | ISingleSelectDropdownOptions> = (props) => {
|
||||
export function DropdownOptions(props: IMultiSelectDropdownOptions | ISingleSelectDropdownOptions) {
|
||||
const {
|
||||
isOpen,
|
||||
query,
|
||||
|
|
@ -88,4 +88,4 @@ export const DropdownOptions: React.FC<IMultiSelectDropdownOptions | ISingleSele
|
|||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { DropdownButton } from "./common";
|
|||
import { DropdownOptions } from "./common/options";
|
||||
import type { IMultiSelectDropdown } from "./dropdown";
|
||||
|
||||
export const MultiSelectDropdown: FC<IMultiSelectDropdown> = (props) => {
|
||||
export function MultiSelectDropdown(props: IMultiSelectDropdown) {
|
||||
const {
|
||||
value,
|
||||
onChange,
|
||||
|
|
@ -165,4 +165,4 @@ export const MultiSelectDropdown: FC<IMultiSelectDropdown> = (props) => {
|
|||
)}
|
||||
</Combobox>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { DropdownButton } from "./common";
|
|||
import { DropdownOptions } from "./common/options";
|
||||
import type { ISingleSelectDropdown } from "./dropdown";
|
||||
|
||||
export const Dropdown: FC<ISingleSelectDropdown> = (props) => {
|
||||
export function Dropdown(props: ISingleSelectDropdown) {
|
||||
const {
|
||||
value,
|
||||
onChange,
|
||||
|
|
@ -165,4 +165,4 @@ export const Dropdown: FC<ISingleSelectDropdown> = (props) => {
|
|||
)}
|
||||
</Combobox>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ type Props = {
|
|||
children: ReactNode;
|
||||
};
|
||||
|
||||
const ComboDropDown = forwardRef((props: Props, ref) => {
|
||||
const ComboDropDown = forwardRef(function ComboDropDown(props: Props, ref) {
|
||||
const { button, renderByDefault = true, children, ...rest } = props;
|
||||
|
||||
const dropDownButtonRef = useRef<HTMLDivElement | null>(null);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ type ContextMenuItemProps = {
|
|||
item: TContextMenuItem;
|
||||
};
|
||||
|
||||
export const ContextMenuItem: React.FC<ContextMenuItemProps> = (props) => {
|
||||
export function ContextMenuItem(props: ContextMenuItemProps) {
|
||||
const { handleActiveItem, handleClose, isActive, item } = props;
|
||||
|
||||
// Nested menu state
|
||||
|
|
@ -243,4 +243,4 @@ export const ContextMenuItem: React.FC<ContextMenuItemProps> = (props) => {
|
|||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ interface PortalProps {
|
|||
container?: Element | null;
|
||||
}
|
||||
|
||||
export const Portal: React.FC<PortalProps> = ({ children, container }) => {
|
||||
export function Portal({ children, container }: PortalProps) {
|
||||
const [mounted, setMounted] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
|
@ -42,7 +42,7 @@ export const Portal: React.FC<PortalProps> = ({ children, container }) => {
|
|||
|
||||
const targetContainer = container || document.body;
|
||||
return ReactDOM.createPortal(children, targetContainer);
|
||||
};
|
||||
}
|
||||
|
||||
// Context for managing nested menus
|
||||
export const ContextMenuContext = React.createContext<{
|
||||
|
|
@ -57,7 +57,7 @@ type ContextMenuProps = {
|
|||
portalContainer?: Element | null;
|
||||
};
|
||||
|
||||
const ContextMenuWithoutPortal: React.FC<ContextMenuProps> = (props) => {
|
||||
function ContextMenuWithoutPortal(props: ContextMenuProps) {
|
||||
const { parentRef, items, portalContainer } = props;
|
||||
// states
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
|
@ -227,11 +227,11 @@ const ContextMenuWithoutPortal: React.FC<ContextMenuProps> = (props) => {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export const ContextMenu: React.FC<ContextMenuProps> = (props) => {
|
||||
export function ContextMenu(props: ContextMenuProps) {
|
||||
let contextMenu = <ContextMenuWithoutPortal {...props} />;
|
||||
const portal = document.querySelector("#context-menu-portal");
|
||||
if (portal) contextMenu = ReactDOM.createPortal(contextMenu, portal);
|
||||
return contextMenu;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ interface PortalProps {
|
|||
asChild?: boolean;
|
||||
}
|
||||
|
||||
const Portal: React.FC<PortalProps> = ({ children, container, asChild = false }) => {
|
||||
function Portal({ children, container, asChild = false }: PortalProps) {
|
||||
const [mounted, setMounted] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
|
@ -44,7 +44,7 @@ const Portal: React.FC<PortalProps> = ({ children, container, asChild = false })
|
|||
}
|
||||
|
||||
return ReactDOM.createPortal(<div data-radix-portal="">{children}</div>, targetContainer);
|
||||
};
|
||||
}
|
||||
|
||||
// Context for main menu to communicate with submenus
|
||||
const MenuContext = React.createContext<{
|
||||
|
|
@ -52,7 +52,7 @@ const MenuContext = React.createContext<{
|
|||
registerSubmenu: (closeSubmenu: () => void) => () => void;
|
||||
} | null>(null);
|
||||
|
||||
const CustomMenu = (props: ICustomMenuDropdownProps) => {
|
||||
function CustomMenu(props: ICustomMenuDropdownProps) {
|
||||
const {
|
||||
ariaLabel,
|
||||
buttonClassName = "",
|
||||
|
|
@ -295,7 +295,7 @@ const CustomMenu = (props: ICustomMenuDropdownProps) => {
|
|||
)}
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// SubMenu context for closing submenu from nested items
|
||||
const SubMenuContext = React.createContext<{ closeSubmenu: () => void } | null>(null);
|
||||
|
|
@ -304,7 +304,7 @@ const SubMenuContext = React.createContext<{ closeSubmenu: () => void } | null>(
|
|||
const useSubMenu = () => React.useContext(SubMenuContext);
|
||||
|
||||
// SubMenu implementation
|
||||
const SubMenu: React.FC<ICustomSubMenuProps> = (props) => {
|
||||
function SubMenu(props: ICustomSubMenuProps) {
|
||||
const {
|
||||
children,
|
||||
trigger,
|
||||
|
|
@ -447,9 +447,9 @@ const SubMenu: React.FC<ICustomSubMenuProps> = (props) => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
const MenuItem: React.FC<ICustomMenuItemProps> = (props) => {
|
||||
function MenuItem(props: ICustomMenuItemProps) {
|
||||
const { children, disabled = false, onClick, className } = props;
|
||||
const submenuContext = useSubMenu();
|
||||
|
||||
|
|
@ -479,9 +479,9 @@ const MenuItem: React.FC<ICustomMenuItemProps> = (props) => {
|
|||
)}
|
||||
</Menu.Item>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
const SubMenuTrigger: React.FC<ICustomSubMenuTriggerProps> = (props) => {
|
||||
function SubMenuTrigger(props: ICustomSubMenuTriggerProps) {
|
||||
const { children, disabled = false, className } = props;
|
||||
|
||||
return (
|
||||
|
|
@ -505,9 +505,9 @@ const SubMenuTrigger: React.FC<ICustomSubMenuTriggerProps> = (props) => {
|
|||
)}
|
||||
</Menu.Item>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
const SubMenuContent: React.FC<ICustomSubMenuContentProps> = (props) => {
|
||||
function SubMenuContent(props: ICustomSubMenuContentProps) {
|
||||
const { children, className } = props;
|
||||
|
||||
return (
|
||||
|
|
@ -520,7 +520,7 @@ const SubMenuContent: React.FC<ICustomSubMenuContentProps> = (props) => {
|
|||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// Add all components as static properties for external use
|
||||
CustomMenu.Portal = Portal;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { useDropdownKeyDown } from "../hooks/use-dropdown-key-down";
|
|||
import { cn } from "../utils";
|
||||
import type { ICustomSearchSelectProps } from "./helper";
|
||||
|
||||
export const CustomSearchSelect = (props: ICustomSearchSelectProps) => {
|
||||
export function CustomSearchSelect(props: ICustomSearchSelectProps) {
|
||||
const {
|
||||
customButtonClassName = "",
|
||||
buttonClassName = "",
|
||||
|
|
@ -223,4 +223,4 @@ export const CustomSearchSelect = (props: ICustomSearchSelectProps) => {
|
|||
}}
|
||||
</Combobox>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { cn } from "../utils";
|
|||
// types
|
||||
import type { ICustomSelectItemProps, ICustomSelectProps } from "./helper";
|
||||
|
||||
const CustomSelect = (props: ICustomSelectProps) => {
|
||||
function CustomSelect(props: ICustomSelectProps) {
|
||||
const {
|
||||
customButtonClassName = "",
|
||||
buttonClassName = "",
|
||||
|
|
@ -131,9 +131,9 @@ const CustomSelect = (props: ICustomSelectProps) => {
|
|||
)}
|
||||
</Combobox>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
const Option = (props: ICustomSelectItemProps) => {
|
||||
function Option(props: ICustomSelectItemProps) {
|
||||
const { children, value, className } = props;
|
||||
return (
|
||||
<Combobox.Option
|
||||
|
|
@ -156,7 +156,7 @@ const Option = (props: ICustomSelectItemProps) => {
|
|||
)}
|
||||
</Combobox.Option>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
CustomSelect.Option = Option;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ type Props = {
|
|||
selected: boolean;
|
||||
};
|
||||
|
||||
export const FavoriteStar: React.FC<Props> = (props) => {
|
||||
export function FavoriteStar(props: Props) {
|
||||
const { buttonClassName, iconClassName, onClick, selected } = props;
|
||||
|
||||
return (
|
||||
|
|
@ -26,4 +26,4 @@ export const FavoriteStar: React.FC<Props> = (props) => {
|
|||
/>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElemen
|
|||
indeterminate?: boolean;
|
||||
}
|
||||
|
||||
const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
|
||||
const Checkbox = React.forwardRef(function Checkbox(props: CheckboxProps, ref: React.ForwardedRef<HTMLInputElement>) {
|
||||
const {
|
||||
id,
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export interface InputColorPickerProps {
|
|||
placeholder: string;
|
||||
}
|
||||
|
||||
export const InputColorPicker: React.FC<InputColorPickerProps> = (props) => {
|
||||
export function InputColorPicker(props: InputColorPickerProps) {
|
||||
const { value, hasError, onChange, name, className, style, placeholder } = props;
|
||||
|
||||
const [referenceElement, setReferenceElement] = React.useState<HTMLButtonElement | null>(null);
|
||||
|
|
@ -111,4 +111,4 @@ export const InputColorPicker: React.FC<InputColorPickerProps> = (props) => {
|
|||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement>
|
|||
autoComplete?: "on" | "off";
|
||||
}
|
||||
|
||||
const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
|
||||
const Input = React.forwardRef(function Input(props: InputProps, ref: React.ForwardedRef<HTMLInputElement>) {
|
||||
const {
|
||||
id,
|
||||
type,
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ export interface PasswordStrengthIndicatorProps {
|
|||
isFocused?: boolean;
|
||||
}
|
||||
|
||||
export const PasswordStrengthIndicator: React.FC<PasswordStrengthIndicatorProps> = ({
|
||||
export function PasswordStrengthIndicator({
|
||||
password,
|
||||
showCriteria = true,
|
||||
isFocused = false,
|
||||
}) => {
|
||||
}: PasswordStrengthIndicatorProps) {
|
||||
const strength = getPasswordStrength(password);
|
||||
const criteria = getPasswordCriteria(password);
|
||||
const strengthInfo = getStrengthInfo(strength);
|
||||
|
|
@ -72,4 +72,4 @@ export const PasswordStrengthIndicator: React.FC<PasswordStrengthIndicatorProps>
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ interface PasswordInputProps {
|
|||
error?: boolean;
|
||||
}
|
||||
|
||||
export const PasswordInput: React.FC<PasswordInputProps> = ({
|
||||
export function PasswordInput({
|
||||
id,
|
||||
value,
|
||||
onChange,
|
||||
|
|
@ -21,7 +21,7 @@ export const PasswordInput: React.FC<PasswordInputProps> = ({
|
|||
className,
|
||||
showToggle = true,
|
||||
error = false,
|
||||
}) => {
|
||||
}: PasswordInputProps) {
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
return (
|
||||
<div className="relative">
|
||||
|
|
@ -66,4 +66,4 @@ export const PasswordInput: React.FC<PasswordInputProps> = ({
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ interface LabelProps {
|
|||
className?: string;
|
||||
}
|
||||
|
||||
export const Label: React.FC<LabelProps> = ({ htmlFor, children, className }) => (
|
||||
<label htmlFor={htmlFor} className={cn("block text-sm font-medium text-custom-text-100", className)}>
|
||||
{children}
|
||||
</label>
|
||||
);
|
||||
export function Label({ htmlFor, children, className }: LabelProps) {
|
||||
return (
|
||||
<label htmlFor={htmlFor} className={cn("block text-sm font-medium text-custom-text-100", className)}>
|
||||
{children}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
||||
// Reusable Form Field Component
|
||||
interface FormFieldProps {
|
||||
|
|
@ -23,15 +25,17 @@ interface FormFieldProps {
|
|||
optional?: boolean;
|
||||
}
|
||||
|
||||
export const FormField: React.FC<FormFieldProps> = ({ label, htmlFor, children, className, optional = false }) => (
|
||||
<div className={cn("flex flex-col gap-1.5", className)}>
|
||||
<Label htmlFor={htmlFor}>
|
||||
{label}
|
||||
{optional && <span className="text-custom-text-400 text-sm"> (optional)</span>}
|
||||
</Label>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
export function FormField({ label, htmlFor, children, className, optional = false }: FormFieldProps) {
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-1.5", className)}>
|
||||
<Label htmlFor={htmlFor}>
|
||||
{label}
|
||||
{optional && <span className="text-custom-text-400 text-sm"> (optional)</span>}
|
||||
</Label>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Reusable Validation Message Component
|
||||
interface ValidationMessageProps {
|
||||
|
|
@ -40,17 +44,19 @@ interface ValidationMessageProps {
|
|||
className?: string;
|
||||
}
|
||||
|
||||
export const ValidationMessage: React.FC<ValidationMessageProps> = ({ type, message, className }) => (
|
||||
<p
|
||||
className={cn(
|
||||
"text-sm",
|
||||
{
|
||||
"text-red-500": type === "error",
|
||||
"text-green-500": type === "success",
|
||||
},
|
||||
className
|
||||
)}
|
||||
>
|
||||
{message}
|
||||
</p>
|
||||
);
|
||||
export function ValidationMessage({ type, message, className }: ValidationMessageProps) {
|
||||
return (
|
||||
<p
|
||||
className={cn(
|
||||
"text-sm",
|
||||
{
|
||||
"text-red-500": type === "error",
|
||||
"text-green-500": type === "success",
|
||||
},
|
||||
className
|
||||
)}
|
||||
>
|
||||
{message}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ export interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextArea
|
|||
className?: string;
|
||||
}
|
||||
|
||||
const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>((props, ref) => {
|
||||
const TextArea = React.forwardRef(function TextArea(
|
||||
props: TextAreaProps,
|
||||
ref: React.ForwardedRef<HTMLTextAreaElement>
|
||||
) {
|
||||
const {
|
||||
id,
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ export interface HeaderProps {
|
|||
}
|
||||
|
||||
const HeaderContext = React.createContext<THeaderVariant | null>(null);
|
||||
const Header = (props: HeaderProps) => {
|
||||
|
||||
function Header(props: HeaderProps) {
|
||||
const {
|
||||
variant = EHeaderVariant.PRIMARY,
|
||||
className = "",
|
||||
|
|
@ -35,19 +36,22 @@ const Header = (props: HeaderProps) => {
|
|||
</Row>
|
||||
</HeaderContext.Provider>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
const LeftItem = (props: HeaderProps) => (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-wrap items-center gap-2 overflow-ellipsis whitespace-nowrap max-w-[80%] flex-grow",
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
const RightItem = (props: HeaderProps) => {
|
||||
function LeftItem(props: HeaderProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-wrap items-center gap-2 overflow-ellipsis whitespace-nowrap max-w-[80%] flex-grow",
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function RightItem(props: HeaderProps) {
|
||||
const variant = React.useContext(HeaderContext);
|
||||
if (variant === undefined) throw new Error("RightItem must be used within Header");
|
||||
return (
|
||||
|
|
@ -63,7 +67,7 @@ const RightItem = (props: HeaderProps) => {
|
|||
{props.children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Header.LeftItem = LeftItem;
|
||||
Header.RightItem = RightItem;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export type TLinkItemBlockProps = {
|
|||
onClick?: () => void;
|
||||
};
|
||||
|
||||
export const LinkItemBlock: FC<TLinkItemBlockProps> = (props) => {
|
||||
export function LinkItemBlock(props: TLinkItemBlockProps) {
|
||||
// props
|
||||
const { title, url, createdAt, menuItems, onClick } = props;
|
||||
// icons
|
||||
|
|
@ -67,4 +67,4 @@ export const LinkItemBlock: FC<TLinkItemBlockProps> = (props) => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ type Props = {
|
|||
className?: string;
|
||||
};
|
||||
|
||||
const Loader = ({ children, className = "" }: Props) => (
|
||||
<div className={cn("animate-pulse", className)} role="status">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
function Loader({ children, className = "" }: Props) {
|
||||
return (
|
||||
<div className={cn("animate-pulse", className)} role="status">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type ItemProps = {
|
||||
height?: string;
|
||||
|
|
@ -19,9 +21,11 @@ type ItemProps = {
|
|||
className?: string;
|
||||
};
|
||||
|
||||
const Item: React.FC<ItemProps> = ({ height = "auto", width = "auto", className = "" }) => (
|
||||
<div className={cn("rounded-md bg-custom-background-80", className)} style={{ height: height, width: width }} />
|
||||
);
|
||||
function Item({ height = "auto", width = "auto", className = "" }: ItemProps) {
|
||||
return (
|
||||
<div className={cn("rounded-md bg-custom-background-80", className)} style={{ height: height, width: width }} />
|
||||
);
|
||||
}
|
||||
|
||||
Loader.Item = Item;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ const VARIANT_CLASSES: Record<TModalVariant, string> = {
|
|||
primary: "bg-custom-primary-100/20 text-custom-primary-100",
|
||||
};
|
||||
|
||||
export const AlertModalCore: React.FC<Props> = (props) => {
|
||||
export function AlertModalCore(props: Props) {
|
||||
const {
|
||||
content,
|
||||
handleClose,
|
||||
|
|
@ -94,4 +94,4 @@ export const AlertModalCore: React.FC<Props> = (props) => {
|
|||
</div>
|
||||
</ModalCore>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ type Props = {
|
|||
width?: EModalWidth;
|
||||
className?: string;
|
||||
};
|
||||
export const ModalCore: React.FC<Props> = (props) => {
|
||||
export function ModalCore(props: Props) {
|
||||
const {
|
||||
children,
|
||||
handleClose,
|
||||
|
|
@ -64,4 +64,4 @@ export const ModalCore: React.FC<Props> = (props) => {
|
|||
</Dialog>
|
||||
</Transition.Root>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ export interface OAuthButtonProps extends React.ButtonHTMLAttributes<HTMLButtonE
|
|||
compact?: boolean;
|
||||
}
|
||||
|
||||
const OAuthButton = React.forwardRef<HTMLButtonElement, OAuthButtonProps>((props, ref) => {
|
||||
const OAuthButton = React.forwardRef(function OAuthButton(
|
||||
props: OAuthButtonProps,
|
||||
ref: React.ForwardedRef<HTMLButtonElement>
|
||||
) {
|
||||
const { text, icon, compact = false, className = "", ...rest } = props;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ type OAuthOptionsProps = {
|
|||
containerClassName?: string;
|
||||
};
|
||||
|
||||
export const OAuthOptions = (props: OAuthOptionsProps) => {
|
||||
export function OAuthOptions(props: OAuthOptionsProps) {
|
||||
const { options, compact = false, className = "", containerClassName = "" } = props;
|
||||
|
||||
// Filter enabled options
|
||||
|
|
@ -54,4 +54,4 @@ export const OAuthOptions = (props: OAuthOptionsProps) => {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { Popover } from "./popover";
|
|||
// types
|
||||
import type { TPopoverMenu } from "./types";
|
||||
|
||||
export const PopoverMenu = <T,>(props: TPopoverMenu<T>) => {
|
||||
export function PopoverMenu<T>(props: TPopoverMenu<T>) {
|
||||
const {
|
||||
popperPosition = "bottom-end",
|
||||
popperPadding = 0,
|
||||
|
|
@ -42,4 +42,4 @@ export const PopoverMenu = <T,>(props: TPopoverMenu<T>) => {
|
|||
</Fragment>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { cn } from "../utils";
|
|||
// types
|
||||
import type { TPopover } from "./types";
|
||||
|
||||
export const Popover = (props: TPopover) => {
|
||||
export function Popover(props: TPopover) {
|
||||
const {
|
||||
popperPosition = "bottom-end",
|
||||
popperPadding = 0,
|
||||
|
|
@ -76,4 +76,4 @@ export const Popover = (props: TPopover) => {
|
|||
</Transition>
|
||||
</HeadlessReactPopover>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ interface ICircularProgressIndicator {
|
|||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const CircularProgressIndicator: React.FC<ICircularProgressIndicator> = (props) => {
|
||||
export function CircularProgressIndicator(props: ICircularProgressIndicator) {
|
||||
const { size = 40, percentage = 25, strokeWidth = 6, strokeColor = "stroke-custom-primary-100", children } = props;
|
||||
|
||||
const sqSize = size;
|
||||
|
|
@ -81,4 +81,4 @@ export const CircularProgressIndicator: React.FC<ICircularProgressIndicator> = (
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ type Props = {
|
|||
barClassName?: string;
|
||||
};
|
||||
|
||||
export const LinearProgressIndicator: React.FC<Props> = ({
|
||||
export function LinearProgressIndicator({
|
||||
data,
|
||||
noTooltip = false,
|
||||
inPercentage = false,
|
||||
size = "sm",
|
||||
className = "",
|
||||
barClassName = "",
|
||||
}) => {
|
||||
}: Props) {
|
||||
const total = data.reduce((acc: any, cur: any) => acc + cur.value, 0);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
let progress = 0;
|
||||
|
|
@ -54,4 +54,4 @@ export const LinearProgressIndicator: React.FC<Props> = ({
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ type Props = {
|
|||
inactiveStrokeColor?: string;
|
||||
};
|
||||
|
||||
export const ProgressBar: React.FC<Props> = ({
|
||||
export function ProgressBar({
|
||||
maxValue = 0,
|
||||
value = 0,
|
||||
radius = 8,
|
||||
strokeWidth = 2,
|
||||
activeStrokeColor = "#3e98c7",
|
||||
inactiveStrokeColor = "#ddd",
|
||||
}) => {
|
||||
}: Props) {
|
||||
// PIE Calc Fn
|
||||
const generatePie = (value: any) => {
|
||||
const x = radius - Math.cos((2 * Math.PI) / (100 / value)) * radius;
|
||||
|
|
@ -65,4 +65,4 @@ export const ProgressBar: React.FC<Props> = ({
|
|||
<circle r={radius - strokeWidth} cx={radius} cy={radius} className="progress-bar" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ interface IRadialProgressBar {
|
|||
progress: number;
|
||||
}
|
||||
|
||||
export const RadialProgressBar: FC<IRadialProgressBar> = (props) => {
|
||||
export function RadialProgressBar(props: IRadialProgressBar) {
|
||||
const { progress } = props;
|
||||
const [circumference, setCircumference] = useState(0);
|
||||
|
||||
|
|
@ -43,4 +43,4 @@ export const RadialProgressBar: FC<IRadialProgressBar> = (props) => {
|
|||
</svg>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export interface RowProps extends React.HTMLAttributes<HTMLDivElement> {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Row = React.forwardRef<HTMLDivElement, RowProps>((props, ref) => {
|
||||
const Row = React.forwardRef(function Row(props: RowProps, ref: React.ForwardedRef<HTMLDivElement>) {
|
||||
const { variant = ERowVariant.REGULAR, className = "", children, ...rest } = props;
|
||||
|
||||
const style = rowStyle[variant];
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const thumbSizeStyles = {
|
|||
lg: "before:absolute before:left-1/2 before:top-1/2 before:size-full before:min-h-17 before:min-w-17 before:-translate-x-1/2 before:-translate-y-1/2",
|
||||
};
|
||||
|
||||
export const ScrollArea: FC<TScrollAreaProps> = (props) => {
|
||||
export function ScrollArea(props: TScrollAreaProps) {
|
||||
const { type = "always", className = "", scrollHideDelay = 600, size = "md", children } = props;
|
||||
|
||||
return (
|
||||
|
|
@ -64,4 +64,4 @@ export const ScrollArea: FC<TScrollAreaProps> = (props) => {
|
|||
</RadixScrollArea.Scrollbar>
|
||||
</RadixScrollArea.Root>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ type Props = {
|
|||
data: any; //@todo make this generic
|
||||
className?: string;
|
||||
};
|
||||
const Draggable = ({ children, data, className }: Props) => {
|
||||
|
||||
function Draggable({ children, data, className }: Props) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [dragging, setDragging] = useState<boolean>(false); // NEW
|
||||
const [isDraggedOver, setIsDraggedOver] = useState(false);
|
||||
|
|
@ -69,6 +70,6 @@ const Draggable = ({ children, data, className }: Props) => {
|
|||
{<DropIndicator isVisible={isDraggedOver && closestEdge === "bottom"} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export { Draggable };
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ const moveItem = <T,>(
|
|||
};
|
||||
};
|
||||
|
||||
export const Sortable = <T,>({ data, render, onChange, keyExtractor, containerClassName, id }: Props<T>) => {
|
||||
export function Sortable<T>({ data, render, onChange, keyExtractor, containerClassName, id }: Props<T>) {
|
||||
useEffect(() => {
|
||||
const unsubscribe = monitorForElements({
|
||||
// @ts-expect-error Due to live server dependencies
|
||||
|
|
@ -100,6 +100,6 @@ export const Sortable = <T,>({ data, render, onChange, keyExtractor, containerCl
|
|||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Sortable;
|
||||
|
|
|
|||
|
|
@ -6,30 +6,28 @@ interface ICircularBarSpinner extends React.SVGAttributes<SVGElement> {
|
|||
className?: string | undefined;
|
||||
}
|
||||
|
||||
export const CircularBarSpinner: React.FC<ICircularBarSpinner> = ({
|
||||
height = "16px",
|
||||
width = "16px",
|
||||
className = "",
|
||||
}) => (
|
||||
<div role="status">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} viewBox="0 0 24 24" className={className}>
|
||||
<g>
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.14} />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.29} transform="rotate(30 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.43} transform="rotate(60 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.57} transform="rotate(90 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.71} transform="rotate(120 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.86} transform="rotate(150 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" transform="rotate(180 12 12)" />
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
calcMode="discrete"
|
||||
dur="0.75s"
|
||||
repeatCount="indefinite"
|
||||
type="rotate"
|
||||
values="0 12 12;30 12 12;60 12 12;90 12 12;120 12 12;150 12 12;180 12 12;210 12 12;240 12 12;270 12 12;300 12 12;330 12 12;360 12 12"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
export function CircularBarSpinner({ height = "16px", width = "16px", className = "" }: ICircularBarSpinner) {
|
||||
return (
|
||||
<div role="status">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} viewBox="0 0 24 24" className={className}>
|
||||
<g>
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.14} />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.29} transform="rotate(30 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.43} transform="rotate(60 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.57} transform="rotate(90 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.71} transform="rotate(120 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" opacity={0.86} transform="rotate(150 12 12)" />
|
||||
<rect width={2} height={5} x={11} y={1} fill="currentColor" transform="rotate(180 12 12)" />
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
calcMode="discrete"
|
||||
dur="0.75s"
|
||||
repeatCount="indefinite"
|
||||
type="rotate"
|
||||
values="0 12 12;30 12 12;60 12 12;90 12 12;120 12 12;150 12 12;180 12 12;210 12 12;240 12 12;270 12 12;300 12 12;330 12 12;360 12 12"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,26 +8,28 @@ export interface ISpinner extends React.SVGAttributes<SVGElement> {
|
|||
className?: string | undefined;
|
||||
}
|
||||
|
||||
export const Spinner: React.FC<ISpinner> = ({ height = "32px", width = "32px", className = "" }) => (
|
||||
<div role="status">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
height={height}
|
||||
width={width}
|
||||
className={cn("animate-spin fill-custom-primary-100 text-custom-text-200", className)}
|
||||
viewBox="0 0 100 101"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||
fill="currentFill"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Loading...</span>
|
||||
</div>
|
||||
);
|
||||
export function Spinner({ height = "32px", width = "32px", className = "" }: ISpinner) {
|
||||
return (
|
||||
<div role="status">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
height={height}
|
||||
width={width}
|
||||
className={cn("animate-spin fill-custom-primary-100 text-custom-text-200", className)}
|
||||
viewBox="0 0 100 101"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||
fill="currentFill"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Loading...</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { cn } from "../utils";
|
|||
// types
|
||||
import type { TTableData } from "./types";
|
||||
|
||||
export const Table = <T,>(props: TTableData<T>) => {
|
||||
export function Table<T>(props: TTableData<T>) {
|
||||
const {
|
||||
data,
|
||||
columns,
|
||||
|
|
@ -45,4 +45,4 @@ export const Table = <T,>(props: TTableData<T>) => {
|
|||
</tbody>
|
||||
</table>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,51 +22,53 @@ type TTabListProps = {
|
|||
onTabChange?: (key: string) => void;
|
||||
};
|
||||
|
||||
export const TabList: FC<TTabListProps> = ({
|
||||
export function TabList({
|
||||
tabs,
|
||||
tabListClassName,
|
||||
tabClassName,
|
||||
size = "md",
|
||||
selectedTab,
|
||||
onTabChange,
|
||||
}) => (
|
||||
<Tab.List
|
||||
as="div"
|
||||
className={cn(
|
||||
"flex w-full min-w-fit items-center justify-between gap-1.5 rounded-md text-sm p-0.5 bg-custom-background-80/60",
|
||||
tabListClassName
|
||||
)}
|
||||
>
|
||||
{tabs.map((tab) => (
|
||||
<Tab
|
||||
className={({ selected }) =>
|
||||
cn(
|
||||
"flex items-center justify-center p-1 min-w-fit w-full font-medium text-custom-text-100 outline-none focus:outline-none cursor-pointer transition-all rounded",
|
||||
(selectedTab ? selectedTab === tab.key : selected)
|
||||
? "bg-custom-background-100 text-custom-text-100 shadow-sm"
|
||||
: tab.disabled
|
||||
? "text-custom-text-400 cursor-not-allowed"
|
||||
: "text-custom-text-400 hover:text-custom-text-300 hover:bg-custom-background-80/60",
|
||||
{
|
||||
"text-xs": size === "sm",
|
||||
"text-sm": size === "md",
|
||||
"text-base": size === "lg",
|
||||
},
|
||||
tabClassName
|
||||
)
|
||||
}
|
||||
key={tab.key}
|
||||
onClick={() => {
|
||||
if (!tab.disabled) {
|
||||
onTabChange?.(tab.key);
|
||||
tab.onClick?.();
|
||||
}: TTabListProps) {
|
||||
return (
|
||||
<Tab.List
|
||||
as="div"
|
||||
className={cn(
|
||||
"flex w-full min-w-fit items-center justify-between gap-1.5 rounded-md text-sm p-0.5 bg-custom-background-80/60",
|
||||
tabListClassName
|
||||
)}
|
||||
>
|
||||
{tabs.map((tab) => (
|
||||
<Tab
|
||||
className={({ selected }) =>
|
||||
cn(
|
||||
"flex items-center justify-center p-1 min-w-fit w-full font-medium text-custom-text-100 outline-none focus:outline-none cursor-pointer transition-all rounded",
|
||||
(selectedTab ? selectedTab === tab.key : selected)
|
||||
? "bg-custom-background-100 text-custom-text-100 shadow-sm"
|
||||
: tab.disabled
|
||||
? "text-custom-text-400 cursor-not-allowed"
|
||||
: "text-custom-text-400 hover:text-custom-text-300 hover:bg-custom-background-80/60",
|
||||
{
|
||||
"text-xs": size === "sm",
|
||||
"text-sm": size === "md",
|
||||
"text-base": size === "lg",
|
||||
},
|
||||
tabClassName
|
||||
)
|
||||
}
|
||||
}}
|
||||
disabled={tab.disabled}
|
||||
>
|
||||
{tab.icon && <tab.icon className="size-4" />}
|
||||
{tab.label}
|
||||
</Tab>
|
||||
))}
|
||||
</Tab.List>
|
||||
);
|
||||
key={tab.key}
|
||||
onClick={() => {
|
||||
if (!tab.disabled) {
|
||||
onTabChange?.(tab.key);
|
||||
tab.onClick?.();
|
||||
}
|
||||
}}
|
||||
disabled={tab.disabled}
|
||||
>
|
||||
{tab.icon && <tab.icon className="size-4" />}
|
||||
{tab.label}
|
||||
</Tab>
|
||||
))}
|
||||
</Tab.List>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ type TTabsProps = {
|
|||
storeInLocalStorage?: boolean;
|
||||
};
|
||||
|
||||
export const Tabs: FC<TTabsProps> = (props: TTabsProps) => {
|
||||
export function Tabs(props: TTabsProps) {
|
||||
const {
|
||||
tabs,
|
||||
storageKey,
|
||||
|
|
@ -87,4 +87,4 @@ export const Tabs: FC<TTabsProps> = (props: TTabsProps) => {
|
|||
</Tab.Group>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export interface TagProps extends React.ComponentProps<"div"> {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Tag = React.forwardRef<HTMLDivElement, TagProps>((props, ref) => {
|
||||
const Tag = React.forwardRef(function Tag(props: TagProps, ref: React.ForwardedRef<HTMLDivElement>) {
|
||||
const { variant = ETagVariant.OUTLINED, className = "", size = ETagSize.SM, children, ...rest } = props;
|
||||
|
||||
const style = getTagStyle(variant, size);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ interface ITooltipProps {
|
|||
renderByDefault?: boolean;
|
||||
}
|
||||
|
||||
export const Tooltip: React.FC<ITooltipProps> = ({
|
||||
export function Tooltip({
|
||||
tooltipHeading,
|
||||
tooltipContent,
|
||||
position = "top",
|
||||
|
|
@ -43,8 +43,10 @@ export const Tooltip: React.FC<ITooltipProps> = ({
|
|||
openDelay = 200,
|
||||
closeDelay,
|
||||
isMobile = false,
|
||||
renderByDefault = true, //FIXME: tooltip should always render on hover and not by default, this is a temporary fix
|
||||
}) => {
|
||||
|
||||
//FIXME: tooltip should always render on hover and not by default, this is a temporary fix
|
||||
renderByDefault = true,
|
||||
}: ITooltipProps) {
|
||||
const toolTipRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const [shouldRender, setShouldRender] = useState(renderByDefault);
|
||||
|
|
@ -107,4 +109,4 @@ export const Tooltip: React.FC<ITooltipProps> = ({
|
|||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@ type Props = {
|
|||
className?: string;
|
||||
noMargin?: boolean;
|
||||
};
|
||||
const SubHeading = ({ children, className, noMargin }: Props) => (
|
||||
<h3 className={cn("text-xl font-medium text-custom-text-200 block leading-7", !noMargin && "mb-2", className)}>
|
||||
{children}
|
||||
</h3>
|
||||
);
|
||||
|
||||
function SubHeading({ children, className, noMargin }: Props) {
|
||||
return (
|
||||
<h3 className={cn("text-xl font-medium text-custom-text-200 block leading-7", !noMargin && "mb-2", className)}>
|
||||
{children}
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
export { SubHeading };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue