mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(root): accordion animation improved, units introduced, button spacing migrated to units
This commit is contained in:
parent
5b5756bb33
commit
29f0d9a937
@ -7,15 +7,38 @@ export default function App() {
|
||||
return (
|
||||
<Accordion
|
||||
motionProps={{
|
||||
startingY: 0,
|
||||
transition: {
|
||||
variants: {
|
||||
enter: {
|
||||
height: { duration: 0.1 },
|
||||
opacity: { duration: 0.3 },
|
||||
y: 0,
|
||||
opacity: 1,
|
||||
height: "auto",
|
||||
transition: {
|
||||
height: {
|
||||
type: "spring",
|
||||
stiffness: 500,
|
||||
damping: 30,
|
||||
duration: 1,
|
||||
},
|
||||
opacity: {
|
||||
easings: "ease",
|
||||
duration: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
exit: {
|
||||
height: { duration: 0.2 },
|
||||
opacity: { duration: 0.3 },
|
||||
y: -10,
|
||||
opacity: 0,
|
||||
height: 0,
|
||||
transition: {
|
||||
height: {
|
||||
easings: "ease",
|
||||
duration: 0.25,
|
||||
},
|
||||
opacity: {
|
||||
easings: "ease",
|
||||
duration: 0.3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
@ -35,7 +35,7 @@ export default function App() {
|
||||
}}
|
||||
>
|
||||
<DropdownTrigger>
|
||||
<Button variant="ghost">Open Menu</Button>
|
||||
<Button variant="ghost" disableRipple>Open Menu</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu
|
||||
aria-label="Custom item styles"
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"version": "2.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "concurrently \"contentlayer dev\" \"next dev\"",
|
||||
"dev": "rimraf .contentlayer && concurrently \"contentlayer dev\" \"next dev\"",
|
||||
"build": "contentlayer build && next build",
|
||||
"build:analyze": "ANALYZE=true next build",
|
||||
"start": "next start",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/accordion",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Collapse display a list of high-level options that can expand/collapse to reveal more information.",
|
||||
"keywords": [
|
||||
"react",
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {useMemo, ReactNode} from "react";
|
||||
import {ChevronIcon} from "@nextui-org/shared-icons";
|
||||
import {CollapseTransition} from "@nextui-org/framer-transitions";
|
||||
import {AnimatePresence, motion} from "framer-motion";
|
||||
import {TRANSITION_VARIANTS} from "@nextui-org/framer-transitions";
|
||||
|
||||
import {UseAccordionItemProps, useAccordionItem} from "./use-accordion-item";
|
||||
|
||||
@ -46,9 +47,20 @@ const AccordionItem = forwardRef<AccordionItemProps, "div">((props, ref) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<CollapseTransition in={isOpen} {...motionProps}>
|
||||
<div {...getContentProps()}>{children}</div>
|
||||
</CollapseTransition>
|
||||
<AnimatePresence initial={false}>
|
||||
{isOpen && (
|
||||
<motion.section
|
||||
key="content"
|
||||
animate="enter"
|
||||
exit="exit"
|
||||
initial="exit"
|
||||
variants={TRANSITION_VARIANTS.collapse}
|
||||
{...motionProps}
|
||||
>
|
||||
<div {...getContentProps()}>{children}</div>
|
||||
</motion.section>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
}, [isOpen, disableAnimation, children, motionProps]);
|
||||
|
||||
|
||||
@ -3,11 +3,11 @@ import type {
|
||||
AccordionItemSlots,
|
||||
SlotsToClasses,
|
||||
} from "@nextui-org/theme";
|
||||
import type {CollapseTransitionProps} from "@nextui-org/framer-transitions";
|
||||
|
||||
import {ItemProps, BaseItem} from "@nextui-org/aria-utils";
|
||||
import {FocusableProps, PressEvents} from "@react-types/shared";
|
||||
import {ReactNode, MouseEventHandler} from "react";
|
||||
import {HTMLMotionProps} from "framer-motion";
|
||||
|
||||
export type AccordionItemIndicatorProps = {
|
||||
/**
|
||||
@ -54,7 +54,7 @@ export interface Props<T extends object = {}>
|
||||
/**
|
||||
* The props to modify the framer motion animation. Use the `variants` API to create your own animation.
|
||||
*/
|
||||
motionProps?: CollapseTransitionProps;
|
||||
motionProps?: HTMLMotionProps<"section">;
|
||||
/**
|
||||
* The native button click event handler.
|
||||
* @deprecated - use `onPress` instead.
|
||||
|
||||
@ -359,15 +359,38 @@ export const CustomMotion = Template.bind({});
|
||||
CustomMotion.args = {
|
||||
...defaultProps,
|
||||
motionProps: {
|
||||
startingY: 0,
|
||||
transition: {
|
||||
exit: {
|
||||
height: {duration: 0.2},
|
||||
opacity: {duration: 0.3},
|
||||
},
|
||||
variants: {
|
||||
enter: {
|
||||
height: {duration: 0.3},
|
||||
opacity: {duration: 0.6},
|
||||
y: 0,
|
||||
opacity: 1,
|
||||
height: "auto",
|
||||
transition: {
|
||||
height: {
|
||||
type: "spring",
|
||||
stiffness: 500,
|
||||
damping: 30,
|
||||
duration: 1,
|
||||
},
|
||||
opacity: {
|
||||
easings: "ease",
|
||||
duration: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
exit: {
|
||||
y: -10,
|
||||
opacity: 0,
|
||||
height: 0,
|
||||
transition: {
|
||||
height: {
|
||||
easings: "ease",
|
||||
duration: 0.25,
|
||||
},
|
||||
opacity: {
|
||||
easings: "ease",
|
||||
duration: 0.3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/avatar",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "The Avatar component is used to represent a user, and displays the profile picture, initials or fallback icon.",
|
||||
"keywords": [
|
||||
"avatar"
|
||||
|
||||
@ -17,7 +17,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
|
||||
@ -18,7 +18,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "2xl", "3xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/badge",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Badges are used as a small numerical value or status descriptor for UI elements.",
|
||||
"keywords": [
|
||||
"badge"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/button",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Buttons allow users to perform actions and choose with a single tap.",
|
||||
"keywords": [
|
||||
"button"
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import {Spinner} from "@nextui-org/spinner";
|
||||
import {Ripple} from "@nextui-org/ripple";
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {lazy} from "react";
|
||||
|
||||
import {UseButtonProps, useButton} from "./use-button";
|
||||
const Ripple = lazy(() => import("@nextui-org/ripple").then(({Ripple}) => ({default: Ripple})));
|
||||
|
||||
export interface ButtonProps extends Omit<UseButtonProps, "ref"> {}
|
||||
|
||||
@ -34,7 +33,7 @@ const Button = forwardRef<ButtonProps, "button">((props, ref) => {
|
||||
{children}
|
||||
{isLoading && spinnerPlacement === "end" && spinner}
|
||||
{endContent}
|
||||
{!disableRipple && <Ripple suspense ripples={ripples} />}
|
||||
{!disableRipple && <Ripple ripples={ripples} />}
|
||||
</Component>
|
||||
);
|
||||
});
|
||||
|
||||
@ -139,6 +139,7 @@ export function useButton(props: UseButtonProps) {
|
||||
} as AriaButtonProps,
|
||||
domRef,
|
||||
);
|
||||
|
||||
const {isHovered, hoverProps} = useHover({isDisabled});
|
||||
|
||||
const getButtonProps: PropGetter = useCallback(
|
||||
|
||||
@ -20,9 +20,10 @@ export default {
|
||||
options: ["default", "primary", "secondary", "success", "warning", "danger"],
|
||||
},
|
||||
},
|
||||
isRounded: {
|
||||
radius: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
type: "select",
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
|
||||
@ -41,7 +41,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["sm", "md", "lg", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
isDisabled: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/card",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Card is a container for text, photos, and actions in the context of a single subject.",
|
||||
"keywords": [
|
||||
"card"
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {lazy} from "react";
|
||||
import {Ripple} from "@nextui-org/ripple";
|
||||
|
||||
import {CardProvider} from "./card-context";
|
||||
import {useCard, UseCardProps} from "./use-card";
|
||||
|
||||
const Ripple = lazy(() => import("@nextui-org/ripple").then(({Ripple}) => ({default: Ripple})));
|
||||
|
||||
export interface CardProps extends Omit<UseCardProps, "ref"> {}
|
||||
|
||||
const Card = forwardRef<CardProps, "div">((props, ref) => {
|
||||
@ -26,7 +24,7 @@ const Card = forwardRef<CardProps, "div">((props, ref) => {
|
||||
return (
|
||||
<Component {...getCardProps()}>
|
||||
<CardProvider value={context}>{children}</CardProvider>
|
||||
{isPressable && !disableAnimation && !disableRipple && <Ripple suspense ripples={ripples} />}
|
||||
{isPressable && !disableAnimation && !disableRipple && <Ripple ripples={ripples} />}
|
||||
</Component>
|
||||
);
|
||||
});
|
||||
|
||||
@ -21,7 +21,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["sm", "md", "lg"],
|
||||
options: ["none", "sm", "md", "lg"],
|
||||
},
|
||||
},
|
||||
fullWidth: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/checkbox",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Checkboxes allow users to select multiple items from a list of individual items, or to mark one individual item as selected.",
|
||||
"keywords": [
|
||||
"checkbox"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/chip",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Chips help people enter information, make selections, filter content, or trigger actions.",
|
||||
"keywords": [
|
||||
"chip"
|
||||
|
||||
@ -25,7 +25,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/code",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Code is a component used to display inline code.",
|
||||
"keywords": [
|
||||
"code"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/divider",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": ". A separator is a visual divider between two groups of content",
|
||||
"keywords": [
|
||||
"divider"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/dropdown",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A dropdown displays a list of actions or options that a user can choose.",
|
||||
"keywords": [
|
||||
"dropdown"
|
||||
|
||||
@ -124,8 +124,7 @@ export function useDropdownItem<T extends object>(originalProps: UseDropdownItem
|
||||
ref: domRef,
|
||||
...mergeProps(
|
||||
itemProps,
|
||||
focusProps,
|
||||
isReadOnly ? {} : pressProps,
|
||||
isReadOnly ? {} : mergeProps(focusProps, pressProps),
|
||||
hoverProps,
|
||||
filterDOMProps(otherProps, {labelable: true}),
|
||||
props,
|
||||
|
||||
@ -103,7 +103,7 @@ export function useDropdown(props: UseDropdownProps) {
|
||||
...classNamesProp,
|
||||
...props.classNames,
|
||||
base: clsx(classNames, classNamesProp?.base, props.className),
|
||||
arrow: clsx("border border-default-100", classNamesProp?.arrow),
|
||||
arrow: clsx(classNamesProp?.arrow),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
placement: {
|
||||
@ -146,7 +146,7 @@ const DividerTemplate: ComponentStory<any> = ({
|
||||
<DropdownItem key="new">New file</DropdownItem>
|
||||
<DropdownItem key="copy">Copy link</DropdownItem>
|
||||
<DropdownItem key="edit">Edit file</DropdownItem>
|
||||
<DropdownItem key="delete" showDivider className="text-danger" color="danger">
|
||||
<DropdownItem key="delete" className="text-danger" color="danger">
|
||||
Delete file
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
@ -172,7 +172,7 @@ const DisabledKeysTemplate: ComponentStory<any> = ({
|
||||
<DropdownItem key="new">New file</DropdownItem>
|
||||
<DropdownItem key="copy">Copy link</DropdownItem>
|
||||
<DropdownItem key="edit">Edit file</DropdownItem>
|
||||
<DropdownItem key="delete" showDivider className="text-danger" color="danger">
|
||||
<DropdownItem key="delete" className="text-danger" color="danger">
|
||||
Delete file
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
@ -273,7 +273,7 @@ const WithShortcutTemplate: ComponentStory<any> = ({color, variant, ...args}) =>
|
||||
<DropdownItem key="edit" shortcut="⌘⇧E">
|
||||
Edit file
|
||||
</DropdownItem>
|
||||
<DropdownItem key="delete" showDivider className="text-danger" color="danger" shortcut="⌘⇧D">
|
||||
<DropdownItem key="delete" className="text-danger" color="danger" shortcut="⌘⇧D">
|
||||
Delete file
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
@ -319,7 +319,6 @@ const WithStartContentTemplate: ComponentStory<any> = ({
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
key="delete"
|
||||
showDivider
|
||||
className="text-danger"
|
||||
color="danger"
|
||||
shortcut="⌘⇧D"
|
||||
@ -359,7 +358,6 @@ const WithEndContentTemplate: ComponentStory<any> = ({
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
key="delete"
|
||||
showDivider
|
||||
className="text-danger"
|
||||
color="danger"
|
||||
endContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
|
||||
@ -413,7 +411,6 @@ const WithDescriptionTemplate: ComponentStory<any> = ({
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
key="delete"
|
||||
showDivider
|
||||
className="text-danger"
|
||||
color="danger"
|
||||
description="Permanently delete the file"
|
||||
@ -506,19 +503,13 @@ const CustomTriggerTemplate: ComponentStory<any> = ({variant, ...args}) => {
|
||||
<p className="font-semibold">Signed in as</p>
|
||||
<p className="font-semibold">zoey@example.com</p>
|
||||
</DropdownItem>
|
||||
<DropdownItem key="settings" showDivider>
|
||||
My Settings
|
||||
</DropdownItem>
|
||||
<DropdownItem key="settings">My Settings</DropdownItem>
|
||||
<DropdownItem key="team_settings">Team Settings</DropdownItem>
|
||||
<DropdownItem key="analytics" showDivider>
|
||||
Analytics
|
||||
</DropdownItem>
|
||||
<DropdownItem key="analytics">Analytics</DropdownItem>
|
||||
<DropdownItem key="system">System</DropdownItem>
|
||||
<DropdownItem key="configurations">Configurations</DropdownItem>
|
||||
<DropdownItem key="help_and_feedback" showDivider>
|
||||
Help & Feedback
|
||||
</DropdownItem>
|
||||
<DropdownItem key="logout" showDivider color="danger">
|
||||
<DropdownItem key="help_and_feedback">Help & Feedback</DropdownItem>
|
||||
<DropdownItem key="logout" color="danger">
|
||||
Log Out
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
@ -543,19 +534,13 @@ const CustomTriggerTemplate: ComponentStory<any> = ({variant, ...args}) => {
|
||||
<p className="font-bold">Signed in as</p>
|
||||
<p className="font-bold">@tonyreichert</p>
|
||||
</DropdownItem>
|
||||
<DropdownItem key="settings" showDivider>
|
||||
My Settings
|
||||
</DropdownItem>
|
||||
<DropdownItem key="settings">My Settings</DropdownItem>
|
||||
<DropdownItem key="team_settings">Team Settings</DropdownItem>
|
||||
<DropdownItem key="analytics" showDivider>
|
||||
Analytics
|
||||
</DropdownItem>
|
||||
<DropdownItem key="analytics">Analytics</DropdownItem>
|
||||
<DropdownItem key="system">System</DropdownItem>
|
||||
<DropdownItem key="configurations">Configurations</DropdownItem>
|
||||
<DropdownItem key="help_and_feedback" showDivider>
|
||||
Help & Feedback
|
||||
</DropdownItem>
|
||||
<DropdownItem key="logout" showDivider color="danger">
|
||||
<DropdownItem key="help_and_feedback">Help & Feedback</DropdownItem>
|
||||
<DropdownItem key="logout" color="danger">
|
||||
Log Out
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/image",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A simple image component",
|
||||
"keywords": [
|
||||
"image"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/input",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "The input component is designed for capturing user input within a text field.",
|
||||
"keywords": [
|
||||
"input"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/kbd",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "The keyboard key components indicates which key or set of keys used to execute a specificv action",
|
||||
"keywords": [
|
||||
"kbd"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/link",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Links allow users to click their way from page to page. This component is styled to resemble a hyperlink and semantically renders an <a>",
|
||||
"keywords": [
|
||||
"link"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/modal",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Displays a dialog with a custom content that requires attention or provides additional information.",
|
||||
"keywords": [
|
||||
"modal"
|
||||
|
||||
@ -33,7 +33,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl"],
|
||||
options: ["none", "sm", "md", "lg"],
|
||||
},
|
||||
},
|
||||
backdrop: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/navbar",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A responsive navigation header positioned on top side of your page that includes support for branding, links, navigation, collapse and more.",
|
||||
"keywords": [
|
||||
"navbar"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/pagination",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "The Pagination component allows you to display active page and navigate between multiple pages.",
|
||||
"keywords": [
|
||||
"pagination"
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
import {ComponentStory, ComponentMeta} from "@storybook/react";
|
||||
import {button, pagination, cn} from "@nextui-org/theme";
|
||||
import {button, pagination} from "@nextui-org/theme";
|
||||
import {cn} from "@nextui-org/system";
|
||||
import {ChevronIcon} from "@nextui-org/shared-icons";
|
||||
|
||||
import {
|
||||
@ -45,7 +46,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/popover",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A popover is an overlay element positioned relative to a trigger.",
|
||||
"keywords": [
|
||||
"popover"
|
||||
|
||||
@ -33,7 +33,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
placement: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/progress",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Progress bars show either determinate or indeterminate progress of an operation over time.",
|
||||
"keywords": [
|
||||
"progress"
|
||||
|
||||
@ -17,7 +17,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/radio",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Radios allow users to select a single option from a list of mutually exclusive options.",
|
||||
"keywords": [
|
||||
"radio"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/ripple",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A simple implementation to display a ripple animation when the source component is clicked",
|
||||
"keywords": [
|
||||
"ripple"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {FC, Suspense, Fragment} from "react";
|
||||
import {FC} from "react";
|
||||
import {AnimatePresence, HTMLMotionProps, motion} from "framer-motion";
|
||||
import {HTMLNextUIProps} from "@nextui-org/system";
|
||||
|
||||
@ -7,7 +7,6 @@ import {RippleType} from "./use-ripple";
|
||||
export interface RippleProps extends HTMLNextUIProps<"span"> {
|
||||
ripples: RippleType[];
|
||||
color?: string;
|
||||
suspense?: boolean;
|
||||
motionProps?: HTMLMotionProps<"span">;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
@ -16,46 +15,36 @@ const clamp = (value: number, min: number, max: number) => {
|
||||
return Math.min(Math.max(value, min), max);
|
||||
};
|
||||
|
||||
const Ripple: FC<RippleProps> = ({
|
||||
ripples = [],
|
||||
motionProps,
|
||||
suspense = false,
|
||||
color = "currentColor",
|
||||
style,
|
||||
}) => {
|
||||
const Ripple: FC<RippleProps> = ({ripples = [], motionProps, color = "currentColor", style}) => {
|
||||
return (
|
||||
<>
|
||||
{ripples.map((ripple) => {
|
||||
const duration = clamp(0.01 * ripple.size, 0.2, ripple.size > 100 ? 0.75 : 0.5);
|
||||
|
||||
const Wrapper = suspense ? Suspense : Fragment;
|
||||
|
||||
return (
|
||||
<Wrapper key={ripple.key}>
|
||||
<AnimatePresence mode="popLayout">
|
||||
<motion.span
|
||||
animate={{transform: "scale(2)", opacity: 0}}
|
||||
className="nextui-ripple"
|
||||
exit={{opacity: 0}}
|
||||
initial={{transform: "scale(0)", opacity: 0.35}}
|
||||
style={{
|
||||
position: "absolute",
|
||||
backgroundColor: color,
|
||||
borderRadius: "100%",
|
||||
transformOrigin: "center",
|
||||
pointerEvents: "none",
|
||||
zIndex: 10,
|
||||
top: ripple.y,
|
||||
left: ripple.x,
|
||||
width: `${ripple.size}px`,
|
||||
height: `${ripple.size}px`,
|
||||
...style,
|
||||
}}
|
||||
transition={{duration}}
|
||||
{...motionProps}
|
||||
/>
|
||||
</AnimatePresence>
|
||||
</Wrapper>
|
||||
<AnimatePresence key={ripple.key} mode="popLayout">
|
||||
<motion.span
|
||||
animate={{transform: "scale(2)", opacity: 0}}
|
||||
className="nextui-ripple"
|
||||
exit={{opacity: 0}}
|
||||
initial={{transform: "scale(0)", opacity: 0.35}}
|
||||
style={{
|
||||
position: "absolute",
|
||||
backgroundColor: color,
|
||||
borderRadius: "100%",
|
||||
transformOrigin: "center",
|
||||
pointerEvents: "none",
|
||||
zIndex: 10,
|
||||
top: ripple.y,
|
||||
left: ripple.x,
|
||||
width: `${ripple.size}px`,
|
||||
height: `${ripple.size}px`,
|
||||
...style,
|
||||
}}
|
||||
transition={{duration}}
|
||||
{...motionProps}
|
||||
/>
|
||||
</AnimatePresence>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
import React from "react";
|
||||
import {ComponentStory, ComponentMeta} from "@storybook/react";
|
||||
import {ripple} from "@nextui-org/theme";
|
||||
|
||||
import {Ripple, RippleProps} from "../src";
|
||||
|
||||
export default {
|
||||
title: "Components/Ripple",
|
||||
component: Ripple,
|
||||
argTypes: {
|
||||
color: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["neutral", "primary", "secondary", "success", "warning", "danger"],
|
||||
},
|
||||
},
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["sm", "md", "lg"],
|
||||
},
|
||||
},
|
||||
isDisabled: {
|
||||
control: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ComponentMeta<typeof Ripple>;
|
||||
|
||||
const defaultProps = {
|
||||
...ripple.defaultVariants,
|
||||
};
|
||||
|
||||
const Template: ComponentStory<typeof Ripple> = (args: RippleProps) => <Ripple {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
...defaultProps,
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/skeleton",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Skeleton is used to display the loading state of some component.",
|
||||
"keywords": [
|
||||
"skeleton"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/snippet",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Display a snippet of copyable code for the command line.",
|
||||
"keywords": [
|
||||
"snippet"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/spacer",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A flexible spacer component designed to create consistent spacing and maintain alignment in your layout.",
|
||||
"keywords": [
|
||||
"spacer"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/spinner",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Loaders express an unspecified wait time or display the length of a process.",
|
||||
"keywords": [
|
||||
"loading",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/switch",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A switch is similar to a checkbox, but represents on/off values as opposed to selection.",
|
||||
"keywords": [
|
||||
"switch"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/table",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Tables are used to display tabular data using rows and columns. ",
|
||||
"keywords": [
|
||||
"table"
|
||||
|
||||
@ -32,13 +32,13 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
shadow: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "sm", "md", "lg", "xl", "2xl", "inner"],
|
||||
options: ["none", "sm", "md", "lg"],
|
||||
},
|
||||
},
|
||||
selectionMode: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/tabs",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Tabs organize content into multiple sections and allow users to navigate between them.",
|
||||
"keywords": [
|
||||
"tabs"
|
||||
|
||||
@ -35,7 +35,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/tooltip",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A React Component for rendering dynamically positioned Tooltips",
|
||||
"keywords": [
|
||||
"tooltip"
|
||||
|
||||
@ -30,7 +30,7 @@ export default {
|
||||
radius: {
|
||||
control: {
|
||||
type: "select",
|
||||
options: ["none", "base", "sm", "md", "lg", "xl", "full"],
|
||||
options: ["none", "sm", "md", "lg", "full"],
|
||||
},
|
||||
},
|
||||
placement: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/user",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Flexible User Profile Component.",
|
||||
"keywords": [
|
||||
"user"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/react",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "🚀 Beautiful and modern React UI library.",
|
||||
"author": "Junior Garcia <jrgarciadev@gmail.com>",
|
||||
"homepage": "https://nextui.org",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/system",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "NextUI system primitives",
|
||||
"keywords": [
|
||||
"system"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/theme",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "The default theme for NextUI components",
|
||||
"keywords": [
|
||||
"theme",
|
||||
|
||||
@ -65,7 +65,6 @@ const accordionItem = tv({
|
||||
heading: "",
|
||||
trigger: [
|
||||
"flex py-4 w-full h-full gap-3 outline-none items-center tap-highlight-transparent",
|
||||
"data-[pressed=true]:opacity-disabled",
|
||||
// focus ring
|
||||
...dataFocusVisibleClasses,
|
||||
],
|
||||
|
||||
@ -51,9 +51,9 @@ const button = tv({
|
||||
ghost: "border-medium bg-transparent",
|
||||
},
|
||||
size: {
|
||||
sm: "px-3 min-w-[4rem] h-8 text-small gap-2 rounded-small",
|
||||
md: "px-4 min-w-[5rem] h-10 text-small gap-2 rounded-medium",
|
||||
lg: "px-6 min-w-[6rem] h-12 text-medium gap-3 rounded-large",
|
||||
sm: "px-unit-3 min-w-16 h-unit-8 text-tiny gap-unit-2 rounded-small",
|
||||
md: "px-unit-4 min-w-20 h-unit-10 text-small gap-unit-2 rounded-medium",
|
||||
lg: "px-unit-6 min-w-24 h-unit-12 text-medium gap-unit-3 rounded-large",
|
||||
},
|
||||
color: {
|
||||
default: "",
|
||||
@ -83,8 +83,8 @@ const button = tv({
|
||||
true: "[&:not(:first-child):not(:last-child)]:rounded-none",
|
||||
},
|
||||
isIconOnly: {
|
||||
true: "px-0 !gap-0",
|
||||
false: "[&>svg]:max-w-[2em]",
|
||||
true: "px-unit-0 !gap-unit-0",
|
||||
false: "[&>svg]:max-w-[theme(spacing.unit-8]",
|
||||
},
|
||||
disableAnimation: {
|
||||
true: "!transition-none",
|
||||
@ -344,22 +344,22 @@ const button = tv({
|
||||
{
|
||||
isInGroup: true,
|
||||
variant: ["bordered", "ghost"],
|
||||
class: "[&:not(:first-child)]:ml-[calc(theme(borderWidth.2)*-1)]",
|
||||
class: "[&:not(:first-child)]:ml-[calc(theme(borderWidth.medium)*-1)]",
|
||||
},
|
||||
{
|
||||
isIconOnly: true,
|
||||
size: "sm",
|
||||
class: "min-w-8 w-8 h-8",
|
||||
class: "min-w-unit-8 w-unit-8 h-unit-8",
|
||||
},
|
||||
{
|
||||
isIconOnly: true,
|
||||
size: "md",
|
||||
class: "min-w-10 w-10 h-10",
|
||||
class: "min-w-unit-10 w-unit-10 h-unit-10",
|
||||
},
|
||||
{
|
||||
isIconOnly: true,
|
||||
size: "lg",
|
||||
class: "min-w-12 w-12 h-12",
|
||||
class: "min-w-unit-12 w-unit-12 h-unit-12",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {LayoutTheme} from "./types";
|
||||
|
||||
export const defaultLayout: LayoutTheme = {
|
||||
spacingUnit: 4,
|
||||
disabledOpacity: ".5",
|
||||
dividerWeight: "1px",
|
||||
fontSize: {
|
||||
|
||||
@ -2,6 +2,7 @@ export * from "./components";
|
||||
export * from "./utils";
|
||||
export * from "./colors";
|
||||
export * from "./plugin";
|
||||
export * from "./types";
|
||||
|
||||
export {tv} from "tailwind-variants";
|
||||
export type {VariantProps} from "tailwind-variants";
|
||||
|
||||
@ -16,7 +16,7 @@ import {semanticColors, commonColors} from "./colors";
|
||||
import {animations} from "./animations";
|
||||
import {utilities} from "./utilities";
|
||||
import {flattenThemeObject} from "./utils/object";
|
||||
import {isBaseTheme} from "./utils/theme";
|
||||
import {createSpacingUnits, generateSpacingScale, isBaseTheme} from "./utils/theme";
|
||||
import {baseStyles} from "./utils/classes";
|
||||
import {ConfigTheme, ConfigThemes, DefaultThemeType, NextUIPluginConfig} from "./types";
|
||||
import {lightLayout, darkLayout, layouts, defaultLayout} from "./default-layout";
|
||||
@ -118,6 +118,20 @@ const resolveConfig = (
|
||||
forEach(value, (v, k) => {
|
||||
const layoutVariable = `--${prefix}-${key}-${k}`;
|
||||
|
||||
resolved.utilities[cssSelector]![layoutVariable] = v;
|
||||
});
|
||||
} else if (key === "spacing-unit") {
|
||||
const layoutVariable = `--${prefix}-${key}`;
|
||||
|
||||
// add the base unit "--spacing-unit: value"
|
||||
resolved.utilities[cssSelector]![layoutVariable] = value;
|
||||
|
||||
const spacingScale = generateSpacingScale(Number(value));
|
||||
|
||||
// add the list of spacing units "--spacing-unit-[key]: value"
|
||||
forEach(spacingScale, (v, k) => {
|
||||
const layoutVariable = `--${prefix}-${key}-${k}`;
|
||||
|
||||
resolved.utilities[cssSelector]![layoutVariable] = v;
|
||||
});
|
||||
} else {
|
||||
@ -169,20 +183,27 @@ const corePlugin = (
|
||||
width: {
|
||||
divider: `var(--${prefix}-divider-weight)`,
|
||||
},
|
||||
spacing: {
|
||||
unit: `var(--${prefix}-spacing-unit)`,
|
||||
...createSpacingUnits(prefix),
|
||||
},
|
||||
minWidth: {
|
||||
1: "0.25rem",
|
||||
2: "0.5rem",
|
||||
3: "0.75rem",
|
||||
"3.5": "0.875rem",
|
||||
4: "1rem",
|
||||
5: "1.25rem",
|
||||
6: "1.5rem",
|
||||
7: "1.75rem",
|
||||
8: "2rem",
|
||||
9: "2.25rem",
|
||||
10: "2.5rem",
|
||||
11: "2.75rem",
|
||||
12: "3rem",
|
||||
"unit-1": `var(--${prefix}-spacing-unit)`,
|
||||
"unit-2": `var(--${prefix}-spacing-unit-2`,
|
||||
"unit-3": `var(--${prefix}-spacing-unit-3)`,
|
||||
"unit-3.5": `var(--${prefix}-spacing-unit-3.5)`,
|
||||
"unit-4": `var(--${prefix}-spacing-unit-4)`,
|
||||
"unit-5": `var(--${prefix}-spacing-unit-5)`,
|
||||
"unit-6": `var(--${prefix}-spacing-unit-6)`,
|
||||
"unit-7": `var(--${prefix}-spacing-unit-7)`,
|
||||
"unit-8": `var(--${prefix}-spacing-unit-8)`,
|
||||
"unit-9": `var(--${prefix}-spacing-unit-9)`,
|
||||
"unit-10": `var(--${prefix}-spacing-unit-10)`,
|
||||
"unit-11": `var(--${prefix}-spacing-unit-11)`,
|
||||
"unit-12": `var(--${prefix}-spacing-unit-12)`,
|
||||
"unit-16": `var(--${prefix}-spacing-unit-16)`,
|
||||
"unit-20": `var(--${prefix}-spacing-unit-20)`,
|
||||
"unit-24": `var(--${prefix}-spacing-unit-24)`,
|
||||
},
|
||||
fontSize: {
|
||||
tiny: [`var(--${prefix}-font-size-tiny)`, `var(--${prefix}-line-height-tiny)`],
|
||||
|
||||
@ -12,7 +12,70 @@ export type FontThemeUnit = BaseThemeUnit & {
|
||||
tiny?: string;
|
||||
};
|
||||
|
||||
export const spacingScaleKeys = [
|
||||
"0",
|
||||
"xs",
|
||||
"sm",
|
||||
"md",
|
||||
"lg",
|
||||
"xl",
|
||||
"2xl",
|
||||
"3xl",
|
||||
"4xl",
|
||||
"5xl",
|
||||
"6xl",
|
||||
"7xl",
|
||||
"8xl",
|
||||
"9xl",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"3.5",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"15",
|
||||
"16",
|
||||
"17",
|
||||
"18",
|
||||
"20",
|
||||
"24",
|
||||
"28",
|
||||
"32",
|
||||
"36",
|
||||
"40",
|
||||
"44",
|
||||
"48",
|
||||
"52",
|
||||
"56",
|
||||
"60",
|
||||
"64",
|
||||
"72",
|
||||
"80",
|
||||
"96",
|
||||
];
|
||||
|
||||
export const mappedSpacingScaleKeys = spacingScaleKeys.map((key) => `unit-${key}`);
|
||||
|
||||
export type SpacingScaleKeys = typeof spacingScaleKeys[number];
|
||||
|
||||
export type SpacingScale = Partial<Record<SpacingScaleKeys, string>>;
|
||||
|
||||
export interface LayoutTheme {
|
||||
/**
|
||||
* Base unit token that defines a consistent spacing scale across the components.
|
||||
*
|
||||
* @default 4 (px)
|
||||
*/
|
||||
spacingUnit?: number;
|
||||
/**
|
||||
* The default font size applied across the components.
|
||||
*
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import {spacingScaleKeys, SpacingScaleKeys, SpacingScale} from "../types";
|
||||
|
||||
/**
|
||||
* Determines if the theme is a base theme
|
||||
*
|
||||
@ -5,3 +7,58 @@
|
||||
* @returns "light" | "dark
|
||||
*/
|
||||
export const isBaseTheme = (theme: string) => theme === "light" || theme === "dark";
|
||||
|
||||
const baseScale = [1, 2, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
||||
const extendedScale = [20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96];
|
||||
|
||||
export const generateSpacingScale = (spacingUnit: number) => {
|
||||
const scaleLabels: Partial<Record<SpacingScaleKeys, number>> = {
|
||||
xs: 2,
|
||||
sm: 3,
|
||||
md: 4,
|
||||
lg: 5.5,
|
||||
xl: 9,
|
||||
"2xl": 12,
|
||||
"3xl": 20,
|
||||
"4xl": 30,
|
||||
"5xl": 56,
|
||||
"6xl": 72,
|
||||
"7xl": 96,
|
||||
"8xl": 128,
|
||||
"9xl": 160,
|
||||
};
|
||||
|
||||
const scale = {0: "0px"} as SpacingScale;
|
||||
|
||||
Object.entries(scaleLabels).forEach(([label, multiplier]) => {
|
||||
scale[label as SpacingScaleKeys] = multiplier
|
||||
? `${spacingUnit * multiplier}px`
|
||||
: `${spacingUnit}px`;
|
||||
});
|
||||
|
||||
baseScale.forEach((i) => {
|
||||
const key = `${i}` as SpacingScaleKeys;
|
||||
|
||||
scale[key] = `${spacingUnit * i}px`;
|
||||
});
|
||||
|
||||
extendedScale.forEach((i) => {
|
||||
const key = `${i}` as SpacingScaleKeys;
|
||||
|
||||
scale[key] = `${spacingUnit * i}px`;
|
||||
});
|
||||
|
||||
return scale;
|
||||
};
|
||||
|
||||
export function createSpacingUnits(prefix: string) {
|
||||
let result = spacingScaleKeys.reduce(
|
||||
(acc, key) => ({
|
||||
...acc,
|
||||
[`unit-${key}`]: `var(--${prefix}-spacing-unit-${key})`,
|
||||
}),
|
||||
{},
|
||||
);
|
||||
|
||||
return result as Record<SpacingScaleKeys, string>;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {tv as tvBase, TV} from "tailwind-variants";
|
||||
|
||||
import {mappedSpacingScaleKeys} from "../types";
|
||||
const COMMON_UNITS = ["small", "medium", "large"];
|
||||
|
||||
export const tv: TV = (options, config) =>
|
||||
@ -11,7 +12,7 @@ export const tv: TV = (options, config) =>
|
||||
theme: {
|
||||
...config?.twMergeConfig?.theme,
|
||||
opacity: ["disabled"],
|
||||
spacing: ["divider"],
|
||||
spacing: ["divider", "unit", ...mappedSpacingScaleKeys],
|
||||
borderWidth: COMMON_UNITS,
|
||||
borderRadius: COMMON_UNITS,
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-aria-accordion-item",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Internal impl for react aria accordion item",
|
||||
"keywords": [
|
||||
"use-aria-accordion-item"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-aria-button",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Internal hook to handle button a11y and events, this is based on react-aria button hook but without the onClick warning",
|
||||
"keywords": [
|
||||
"use-aria-button"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-aria-label",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Based on react-aria label hook, it provides the accessibility implementation for labels and their associated elements. Labels provide context for user inputs.",
|
||||
"keywords": [
|
||||
"use-aria-label"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-aria-modal-overlay",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A custom implementation of react aria modal overlay, this removes the prevent scroll",
|
||||
"keywords": [
|
||||
"use-aria-modal-overlay"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-aria-toggle-button",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Internal hook to handle button a11y and events, this is based on react-aria button hook but without the onClick warning",
|
||||
"keywords": [
|
||||
"use-aria-toggle-button"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-callback-ref",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "React hook to persist any value between renders, but keeps it up-to-date if it changes.",
|
||||
"keywords": [
|
||||
"use-callback-ref"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-clipboard",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Wrapper around navigator.clipboard with feedback timeout",
|
||||
"keywords": [
|
||||
"use-clipboard"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-disclosure",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "The hook in charge of managing modals",
|
||||
"keywords": [
|
||||
"use-disclosure"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-image",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "React hook for progressing image loading",
|
||||
"keywords": [
|
||||
"use-image"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-infinite-scroll",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A hook for handling infinity scroll based on the IntersectionObserver API",
|
||||
"keywords": [
|
||||
"use-infinite-scroll"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-is-mobile",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A hook that returns whether the device is mobile or not",
|
||||
"keywords": [
|
||||
"use-is-mobile"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-is-mounted",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "This hook can be used to render client-based components or run client logic",
|
||||
"keywords": [
|
||||
"use-is-mounted"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-pagination",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "State management hook for Pagination component, it lets you manage pagination with controlled and uncontrolled state",
|
||||
"keywords": [
|
||||
"use-pagination"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-real-shape",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Hook that returns the real dimensions of an element",
|
||||
"keywords": [
|
||||
"use-real-shape"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-ref-state",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Hook for saving the state in a ref value",
|
||||
"keywords": [
|
||||
"use-ref-state"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-resize",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Hook that adds an event listener to the resize window event",
|
||||
"keywords": [
|
||||
"use-resize"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-safe-layout-effect",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"use-safe-layout-effect"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-scroll-position",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Provides the logic to control the scroll over an element",
|
||||
"keywords": [
|
||||
"use-scroll-position"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-ssr",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"use-ssr"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/use-update-effect",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "React effect hook that invokes only on update",
|
||||
"keywords": [
|
||||
"use-update-effect"
|
||||
|
||||
@ -137,5 +137,5 @@ import {link, button} from "@nextui-org/theme";
|
||||
|
||||
|
||||
<div class="block text-xs text-default-400">
|
||||
Last updated on <time datetime="2023-03-07">Jul 04, 2023</time>
|
||||
Last updated on <time datetime="2023-03-07">Jul 06, 2023</time>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/aria-utils",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A package for managing @react-aria nextui utils.",
|
||||
"keywords": [
|
||||
"aria-utils"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/framer-transitions",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A set of framer motion transitions for react",
|
||||
"keywords": [
|
||||
"framer-transitions"
|
||||
|
||||
@ -1,155 +0,0 @@
|
||||
/**
|
||||
* Part of this code is taken from @chakra-ui/system ❤️
|
||||
*/
|
||||
|
||||
import {warn, isNumeric} from "@nextui-org/shared-utils";
|
||||
import {AnimatePresence, HTMLMotionProps, motion, Variants as _Variants} from "framer-motion";
|
||||
import {forwardRef, useEffect, useState} from "react";
|
||||
|
||||
import {TRANSITION_EASINGS, Variants, WithTransitionConfig, withDelay} from "./transition-utils";
|
||||
|
||||
export interface CollapseTransitionOptions {
|
||||
/**
|
||||
* If `true`, the opacity of the content will be animated
|
||||
* @default true
|
||||
*/
|
||||
animateOpacity?: boolean;
|
||||
/**
|
||||
* The height you want the content in its collapsed state.
|
||||
* @default 0
|
||||
*/
|
||||
startingHeight?: number;
|
||||
/**
|
||||
* The height you want the content in its expanded state.
|
||||
* @default "auto"
|
||||
*/
|
||||
endingHeight?: number | string;
|
||||
/**
|
||||
* The y-axis offset you want the content in its collapsed state.
|
||||
* @default 10
|
||||
*/
|
||||
startingY?: number;
|
||||
/**
|
||||
* The y-axis offset you want the content in its expanded state.
|
||||
* @default 0
|
||||
*/
|
||||
endingY?: number;
|
||||
}
|
||||
|
||||
const defaultTransitions = {
|
||||
exit: {
|
||||
height: {duration: 0.2, ease: TRANSITION_EASINGS.ease},
|
||||
opacity: {duration: 0.3, ease: TRANSITION_EASINGS.ease},
|
||||
},
|
||||
enter: {
|
||||
height: {duration: 0.3, ease: TRANSITION_EASINGS.ease},
|
||||
opacity: {duration: 0.4, ease: TRANSITION_EASINGS.ease},
|
||||
},
|
||||
};
|
||||
|
||||
const variants: Variants<CollapseTransitionOptions> = {
|
||||
enter: ({animateOpacity, endingHeight, transition, transitionEnd, delay}) => ({
|
||||
...(animateOpacity && {opacity: 1}),
|
||||
height: endingHeight,
|
||||
transitionEnd: transitionEnd?.enter,
|
||||
transition: transition?.enter ?? withDelay.enter(defaultTransitions.enter, delay),
|
||||
}),
|
||||
exit: ({animateOpacity, startingHeight, transition, transitionEnd, delay}) => ({
|
||||
...(animateOpacity && {opacity: isNumeric(startingHeight) ? 1 : 0}),
|
||||
height: startingHeight,
|
||||
transitionEnd: transitionEnd?.exit,
|
||||
transition: transition?.exit ?? withDelay.exit(defaultTransitions.exit, delay),
|
||||
}),
|
||||
};
|
||||
|
||||
export type ICollapseTransition = CollapseTransitionProps;
|
||||
|
||||
export interface CollapseTransitionProps
|
||||
extends WithTransitionConfig<HTMLMotionProps<"div">>,
|
||||
CollapseTransitionOptions {}
|
||||
|
||||
export const CollapseTransition = forwardRef<HTMLDivElement, CollapseTransitionProps>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
in: isOpen,
|
||||
unmountOnExit,
|
||||
animateOpacity = true,
|
||||
startingHeight = 0,
|
||||
endingHeight = "auto",
|
||||
style,
|
||||
className,
|
||||
transition,
|
||||
transitionEnd,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const timeout = setTimeout(() => {
|
||||
setMounted(true);
|
||||
});
|
||||
|
||||
return () => clearTimeout(timeout);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Warn 🚨: `startingHeight` and `unmountOnExit` are mutually exclusive
|
||||
*
|
||||
* If you specify a starting height, the collapsed needs to be mounted
|
||||
* for the height to take effect.
|
||||
*/
|
||||
|
||||
if (Boolean(startingHeight > 0 && unmountOnExit)) {
|
||||
warn(
|
||||
`startingHeight and unmountOnExit are mutually exclusive. You can't use them together`,
|
||||
"FramerTransitions - Collapse",
|
||||
);
|
||||
}
|
||||
|
||||
const hasStartingHeight = parseFloat(startingHeight.toString()) > 0;
|
||||
|
||||
const custom = {
|
||||
startingHeight,
|
||||
endingHeight,
|
||||
animateOpacity,
|
||||
transition: !mounted ? {enter: {duration: 0}} : transition,
|
||||
transitionEnd: {
|
||||
enter: transitionEnd?.enter,
|
||||
exit: unmountOnExit
|
||||
? transitionEnd?.exit
|
||||
: {
|
||||
...transitionEnd?.exit,
|
||||
display: hasStartingHeight ? "block" : "none",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const show = unmountOnExit ? isOpen : true;
|
||||
const animate = isOpen || unmountOnExit ? "enter" : "exit";
|
||||
|
||||
return (
|
||||
<AnimatePresence custom={custom} initial={false}>
|
||||
{show && (
|
||||
<motion.div
|
||||
ref={ref}
|
||||
{...rest}
|
||||
animate={animate}
|
||||
className={className}
|
||||
custom={custom}
|
||||
exit="exit"
|
||||
initial={unmountOnExit ? "exit" : false}
|
||||
style={{
|
||||
overflow: "hidden",
|
||||
display: "block",
|
||||
...style,
|
||||
}}
|
||||
variants={variants as _Variants}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
CollapseTransition.displayName = "NextUI.CollapseTransition";
|
||||
@ -1,2 +1 @@
|
||||
export * from "./collapse-transition";
|
||||
export * from "./transition-utils";
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
/**
|
||||
* Part of this code is taken from @chakra-ui/system ❤️
|
||||
*/
|
||||
|
||||
import type {Target, TargetAndTransition, Transition} from "framer-motion";
|
||||
|
||||
type WithMotionState<P> = Partial<Record<"enter" | "exit", P>>;
|
||||
|
||||
export type TransitionConfig = WithMotionState<Transition>;
|
||||
|
||||
export type TransitionEndConfig = WithMotionState<Target>;
|
||||
|
||||
export type TransitionProperties = {
|
||||
/**
|
||||
* Custom `transition` definition for `enter` and `exit`
|
||||
@ -13,29 +15,20 @@ export type TransitionProperties = {
|
||||
* Custom `transitionEnd` definition for `enter` and `exit`
|
||||
*/
|
||||
transitionEnd?: TransitionEndConfig;
|
||||
/**
|
||||
* Custom `delay` definition for `enter` and `exit`
|
||||
*/
|
||||
delay?: number | DelayConfig;
|
||||
};
|
||||
|
||||
type TargetResolver<P = {}> = (props: P & TransitionProperties) => TargetAndTransition;
|
||||
|
||||
type Variant<P = {}> = TargetAndTransition | TargetResolver<P>;
|
||||
|
||||
export type Variants<P = {}> = {
|
||||
enter: Variant<P>;
|
||||
exit: Variant<P>;
|
||||
initial?: Variant<P>;
|
||||
};
|
||||
|
||||
type WithMotionState<P> = Partial<Record<"enter" | "exit", P>>;
|
||||
|
||||
export type TransitionConfig = WithMotionState<Transition>;
|
||||
|
||||
export type TransitionEndConfig = WithMotionState<Target>;
|
||||
|
||||
export type DelayConfig = WithMotionState<number>;
|
||||
export type Variants<P = {}> = Record<
|
||||
string,
|
||||
{
|
||||
enter: Variant<P>;
|
||||
exit: Variant<P>;
|
||||
initial?: Variant<P>;
|
||||
}
|
||||
>;
|
||||
|
||||
export const TRANSITION_EASINGS = {
|
||||
ease: [0.36, 0.66, 0.4, 1],
|
||||
@ -47,7 +40,18 @@ export const TRANSITION_EASINGS = {
|
||||
softSpring: [0.16, 1.11, 0.3, 1.02],
|
||||
} as const;
|
||||
|
||||
export const TRANSITION_VARIANTS = {
|
||||
export const TRANSITION_DEFAULTS = {
|
||||
enter: {
|
||||
duration: 0.2,
|
||||
ease: TRANSITION_EASINGS.easeOut,
|
||||
},
|
||||
exit: {
|
||||
duration: 0.1,
|
||||
ease: TRANSITION_EASINGS.easeIn,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const TRANSITION_VARIANTS: Variants = {
|
||||
scaleSpring: {
|
||||
initial: {
|
||||
opacity: 0,
|
||||
@ -146,99 +150,34 @@ export const TRANSITION_VARIANTS = {
|
||||
},
|
||||
},
|
||||
},
|
||||
pushLeft: {
|
||||
enter: {x: "100%"},
|
||||
exit: {x: "-30%"},
|
||||
},
|
||||
pushRight: {
|
||||
enter: {x: "-100%"},
|
||||
exit: {x: "30%"},
|
||||
},
|
||||
pushUp: {
|
||||
enter: {y: "100%"},
|
||||
exit: {y: "-30%"},
|
||||
},
|
||||
pushDown: {
|
||||
enter: {y: "-100%"},
|
||||
exit: {y: "30%"},
|
||||
},
|
||||
slideLeft: {
|
||||
position: {left: 0, top: 0, bottom: 0, width: "100%"},
|
||||
enter: {x: 0, y: 0},
|
||||
exit: {x: "-100%", y: 0},
|
||||
},
|
||||
slideRight: {
|
||||
position: {right: 0, top: 0, bottom: 0, width: "100%"},
|
||||
enter: {x: 0, y: 0},
|
||||
exit: {x: "100%", y: 0},
|
||||
},
|
||||
slideUp: {
|
||||
position: {top: 0, left: 0, right: 0, maxWidth: "100vw"},
|
||||
enter: {x: 0, y: 0},
|
||||
exit: {x: 0, y: "-100%"},
|
||||
},
|
||||
slideDown: {
|
||||
position: {bottom: 0, left: 0, right: 0, maxWidth: "100vw"},
|
||||
enter: {x: 0, y: 0},
|
||||
exit: {x: 0, y: "100%"},
|
||||
collapse: {
|
||||
enter: {
|
||||
opacity: 1,
|
||||
height: "auto",
|
||||
transition: {
|
||||
height: {
|
||||
ease: TRANSITION_EASINGS.ease,
|
||||
duration: 0.25,
|
||||
},
|
||||
opacity: {
|
||||
ease: TRANSITION_EASINGS.ease,
|
||||
duration: 0.3,
|
||||
},
|
||||
},
|
||||
},
|
||||
exit: {
|
||||
opacity: 0,
|
||||
height: 0,
|
||||
transition: {
|
||||
height: {
|
||||
ease: TRANSITION_EASINGS.ease,
|
||||
duration: 0.3,
|
||||
},
|
||||
opacity: {
|
||||
ease: TRANSITION_EASINGS.ease,
|
||||
duration: 0.1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export type SlideDirection = "top" | "left" | "bottom" | "right";
|
||||
|
||||
export function getSlideTransition(options?: {direction?: SlideDirection}) {
|
||||
const side = options?.direction ?? "right";
|
||||
|
||||
switch (side) {
|
||||
case "right":
|
||||
return TRANSITION_VARIANTS.slideRight;
|
||||
case "left":
|
||||
return TRANSITION_VARIANTS.slideLeft;
|
||||
case "bottom":
|
||||
return TRANSITION_VARIANTS.slideDown;
|
||||
case "top":
|
||||
return TRANSITION_VARIANTS.slideUp;
|
||||
default:
|
||||
return TRANSITION_VARIANTS.slideRight;
|
||||
}
|
||||
}
|
||||
|
||||
export const TRANSITION_DEFAULTS = {
|
||||
enter: {
|
||||
duration: 0.2,
|
||||
ease: TRANSITION_EASINGS.easeOut,
|
||||
},
|
||||
exit: {
|
||||
duration: 0.1,
|
||||
ease: TRANSITION_EASINGS.easeIn,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type WithTransitionConfig<P extends object> = Omit<P, "transition"> &
|
||||
TransitionProperties & {
|
||||
/**
|
||||
* If `true`, the element will unmount when `in={false}` and animation is done
|
||||
*/
|
||||
unmountOnExit?: boolean;
|
||||
/**
|
||||
* Show the component; triggers when enter or exit states
|
||||
*/
|
||||
in?: boolean;
|
||||
};
|
||||
|
||||
export const withDelay = {
|
||||
enter: (
|
||||
transition: Transition,
|
||||
delay?: number | DelayConfig,
|
||||
): Transition & {delay: number | undefined} => ({
|
||||
...transition,
|
||||
delay: typeof delay === "number" ? delay : delay?.["enter"],
|
||||
}),
|
||||
exit: (
|
||||
transition: Transition,
|
||||
delay?: number | DelayConfig,
|
||||
): Transition & {delay: number | undefined} => ({
|
||||
...transition,
|
||||
delay: typeof delay === "number" ? delay : delay?.["exit"],
|
||||
}),
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/react-utils",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A set of utilities for react on client side",
|
||||
"keywords": [
|
||||
"react-utils"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/shared-icons",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "Internal icons set, commonly used in the components stories",
|
||||
"keywords": [
|
||||
"icons-utils"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/shared-utils",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A set of NextUI utilities",
|
||||
"keywords": [
|
||||
"system"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nextui-org/test-utils",
|
||||
"version": "0.0.0-dev-v2-20230706030638",
|
||||
"version": "0.0.0-dev-v2-20230706232536",
|
||||
"description": "A set of utilities for react testing",
|
||||
"keywords": [
|
||||
"test-utils"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user