mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(components): focus visible & other states are now handled by data properties
This commit is contained in:
parent
5f1d889d8c
commit
f4e2e502a6
@ -15,7 +15,7 @@ import {useAvatarGroupContext} from "./avatar-group-context";
|
||||
export interface UseAvatarProps
|
||||
extends Omit<
|
||||
HTMLNextUIProps<"span", AvatarVariantProps>,
|
||||
"children" | "isInGroup" | "isInGridGroup" | "isFocusVisible"
|
||||
"children" | "isInGroup" | "isInGridGroup"
|
||||
> {
|
||||
/**
|
||||
* Ref to the DOM node.
|
||||
|
||||
@ -18,7 +18,7 @@ import {useButtonGroupContext} from "./button-group-context";
|
||||
|
||||
export interface UseButtonProps
|
||||
extends HTMLNextUIProps<"button", Omit<AriaButtonProps, keyof ButtonVariantProps>>,
|
||||
Omit<ButtonVariantProps, "isFocusVisible" | "isInGroup" | "isInVerticalGroup"> {
|
||||
Omit<ButtonVariantProps, "isInGroup" | "isInVerticalGroup"> {
|
||||
/**
|
||||
* Ref to the DOM node.
|
||||
*/
|
||||
|
||||
@ -68,7 +68,7 @@ interface Props extends HTMLNextUIProps<"label"> {
|
||||
|
||||
export type UseCheckboxProps = Omit<Props, "defaultChecked"> &
|
||||
Omit<AriaCheckboxProps, keyof CheckboxVariantProps | "onChange"> &
|
||||
Omit<CheckboxVariantProps, "isFocusVisible">;
|
||||
CheckboxVariantProps;
|
||||
|
||||
export function useCheckbox(props: UseCheckboxProps) {
|
||||
const groupContext = useCheckboxGroupContext();
|
||||
|
||||
@ -9,7 +9,7 @@ import {TreeState} from "@react-stately/tree";
|
||||
import {clsx, dataAttr} from "@nextui-org/shared-utils";
|
||||
import {useMenuItem} from "@react-aria/menu";
|
||||
import {chain, filterDOMProps, mergeProps} from "@react-aria/utils";
|
||||
import {usePress} from "@react-aria/interactions";
|
||||
import {useHover, usePress} from "@react-aria/interactions";
|
||||
|
||||
import {useDropdownContext} from "./dropdown-context";
|
||||
|
||||
@ -65,12 +65,16 @@ export function useDropdownItem<T extends object>(originalProps: UseDropdownItem
|
||||
const descriptionId = useId();
|
||||
const keyboardId = useId();
|
||||
|
||||
const {pressProps} = usePress({
|
||||
const {pressProps, isPressed} = usePress({
|
||||
ref: domRef,
|
||||
isDisabled,
|
||||
onPress,
|
||||
});
|
||||
|
||||
const {isHovered, hoverProps} = useHover({
|
||||
isDisabled,
|
||||
});
|
||||
|
||||
const {isFocusVisible, focusProps} = useFocusRing({
|
||||
autoFocus,
|
||||
});
|
||||
@ -101,10 +105,9 @@ export function useDropdownItem<T extends object>(originalProps: UseDropdownItem
|
||||
dropdownItem({
|
||||
...variantProps,
|
||||
isDisabled,
|
||||
isFocusVisible,
|
||||
disableAnimation,
|
||||
}),
|
||||
[...Object.values(variantProps), isDisabled, isFocusVisible, disableAnimation],
|
||||
[...Object.values(variantProps), isDisabled, disableAnimation],
|
||||
);
|
||||
|
||||
const baseStyles = clsx(classNames?.base, className);
|
||||
@ -115,10 +118,16 @@ export function useDropdownItem<T extends object>(originalProps: UseDropdownItem
|
||||
menuItemProps,
|
||||
focusProps,
|
||||
pressProps,
|
||||
hoverProps,
|
||||
filterDOMProps(otherProps, {labelable: true}),
|
||||
props,
|
||||
),
|
||||
"data-focused": dataAttr(isFocused),
|
||||
"data-focus": dataAttr(isFocused),
|
||||
"data-hover": dataAttr(isHovered),
|
||||
"data-disabled": dataAttr(isDisabled),
|
||||
"data-selected": dataAttr(isSelected),
|
||||
"data-pressed": dataAttr(isPressed),
|
||||
"data-focus-visible": dataAttr(isFocusVisible),
|
||||
"aria-labelledby": labelId,
|
||||
"aria-describedby": [descriptionId, keyboardId].filter(Boolean).join(" ") || undefined,
|
||||
className: slots.base({class: clsx(baseStyles, props.className)}),
|
||||
|
||||
@ -60,11 +60,9 @@ const Pagination = forwardRef<PaginationProps, "ul">((props, ref) => {
|
||||
<PaginationItem
|
||||
key={key}
|
||||
className={slots.prev({
|
||||
class: clsx(
|
||||
classNames?.prev,
|
||||
!loop && activePage === 1 && "opacity-50 pointer-events-none",
|
||||
),
|
||||
class: classNames?.prev,
|
||||
})}
|
||||
isDisabled={!loop && activePage === 1}
|
||||
value={value}
|
||||
onPress={onPrevious}
|
||||
>
|
||||
@ -77,11 +75,9 @@ const Pagination = forwardRef<PaginationProps, "ul">((props, ref) => {
|
||||
<PaginationItem
|
||||
key={key}
|
||||
className={slots.next({
|
||||
class: clsx(
|
||||
classNames?.next,
|
||||
!loop && activePage === total && "opacity-50 pointer-events-none",
|
||||
),
|
||||
class: clsx(classNames?.next),
|
||||
})}
|
||||
isDisabled={!loop && activePage === total}
|
||||
value={value}
|
||||
onPress={onNext}
|
||||
>
|
||||
|
||||
@ -4,11 +4,10 @@ import type {PressEvent} from "@react-types/shared";
|
||||
|
||||
import {useMemo} from "react";
|
||||
import {PaginationItemType, PaginationItemValue} from "@nextui-org/use-pagination";
|
||||
import {ringClasses} from "@nextui-org/theme";
|
||||
import {clsx, dataAttr, warn} from "@nextui-org/shared-utils";
|
||||
import {mergeProps} from "@react-aria/utils";
|
||||
import {clsx, dataAttr} from "@nextui-org/shared-utils";
|
||||
import {chain, mergeProps} from "@react-aria/utils";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {usePress} from "@react-aria/interactions";
|
||||
import {useHover, usePress} from "@react-aria/interactions";
|
||||
import {useFocusRing} from "@react-aria/focus";
|
||||
|
||||
export interface UsePaginationItemProps extends Omit<HTMLNextUIProps<"li">, "onClick"> {
|
||||
@ -91,19 +90,13 @@ export function usePaginationItem(props: UsePaginationItemProps) {
|
||||
[value, isActive],
|
||||
);
|
||||
|
||||
const handlePress = (e: PressEvent) => {
|
||||
if (onClick) {
|
||||
warn("onClick is deprecated, use onPress instead.", "PaginationItem");
|
||||
}
|
||||
onPress?.(e);
|
||||
};
|
||||
|
||||
const {pressProps} = usePress({
|
||||
isDisabled,
|
||||
onPress: handlePress,
|
||||
onPress,
|
||||
});
|
||||
|
||||
const {focusProps, isFocused, isFocusVisible} = useFocusRing();
|
||||
const {focusProps, isFocused, isFocusVisible} = useFocusRing({});
|
||||
const {isHovered, hoverProps} = useHover({isDisabled});
|
||||
|
||||
const getItemProps: PropGetter = (props = {}) => {
|
||||
return {
|
||||
@ -113,11 +106,14 @@ export function usePaginationItem(props: UsePaginationItemProps) {
|
||||
"aria-label": ariaLabel,
|
||||
"aria-current": dataAttr(isActive),
|
||||
"aria-disabled": dataAttr(isDisabled),
|
||||
"data-disabled": dataAttr(isDisabled),
|
||||
"data-active": dataAttr(isActive),
|
||||
"data-focus": dataAttr(isFocused),
|
||||
"data-hover": dataAttr(isHovered),
|
||||
"data-focus-visible": dataAttr(isFocusVisible),
|
||||
"data-focused": dataAttr(isFocused),
|
||||
className: clsx(isFocusVisible && [...ringClasses], className),
|
||||
...mergeProps(props, pressProps, focusProps, otherProps),
|
||||
...mergeProps(props, pressProps, focusProps, hoverProps, otherProps),
|
||||
className: clsx(className, props.className),
|
||||
onClick: chain(pressProps.onClick, onClick),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -64,7 +64,6 @@ interface Props extends Omit<HTMLNextUIProps<"ul">, "onChange"> {
|
||||
* ```ts
|
||||
* <Pagination classNames={{
|
||||
* base:"base-classes",
|
||||
* wrapper: "wrapper-classes",
|
||||
* prev: "prev-classes", // prev button classes
|
||||
* item: "item-classes",
|
||||
* next: "next-classes", // next button classes
|
||||
@ -214,7 +213,7 @@ export function usePagination(originalProps: UsePaginationProps) {
|
||||
"data-dots-jump": dotsJump,
|
||||
"data-total": total,
|
||||
"data-active-page": activePage,
|
||||
className: slots.base({class: baseStyles}),
|
||||
className: slots.base({class: clsx(baseStyles, props?.className)}),
|
||||
...otherProps,
|
||||
};
|
||||
};
|
||||
@ -224,7 +223,7 @@ export function usePagination(originalProps: UsePaginationProps) {
|
||||
...props,
|
||||
ref: (node) => getItemRef(node, props.value),
|
||||
isActive: props.value === activePage,
|
||||
className: slots.item({class: classNames?.item}),
|
||||
className: slots.item({class: clsx(classNames?.item, props?.className)}),
|
||||
onPress: () => {
|
||||
if (props.value !== activePage) {
|
||||
setPage(props.value);
|
||||
@ -238,7 +237,7 @@ export function usePagination(originalProps: UsePaginationProps) {
|
||||
...props,
|
||||
ref: cursorRef,
|
||||
activePage,
|
||||
className: slots.cursor({class: classNames?.cursor}),
|
||||
className: slots.cursor({class: clsx(classNames?.cursor, props?.className)}),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@ import type {HTMLMotionProps} from "framer-motion";
|
||||
import {DOMAttributes, ReactNode, useMemo, useRef} from "react";
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {DismissButton} from "@react-aria/overlays";
|
||||
import {FocusScope} from "@react-aria/focus";
|
||||
import {TRANSITION_VARIANTS} from "@nextui-org/framer-transitions";
|
||||
import {motion} from "framer-motion";
|
||||
import {getTransformOrigins} from "@nextui-org/aria-utils";
|
||||
@ -54,9 +53,7 @@ const PopoverContent = forwardRef<PopoverContentProps, "section">((props, _) =>
|
||||
<>
|
||||
<DismissButton onDismiss={onClose} />
|
||||
<Component {...getDialogProps(mergeProps(dialogProps, otherProps))} ref={dialogRef}>
|
||||
<FocusScope contain restoreFocus>
|
||||
{typeof children === "function" ? children(titleProps) : children}
|
||||
</FocusScope>
|
||||
{typeof children === "function" ? children(titleProps) : children}
|
||||
{arrowContent}
|
||||
</Component>
|
||||
<DismissButton onDismiss={onClose} />
|
||||
|
||||
@ -16,7 +16,7 @@ import {toReactAriaPlacement, getArrowPlacement} from "@nextui-org/aria-utils";
|
||||
import {popover} from "@nextui-org/theme";
|
||||
import {mergeProps, mergeRefs} from "@react-aria/utils";
|
||||
import {createDOMRef} from "@nextui-org/dom-utils";
|
||||
import {ReactRef, clsx} from "@nextui-org/shared-utils";
|
||||
import {ReactRef, clsx, dataAttr} from "@nextui-org/shared-utils";
|
||||
import {useId, useMemo, useCallback, useImperativeHandle, useRef} from "react";
|
||||
|
||||
export interface Props extends HTMLNextUIProps<"div"> {
|
||||
@ -154,15 +154,14 @@ export function usePopover(originalProps: UsePopoverProps) {
|
||||
|
||||
const {triggerProps} = useOverlayTrigger({type: triggerType}, state, triggerRef);
|
||||
|
||||
const {isFocusVisible, focusProps} = useFocusRing();
|
||||
const {isFocusVisible, isFocused, focusProps} = useFocusRing();
|
||||
|
||||
const slots = useMemo(
|
||||
() =>
|
||||
popover({
|
||||
...variantProps,
|
||||
isFocusVisible,
|
||||
}),
|
||||
[...Object.values(variantProps), isFocusVisible],
|
||||
[...Object.values(variantProps)],
|
||||
);
|
||||
|
||||
const baseStyles = clsx(classNames?.base, className);
|
||||
@ -175,6 +174,9 @@ export function usePopover(originalProps: UsePopoverProps) {
|
||||
|
||||
const getDialogProps: PropGetter = (props = {}) => ({
|
||||
className: slots.base({class: clsx(baseStyles, props.className)}),
|
||||
"data-open": dataAttr(state.isOpen),
|
||||
"data-focus": dataAttr(isFocused),
|
||||
"data-focus-visible": dataAttr(isFocusVisible),
|
||||
...mergeProps(focusProps, props),
|
||||
style: {
|
||||
// this prevent the dialog to have a default outline
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
import React from "react";
|
||||
import {ComponentStory, ComponentMeta} from "@storybook/react";
|
||||
import {popover, ButtonVariantProps} from "@nextui-org/theme";
|
||||
@ -379,7 +380,7 @@ const WithFormTemplate: ComponentStory<typeof Popover> = (args: PopoverProps) =>
|
||||
Dimensions
|
||||
</p>
|
||||
<div className="mt-2 flex flex-col gap-2 w-full">
|
||||
<Input defaultValue="100%" label="Width" size="sm" variant="bordered" />
|
||||
<Input autoFocus defaultValue="100%" label="Width" size="sm" variant="bordered" />
|
||||
<Input defaultValue="300px" label="Max. width" size="sm" variant="bordered" />
|
||||
<Input defaultValue="24px" label="Height" size="sm" variant="bordered" />
|
||||
<Input defaultValue="30px" label="Max. height" size="sm" variant="bordered" />
|
||||
|
||||
@ -48,7 +48,7 @@ interface Props extends HTMLNextUIProps<"label"> {
|
||||
|
||||
export type UseRadioProps = Omit<Props, "defaultChecked"> &
|
||||
Omit<AriaRadioProps, keyof RadioVariantProps> &
|
||||
Omit<RadioVariantProps, "isFocusVisible">;
|
||||
RadioVariantProps;
|
||||
|
||||
export function useRadio(props: UseRadioProps) {
|
||||
const groupContext = useRadioGroupContext();
|
||||
|
||||
@ -43,7 +43,9 @@
|
||||
"@nextui-org/dom-utils": "workspace:*",
|
||||
"@nextui-org/use-clipboard": "workspace:*",
|
||||
"@nextui-org/tooltip": "workspace:*",
|
||||
"@react-aria/focus": "^3.12.0"
|
||||
"@react-aria/focus": "^3.12.0",
|
||||
"@react-aria/interactions": "^3.15.0",
|
||||
"@react-aria/utils": "^3.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-package": "2.2.0",
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {clsx} from "@nextui-org/shared-utils";
|
||||
import {Tooltip} from "@nextui-org/tooltip";
|
||||
import {ReactNode, useCallback, useMemo} from "react";
|
||||
|
||||
@ -26,9 +25,9 @@ const Snippet = forwardRef<SnippetProps, "div">((props, ref) => {
|
||||
hideCopyButton,
|
||||
tooltipProps,
|
||||
isMultiLine,
|
||||
focusProps,
|
||||
onCopy,
|
||||
getSnippetProps,
|
||||
getCopyButtonProps,
|
||||
} = useSnippet({ref, ...props});
|
||||
|
||||
const TooltipContent = useCallback(
|
||||
@ -41,17 +40,7 @@ const Snippet = forwardRef<SnippetProps, "div">((props, ref) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const copyButton = (
|
||||
<button
|
||||
className={slots.copy({
|
||||
class: clsx(disableCopy && "opacity-50 cursor-not-allowed", classNames?.copy),
|
||||
})}
|
||||
onClick={onCopy}
|
||||
{...focusProps}
|
||||
>
|
||||
{copied ? checkIcon : copyIcon}
|
||||
</button>
|
||||
);
|
||||
const copyButton = <button {...getCopyButtonProps()}>{copied ? checkIcon : copyIcon}</button>;
|
||||
|
||||
if (disableTooltip) {
|
||||
return copyButton;
|
||||
|
||||
@ -3,11 +3,13 @@ import type {SnippetVariantProps, SnippetSlots, SlotsToClasses} from "@nextui-or
|
||||
import {snippet} from "@nextui-org/theme";
|
||||
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {clsx, ReactRef} from "@nextui-org/shared-utils";
|
||||
import {clsx, dataAttr, ReactRef} from "@nextui-org/shared-utils";
|
||||
import {useClipboard} from "@nextui-org/use-clipboard";
|
||||
import {useFocusRing} from "@react-aria/focus";
|
||||
import {useMemo, useCallback} from "react";
|
||||
import {TooltipProps} from "@nextui-org/tooltip";
|
||||
import {usePress} from "@react-aria/interactions";
|
||||
import {mergeProps} from "@react-aria/utils";
|
||||
export interface UseSnippetProps
|
||||
extends Omit<HTMLNextUIProps<"div">, "onCopy">,
|
||||
SnippetVariantProps {
|
||||
@ -79,6 +81,14 @@ export interface UseSnippetProps
|
||||
hideSymbol?: boolean;
|
||||
/**
|
||||
* Tooltip props.
|
||||
* @default {
|
||||
* offset: 15,
|
||||
* delay: 1000,
|
||||
* content: "Copy to clipboard",
|
||||
* variant: snippetProps?.variant, // same as the snippet variant
|
||||
* color: snippetProps?.color, // same as the snippet color
|
||||
* isDisabled: disableCopy,
|
||||
* }
|
||||
*/
|
||||
tooltipProps?: TooltipProps;
|
||||
/**
|
||||
@ -107,6 +117,7 @@ export function useSnippet(originalProps: UseSnippetProps) {
|
||||
onCopy: onCopyProp,
|
||||
tooltipProps = {
|
||||
offset: 15,
|
||||
delay: 1000,
|
||||
content: "Copy to clipboard",
|
||||
variant: originalProps?.variant as TooltipProps["variant"],
|
||||
color: originalProps?.color as TooltipProps["color"],
|
||||
@ -124,7 +135,7 @@ export function useSnippet(originalProps: UseSnippetProps) {
|
||||
|
||||
const isMultiLine = children && Array.isArray(children);
|
||||
|
||||
const {isFocusVisible, focusProps} = useFocusRing({
|
||||
const {isFocusVisible, isFocused, focusProps} = useFocusRing({
|
||||
autoFocus,
|
||||
});
|
||||
|
||||
@ -132,9 +143,8 @@ export function useSnippet(originalProps: UseSnippetProps) {
|
||||
() =>
|
||||
snippet({
|
||||
...variantProps,
|
||||
isFocusVisible,
|
||||
}),
|
||||
[...Object.values(variantProps), isFocusVisible],
|
||||
[...Object.values(variantProps)],
|
||||
);
|
||||
|
||||
const symbolBefore = useMemo(() => {
|
||||
@ -172,6 +182,33 @@ export function useSnippet(originalProps: UseSnippetProps) {
|
||||
onCopyProp?.(value);
|
||||
}, [copy, disableCopy, onCopyProp, children]);
|
||||
|
||||
const {isPressed: isCopyPressed, pressProps: copyButtonPressProps} = usePress({
|
||||
isDisabled: disableCopy,
|
||||
onPress: onCopy,
|
||||
});
|
||||
|
||||
const getCopyButtonProps = useCallback<PropGetter>(
|
||||
(props = {}) => ({
|
||||
...mergeProps(copyButtonPressProps, focusProps, props),
|
||||
"data-focus": dataAttr(isFocused),
|
||||
"data-focus-visible": dataAttr(isFocusVisible),
|
||||
"data-pressed": dataAttr(isCopyPressed),
|
||||
className: slots.copy({
|
||||
class: clsx(disableCopy && "opacity-50 cursor-not-allowed", classNames?.copy),
|
||||
}),
|
||||
}),
|
||||
[
|
||||
slots,
|
||||
isCopyPressed,
|
||||
isFocusVisible,
|
||||
isFocused,
|
||||
disableCopy,
|
||||
classNames?.copy,
|
||||
copyButtonPressProps,
|
||||
focusProps,
|
||||
],
|
||||
);
|
||||
|
||||
return {
|
||||
Component,
|
||||
as,
|
||||
@ -186,13 +223,13 @@ export function useSnippet(originalProps: UseSnippetProps) {
|
||||
symbolBefore,
|
||||
isMultiLine,
|
||||
isFocusVisible,
|
||||
focusProps,
|
||||
hideCopyButton,
|
||||
disableCopy,
|
||||
disableTooltip,
|
||||
hideSymbol,
|
||||
tooltipProps,
|
||||
getSnippetProps,
|
||||
getCopyButtonProps,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
import type {UserVariantProps, SlotsToClasses, UserSlots} from "@nextui-org/theme";
|
||||
import type {SlotsToClasses, UserSlots} from "@nextui-org/theme";
|
||||
import type {AvatarProps} from "@nextui-org/avatar";
|
||||
|
||||
import {ReactNode, useMemo, useCallback} from "react";
|
||||
import {useFocusRing} from "@react-aria/focus";
|
||||
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
|
||||
import {user} from "@nextui-org/theme";
|
||||
import {ReactRef, clsx} from "@nextui-org/shared-utils";
|
||||
import {ReactRef, clsx, dataAttr} from "@nextui-org/shared-utils";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {mergeProps} from "@react-aria/utils";
|
||||
export interface UseUserProps
|
||||
extends Omit<HTMLNextUIProps<"div", UserVariantProps>, "children" | "isFocusVisible"> {
|
||||
export interface UseUserProps extends Omit<HTMLNextUIProps<"div">, "children"> {
|
||||
/**
|
||||
* Ref to the DOM node.
|
||||
*/
|
||||
@ -69,13 +68,13 @@ export function useUser(props: UseUserProps) {
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const {isFocusVisible, focusProps} = useFocusRing();
|
||||
const {isFocusVisible, isFocused, focusProps} = useFocusRing();
|
||||
|
||||
const canBeFocused = useMemo(() => {
|
||||
return isFocusable || as === "button";
|
||||
}, [isFocusable, as]);
|
||||
|
||||
const slots = useMemo(() => user({isFocusVisible}), [isFocusVisible]);
|
||||
const slots = useMemo(() => user(), []);
|
||||
|
||||
const baseStyles = clsx(classNames?.base, className);
|
||||
|
||||
@ -99,6 +98,8 @@ export function useUser(props: UseUserProps) {
|
||||
() => ({
|
||||
ref: domRef,
|
||||
tabIndex: canBeFocused ? 0 : -1,
|
||||
"data-focus-visible": dataAttr(isFocusVisible),
|
||||
"data-focused": dataAttr(isFocused),
|
||||
className: slots.base({
|
||||
class: clsx(baseStyles, buttonStyles),
|
||||
}),
|
||||
|
||||
@ -43,7 +43,7 @@ const accordionItem = tv({
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-2",
|
||||
"data-[focus-visible=true]:!ring-primary",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-background",
|
||||
"data-[focus-visible=true]:dark:ring-offset-background-dark",
|
||||
|
||||
@ -31,7 +31,7 @@ const avatar = tv({
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-2",
|
||||
"data-[focus-visible=true]:!ring-primary",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-background",
|
||||
"data-[focus-visible=true]:dark:ring-offset-background-dark",
|
||||
|
||||
@ -41,7 +41,7 @@ const button = tv({
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-2",
|
||||
"data-[focus-visible=true]:!ring-primary",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-background",
|
||||
"data-[focus-visible=true]:dark:ring-offset-background-dark",
|
||||
|
||||
@ -33,7 +33,7 @@ const card = tv({
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-2",
|
||||
"data-[focus-visible=true]:!ring-primary",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-background",
|
||||
"data-[focus-visible=true]:dark:ring-offset-background-dark",
|
||||
|
||||
@ -2,15 +2,13 @@ import type {VariantProps} from "tailwind-variants";
|
||||
|
||||
import {tv} from "tailwind-variants";
|
||||
|
||||
import {ringClasses} from "../utils";
|
||||
|
||||
/**
|
||||
* DropdownItem wrapper **Tailwind Variants** component
|
||||
*
|
||||
* const {base, heading, indicator, trigger, leftIndicator, title, subtitle, content } = dropdownItem({...})
|
||||
*
|
||||
* @example
|
||||
* <div className={base())}>
|
||||
* <div className={base())} data-focus-visible={boolean} data-hover={boolean}>
|
||||
* <div className={heading())}>
|
||||
* <button className={trigger())}>
|
||||
* <div className={leftIndicator()}>
|
||||
@ -43,6 +41,13 @@ const dropdownItem = tv({
|
||||
"rounded-lg",
|
||||
"outline-none",
|
||||
"cursor-pointer",
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-2",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-background",
|
||||
"data-[focus-visible=true]:dark:ring-offset-background-content1",
|
||||
],
|
||||
wrapper: "w-full flex flex-col items-start justify-center",
|
||||
title: "flex-1",
|
||||
@ -73,13 +78,13 @@ const dropdownItem = tv({
|
||||
base: "bg-transparent",
|
||||
},
|
||||
faded: {
|
||||
base: "border border-transparent hover:border-neutral hover:bg-neutral-100",
|
||||
base: "border border-transparent hover:border-neutral data-[hover=true]:bg-neutral-100",
|
||||
},
|
||||
flat: {
|
||||
base: "",
|
||||
},
|
||||
shadow: {
|
||||
base: "hover:shadow-lg",
|
||||
base: "data-[hover=true]:shadow-lg",
|
||||
},
|
||||
},
|
||||
color: {
|
||||
@ -109,11 +114,6 @@ const dropdownItem = tv({
|
||||
base: "opacity-50 pointer-events-none",
|
||||
},
|
||||
},
|
||||
isFocusVisible: {
|
||||
true: {
|
||||
base: [...ringClasses],
|
||||
},
|
||||
},
|
||||
disableAnimation: {
|
||||
true: {},
|
||||
false: {},
|
||||
@ -130,42 +130,42 @@ const dropdownItem = tv({
|
||||
variant: "solid",
|
||||
color: "neutral",
|
||||
class: {
|
||||
base: "hover:bg-neutral hover:text-neutral-contrastText",
|
||||
base: "data-[hover=true]:bg-neutral data-[hover=true]:text-neutral-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "solid",
|
||||
color: "primary",
|
||||
class: {
|
||||
base: "hover:bg-primary hover:text-primary-contrastText",
|
||||
base: "data-[hover=true]:bg-primary data-[hover=true]:text-primary-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "solid",
|
||||
color: "secondary",
|
||||
class: {
|
||||
base: "hover:bg-secondary hover:text-secondary-contrastText",
|
||||
base: "data-[hover=true]:bg-secondary data-[hover=true]:text-secondary-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "solid",
|
||||
color: "success",
|
||||
class: {
|
||||
base: "hover:bg-success hover:text-success-contrastText",
|
||||
base: "data-[hover=true]:bg-success data-[hover=true]:text-success-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "solid",
|
||||
color: "warning",
|
||||
class: {
|
||||
base: "hover:bg-warning hover:text-warning-contrastText",
|
||||
base: "data-[hover=true]:bg-warning data-[hover=true]:text-warning-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "solid",
|
||||
color: "danger",
|
||||
class: {
|
||||
base: "hover:bg-danger hover:text-danger-contrastText",
|
||||
base: "data-[hover=true]:bg-danger data-[hover=true]:text-danger-contrastText",
|
||||
},
|
||||
},
|
||||
// shadow / color
|
||||
@ -173,42 +173,48 @@ const dropdownItem = tv({
|
||||
variant: "shadow",
|
||||
color: "neutral",
|
||||
class: {
|
||||
base: "hover:shadow-neutral/50 hover:bg-neutral hover:text-neutral-contrastText",
|
||||
base:
|
||||
"data-[hover=true]:shadow-neutral/50 data-[hover=true]:bg-neutral data-[hover=true]:text-neutral-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "shadow",
|
||||
color: "primary",
|
||||
class: {
|
||||
base: "hover:shadow-primary/30 hover:bg-primary hover:text-primary-contrastText",
|
||||
base:
|
||||
"data-[hover=true]:shadow-primary/30 data-[hover=true]:bg-primary data-[hover=true]:text-primary-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "shadow",
|
||||
color: "secondary",
|
||||
class: {
|
||||
base: "hover:shadow-secondary/30 hover:bg-secondary hover:text-secondary-contrastText",
|
||||
base:
|
||||
"data-[hover=true]:shadow-secondary/30 data-[hover=true]:bg-secondary data-[hover=true]:text-secondary-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "shadow",
|
||||
color: "success",
|
||||
class: {
|
||||
base: "hover:shadow-success/30 hover:bg-success hover:text-success-contrastText",
|
||||
base:
|
||||
"data-[hover=true]:shadow-success/30 data-[hover=true]:bg-success data-[hover=true]:text-success-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "shadow",
|
||||
color: "warning",
|
||||
class: {
|
||||
base: "hover:shadow-warning/30 hover:bg-warning hover:text-warning-contrastText",
|
||||
base:
|
||||
"data-[hover=true]:shadow-warning/30 data-[hover=true]:bg-warning data-[hover=true]:text-warning-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "shadow",
|
||||
color: "danger",
|
||||
class: {
|
||||
base: "hover:shadow-danger/30 hover:bg-danger hover:text-danger-contrastText",
|
||||
base:
|
||||
"data-[hover=true]:shadow-danger/30 data-[hover=true]:bg-danger data-[hover=true]:text-danger-contrastText",
|
||||
},
|
||||
},
|
||||
// bordered / color
|
||||
@ -216,42 +222,42 @@ const dropdownItem = tv({
|
||||
variant: "bordered",
|
||||
color: "neutral",
|
||||
class: {
|
||||
base: "hover:border-neutral",
|
||||
base: "data-[hover=true]:border-neutral",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "primary",
|
||||
class: {
|
||||
base: "hover:border-primary hover:text-primary",
|
||||
base: "data-[hover=true]:border-primary data-[hover=true]:text-primary",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "secondary",
|
||||
class: {
|
||||
base: "hover:border-secondary hover:text-secondary",
|
||||
base: "data-[hover=true]:border-secondary data-[hover=true]:text-secondary",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "success",
|
||||
class: {
|
||||
base: "hover:border-success hover:text-success",
|
||||
base: "data-[hover=true]:border-success data-[hover=true]:text-success",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "warning",
|
||||
class: {
|
||||
base: "hover:border-warning hover:text-warning",
|
||||
base: "data-[hover=true]:border-warning data-[hover=true]:text-warning",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "danger",
|
||||
class: {
|
||||
base: "hover:border-danger hover:text-danger",
|
||||
base: "data-[hover=true]:border-danger data-[hover=true]:text-danger",
|
||||
},
|
||||
},
|
||||
// flat / color
|
||||
@ -259,42 +265,42 @@ const dropdownItem = tv({
|
||||
variant: "flat",
|
||||
color: "neutral",
|
||||
class: {
|
||||
base: "hover:bg-neutral-100 hover:text-neutral-contrastText",
|
||||
base: "data-[hover=true]:bg-neutral-100 data-[hover=true]:text-neutral-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "flat",
|
||||
color: "primary",
|
||||
class: {
|
||||
base: "hover:bg-primary-50 hover:text-primary",
|
||||
base: "data-[hover=true]:bg-primary-50 data-[hover=true]:text-primary",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "flat",
|
||||
color: "secondary",
|
||||
class: {
|
||||
base: "hover:bg-secondary-100 hover:text-secondary",
|
||||
base: "data-[hover=true]:bg-secondary-100 data-[hover=true]:text-secondary",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "flat",
|
||||
color: "success",
|
||||
class: {
|
||||
base: "hover:bg-success-50 hover:text-success",
|
||||
base: "data-[hover=true]:bg-success-50 data-[hover=true]:text-success",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "flat",
|
||||
color: "warning",
|
||||
class: {
|
||||
base: "hover:bg-warning-50 hover:text-warning",
|
||||
base: "data-[hover=true]:bg-warning-50 data-[hover=true]:text-warning",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "flat",
|
||||
color: "danger",
|
||||
class: {
|
||||
base: "hover:bg-danger-50 hover:text-danger",
|
||||
base: "data-[hover=true]:bg-danger-50 data-[hover=true]:text-danger",
|
||||
},
|
||||
},
|
||||
// faded / color
|
||||
@ -302,42 +308,42 @@ const dropdownItem = tv({
|
||||
variant: "faded",
|
||||
color: "neutral",
|
||||
class: {
|
||||
base: "hover:text-neutral-contrastText",
|
||||
base: "data-[hover=true]:text-neutral-contrastText",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "faded",
|
||||
color: "primary",
|
||||
class: {
|
||||
base: "hover:text-primary",
|
||||
base: "data-[hover=true]:text-primary",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "faded",
|
||||
color: "secondary",
|
||||
class: {
|
||||
base: "hover:text-secondary",
|
||||
base: "data-[hover=true]:text-secondary",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "faded",
|
||||
color: "success",
|
||||
class: {
|
||||
base: "hover:text-success",
|
||||
base: "data-[hover=true]:text-success",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "faded",
|
||||
color: "warning",
|
||||
class: {
|
||||
base: "hover:text-warning",
|
||||
base: "data-[hover=true]:text-warning",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "faded",
|
||||
color: "danger",
|
||||
class: {
|
||||
base: "hover:text-danger",
|
||||
base: "data-[hover=true]:text-danger",
|
||||
},
|
||||
},
|
||||
// light / color
|
||||
@ -345,42 +351,42 @@ const dropdownItem = tv({
|
||||
variant: "light",
|
||||
color: "neutral",
|
||||
class: {
|
||||
base: "hover:text-neutral-500",
|
||||
base: "data-[hover=true]:text-neutral-500",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "light",
|
||||
color: "primary",
|
||||
class: {
|
||||
base: "hover:text-primary",
|
||||
base: "data-[hover=true]:text-primary",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "light",
|
||||
color: "secondary",
|
||||
class: {
|
||||
base: "hover:text-secondary",
|
||||
base: "data-[hover=true]:text-secondary",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "light",
|
||||
color: "success",
|
||||
class: {
|
||||
base: "hover:text-success",
|
||||
base: "data-[hover=true]:text-success",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "light",
|
||||
color: "warning",
|
||||
class: {
|
||||
base: "hover:text-warning",
|
||||
base: "data-[hover=true]:text-warning",
|
||||
},
|
||||
},
|
||||
{
|
||||
variant: "light",
|
||||
color: "danger",
|
||||
class: {
|
||||
base: "hover:text-danger",
|
||||
base: "data-[hover=true]:text-danger",
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@ -2,7 +2,7 @@ import type {VariantProps} from "tailwind-variants";
|
||||
|
||||
import {tv} from "tailwind-variants";
|
||||
|
||||
import {colorVariants, ringClasses} from "../utils";
|
||||
import {colorVariants} from "../utils";
|
||||
|
||||
/**
|
||||
* Pagination wrapper **Tailwind Variants** component
|
||||
@ -23,7 +23,7 @@ import {colorVariants, ringClasses} from "../utils";
|
||||
const pagination = tv({
|
||||
slots: {
|
||||
base: "flex flex-wrap relative items-center gap-1 max-w-fit",
|
||||
item: "",
|
||||
item: [],
|
||||
prev: "",
|
||||
next: "",
|
||||
cursor: [
|
||||
@ -39,7 +39,12 @@ const pagination = tv({
|
||||
variants: {
|
||||
variant: {
|
||||
bordered: {
|
||||
item: ["border-1.5", "border-neutral", "bg-transparent", "hover:bg-neutral-100"],
|
||||
item: [
|
||||
"border-1.5",
|
||||
"border-neutral",
|
||||
"bg-transparent",
|
||||
"data-[hover=true]:bg-neutral-100",
|
||||
],
|
||||
},
|
||||
light: {
|
||||
item: "bg-transparent",
|
||||
@ -102,11 +107,6 @@ const pagination = tv({
|
||||
base: "opacity-50 pointer-events-none",
|
||||
},
|
||||
},
|
||||
isFocusVisible: {
|
||||
true: {
|
||||
wrapper: [...ringClasses],
|
||||
},
|
||||
},
|
||||
showShadow: {
|
||||
true: {},
|
||||
},
|
||||
@ -325,22 +325,32 @@ const pagination = tv({
|
||||
"items-center",
|
||||
"justify-center",
|
||||
"text-neutral-contrastText",
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-2",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-background",
|
||||
"data-[focus-visible=true]:dark:ring-offset-background-dark",
|
||||
// disabled
|
||||
"data-[disabled=true]:opacity-50",
|
||||
"data-[disabled=true]:pointer-events-none",
|
||||
],
|
||||
},
|
||||
{
|
||||
slots: ["item", "prev", "next"],
|
||||
variant: "flat",
|
||||
class: ["bg-neutral-100", "hover:bg-neutral-200", "active:bg-neutral-300"],
|
||||
class: ["bg-neutral-100", "data-[hover=true]:bg-neutral-200", "active:bg-neutral-300"],
|
||||
},
|
||||
{
|
||||
slots: ["item", "prev", "next"],
|
||||
variant: "faded",
|
||||
class: ["bg-neutral-100", "hover:bg-neutral-200", "active:bg-neutral-300"],
|
||||
class: ["bg-neutral-100", "data-[hover=true]:bg-neutral-200", "active:bg-neutral-300"],
|
||||
},
|
||||
{
|
||||
slots: ["item", "prev", "next"],
|
||||
variant: "light",
|
||||
class: ["hover:bg-neutral-100", "active:bg-neutral-200"],
|
||||
class: ["data-[hover=true]:bg-neutral-100", "active:bg-neutral-200"],
|
||||
},
|
||||
// size
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@ import type {VariantProps} from "tailwind-variants";
|
||||
|
||||
import {tv} from "tailwind-variants";
|
||||
|
||||
import {colorVariants, ringClasses} from "../utils";
|
||||
import {colorVariants} from "../utils";
|
||||
/**
|
||||
* Popover wrapper **Tailwind Variants** component
|
||||
*
|
||||
@ -31,6 +31,13 @@ const popover = tv({
|
||||
"py-1",
|
||||
"text-base",
|
||||
"!outline-none",
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-2",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-background",
|
||||
"data-[focus-visible=true]:dark:ring-offset-background-dark",
|
||||
],
|
||||
trigger: ["z-10"],
|
||||
backdrop: ["hidden"],
|
||||
@ -111,11 +118,6 @@ const popover = tv({
|
||||
backdrop: "backdrop-blur-sm backdrop-saturate-150 bg-black/20",
|
||||
},
|
||||
},
|
||||
isFocusVisible: {
|
||||
true: {
|
||||
base: [...ringClasses],
|
||||
},
|
||||
},
|
||||
triggerScaleOnOpen: {
|
||||
true: {
|
||||
trigger: ["aria-expanded:scale-95", "aria-expanded:opacity-70", "subpixel-antialiased"],
|
||||
|
||||
@ -2,7 +2,7 @@ import type {VariantProps} from "tailwind-variants";
|
||||
|
||||
import {tv} from "tailwind-variants";
|
||||
|
||||
import {ringClasses, colorVariants} from "../utils";
|
||||
import {colorVariants} from "../utils";
|
||||
|
||||
/**
|
||||
* Snippet wrapper **Tailwind Variants** component
|
||||
@ -25,7 +25,16 @@ const snippet = tv({
|
||||
slots: {
|
||||
base: "inline-flex items-center justify-between space-x-3 rounded-md",
|
||||
pre: "bg-transparent text-inherit font-mono whitespace-pre-wrap",
|
||||
copy: "z-10 appearance-none outline-none",
|
||||
copy: [
|
||||
"z-10 appearance-none outline-none rounded-sm",
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-1",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-transparent",
|
||||
"data-[focus-visible=true]:dark:ring-offset-transparent",
|
||||
],
|
||||
},
|
||||
variants: {
|
||||
variant: {
|
||||
@ -99,17 +108,6 @@ const snippet = tv({
|
||||
base: "w-full",
|
||||
},
|
||||
},
|
||||
isFocusVisible: {
|
||||
true: {
|
||||
copy: [
|
||||
...ringClasses,
|
||||
"ring-1",
|
||||
"rounded-sm",
|
||||
"ring-offset-transparent",
|
||||
"dark:ring-offset-transparent",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
color: "neutral",
|
||||
@ -117,7 +115,6 @@ const snippet = tv({
|
||||
size: "md",
|
||||
radius: "lg",
|
||||
fullWidth: false,
|
||||
isFocusVisible: false,
|
||||
},
|
||||
compoundVariants: [
|
||||
// solid & shadow / color
|
||||
|
||||
@ -105,21 +105,6 @@ const toggle = tv({
|
||||
},
|
||||
size: {
|
||||
xs: {
|
||||
wrapper: "px-0.5 w-7 h-4 mr-1",
|
||||
thumb: [
|
||||
"w-3 h-3 text-[0.5rem]",
|
||||
//checked
|
||||
"group-data-[checked=true]:ml-3",
|
||||
// pressed
|
||||
"group-data-[pressed=true]:w-4",
|
||||
"group-data-[checked]:group-data-[pressed]:ml-2",
|
||||
],
|
||||
startIcon: "text-[0.5rem] left-1",
|
||||
endIcon: "text-[0.5rem] right-1",
|
||||
right: "text-[0.5rem]",
|
||||
label: "text-xs",
|
||||
},
|
||||
sm: {
|
||||
wrapper: "w-8 h-5 mr-1",
|
||||
thumb: [
|
||||
"w-3 h-3 text-[0.6rem]",
|
||||
@ -133,7 +118,7 @@ const toggle = tv({
|
||||
endIcon: "text-[0.6rem] right-1",
|
||||
label: "text-sm",
|
||||
},
|
||||
md: {
|
||||
sm: {
|
||||
wrapper: "w-10 h-6 mr-2",
|
||||
thumb: [
|
||||
"w-4 h-4 text-xs",
|
||||
@ -147,7 +132,7 @@ const toggle = tv({
|
||||
startIcon: "text-xs",
|
||||
label: "text-base",
|
||||
},
|
||||
lg: {
|
||||
md: {
|
||||
wrapper: "w-12 h-7 mr-2",
|
||||
thumb: [
|
||||
"w-5 h-5 text-sm",
|
||||
@ -161,7 +146,7 @@ const toggle = tv({
|
||||
startIcon: "text-sm",
|
||||
label: "text-lg",
|
||||
},
|
||||
xl: {
|
||||
lg: {
|
||||
wrapper: "w-14 h-8 mr-2",
|
||||
thumb: [
|
||||
"w-6 h-6 text-base",
|
||||
@ -175,6 +160,20 @@ const toggle = tv({
|
||||
startIcon: "text-base",
|
||||
label: "text-xl",
|
||||
},
|
||||
xl: {
|
||||
wrapper: "w-16 h-9 mr-2",
|
||||
thumb: [
|
||||
"w-7 h-7 text-lg",
|
||||
//checked
|
||||
"group-data-[checked=true]:ml-7",
|
||||
// pressed
|
||||
"group-data-[pressed=true]:w-8",
|
||||
"group-data-[checked]:group-data-[pressed]:ml-6",
|
||||
],
|
||||
endIcon: "text-base",
|
||||
startIcon: "text-base",
|
||||
label: "text-xl",
|
||||
},
|
||||
},
|
||||
isDisabled: {
|
||||
true: {
|
||||
@ -207,7 +206,7 @@ const toggle = tv({
|
||||
},
|
||||
defaultVariants: {
|
||||
color: "primary",
|
||||
size: "lg",
|
||||
size: "md",
|
||||
isDisabled: false,
|
||||
disableAnimation: false,
|
||||
},
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
import type {VariantProps} from "tailwind-variants";
|
||||
|
||||
import {tv} from "tailwind-variants";
|
||||
|
||||
import {ringClasses} from "../utils";
|
||||
|
||||
/**
|
||||
* User wrapper **Tailwind Variants** component
|
||||
*
|
||||
@ -20,21 +16,22 @@ import {ringClasses} from "../utils";
|
||||
*/
|
||||
const user = tv({
|
||||
slots: {
|
||||
base: "inline-flex items-center justify-center gap-2",
|
||||
base: [
|
||||
"inline-flex items-center justify-center gap-2 rounded-sm",
|
||||
// focus ring
|
||||
"data-[focus-visible=true]:outline-none",
|
||||
"data-[focus-visible=true]:ring-2",
|
||||
"data-[focus-visible=true]:ring-primary",
|
||||
"data-[focus-visible=true]:ring-offset-2",
|
||||
"data-[focus-visible=true]:ring-offset-background",
|
||||
"data-[focus-visible=true]:dark:ring-offset-background-dark",
|
||||
],
|
||||
wrapper: "inline-flex flex-col items-start",
|
||||
name: "text-sm text-foreground dark:text-foreground-dark",
|
||||
description: "text-xs text-neutral-500",
|
||||
},
|
||||
variants: {
|
||||
isFocusVisible: {
|
||||
true: {
|
||||
base: [...ringClasses, "rounded-sm"],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export type UserVariantProps = VariantProps<typeof user>;
|
||||
export type UserSlots = keyof ReturnType<typeof user>;
|
||||
|
||||
export {user};
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@ -1290,6 +1290,12 @@ importers:
|
||||
'@react-aria/focus':
|
||||
specifier: ^3.12.0
|
||||
version: 3.12.0(react@18.2.0)
|
||||
'@react-aria/interactions':
|
||||
specifier: ^3.15.0
|
||||
version: 3.15.0(react@18.2.0)
|
||||
'@react-aria/utils':
|
||||
specifier: ^3.16.0
|
||||
version: 3.16.0(react@18.2.0)
|
||||
devDependencies:
|
||||
clean-package:
|
||||
specifier: 2.2.0
|
||||
@ -4272,7 +4278,7 @@ packages:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@types/react': 18.0.1
|
||||
clsx: 1.1.0
|
||||
clsx: 1.2.1
|
||||
focus-lock: 0.8.1
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user