refactor: add support for disabling the animation globally (#2929)

* refactor: add support for disabling the animation globally

* chore(docs): disableAnimation removed from global provider

* feat(docs): nextui provider api updated, storybook preview adjusted

* chore(theme): button is scalable when disabled, tooltip animation improved
This commit is contained in:
Junior Garcia 2024-05-12 23:13:54 -03:00 committed by GitHub
parent e34c5e307d
commit 422770cc6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
106 changed files with 633 additions and 286 deletions

View File

@ -0,0 +1,40 @@
---
"@nextui-org/accordion": patch
"@nextui-org/autocomplete": patch
"@nextui-org/avatar": patch
"@nextui-org/badge": patch
"@nextui-org/breadcrumbs": patch
"@nextui-org/button": patch
"@nextui-org/calendar": patch
"@nextui-org/card": patch
"@nextui-org/checkbox": patch
"@nextui-org/date-input": patch
"@nextui-org/date-picker": patch
"@nextui-org/dropdown": patch
"@nextui-org/image": patch
"@nextui-org/input": patch
"@nextui-org/link": patch
"@nextui-org/listbox": patch
"@nextui-org/menu": patch
"@nextui-org/modal": patch
"@nextui-org/navbar": patch
"@nextui-org/pagination": patch
"@nextui-org/popover": patch
"@nextui-org/progress": patch
"@nextui-org/radio": patch
"@nextui-org/ripple": patch
"@nextui-org/select": patch
"@nextui-org/skeleton": patch
"@nextui-org/slider": patch
"@nextui-org/snippet": patch
"@nextui-org/switch": patch
"@nextui-org/table": patch
"@nextui-org/tabs": patch
"@nextui-org/tooltip": patch
"@nextui-org/react": patch
"@nextui-org/system": patch
"@nextui-org/theme": patch
"@nextui-org/framer-utils": patch
---
Add support for disabling the animations globally.

View File

@ -154,7 +154,8 @@
"key": "badge", "key": "badge",
"title": "Badge", "title": "Badge",
"keywords": "badge, markers, status indication, count display", "keywords": "badge, markers, status indication, count display",
"path": "/docs/components/badge.mdx" "path": "/docs/components/badge.mdx",
"updated": true
}, },
{ {
"key": "button", "key": "button",
@ -334,7 +335,8 @@
"key": "skeleton", "key": "skeleton",
"title": "Skeleton", "title": "Skeleton",
"keywords": "skeleton, loading state, placeholder, content preview", "keywords": "skeleton, loading state, placeholder, content preview",
"path": "/docs/components/skeleton.mdx" "path": "/docs/components/skeleton.mdx",
"updated": true
}, },
{ {
"key": "snippet", "key": "snippet",

View File

@ -9,7 +9,7 @@ import {badgeContent} from "@/content/components/badge";
Badges are used as a small numerical value or status descriptor for UI elements. Badges are used as a small numerical value or status descriptor for UI elements.
<ComponentLinks component="badge" rscCompatible /> <ComponentLinks component="badge" />
--- ---

View File

@ -9,7 +9,7 @@ import {skeletonContent} from "@/content/components/skeleton";
Skeleton is a placeholder to show a loading state and the expected shape of a component. Skeleton is a placeholder to show a loading state and the expected shape of a component.
<ComponentLinks component="skeleton" rscCompatible /> <ComponentLinks component="skeleton" />
--- ---

View File

@ -42,7 +42,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -1,4 +1,4 @@
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system"; import {HTMLNextUIProps, PropGetter, useProviderContext} from "@nextui-org/system";
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
import {accordionItem} from "@nextui-org/theme"; import {accordionItem} from "@nextui-org/theme";
import {clsx, callAllHandlers, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, callAllHandlers, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
@ -39,6 +39,8 @@ export type UseAccordionItemProps<T extends object = {}> = Props<T> &
Omit<AccordionItemBaseProps, "onFocusChange">; Omit<AccordionItemBaseProps, "onFocusChange">;
export function useAccordionItem<T extends object = {}>(props: UseAccordionItemProps<T>) { export function useAccordionItem<T extends object = {}>(props: UseAccordionItemProps<T>) {
const globalContext = useProviderContext();
const {ref, as, item, onFocusChange} = props; const {ref, as, item, onFocusChange} = props;
const { const {
@ -55,7 +57,7 @@ export function useAccordionItem<T extends object = {}>(props: UseAccordionItemP
classNames: classNamesProp = {}, classNames: classNamesProp = {},
isDisabled: isDisabledProp = false, isDisabled: isDisabledProp = false,
hideIndicator = false, hideIndicator = false,
disableAnimation = false, disableAnimation = globalContext?.disableAnimation ?? false,
keepContentMounted = false, keepContentMounted = false,
disableIndicatorAnimation = false, disableIndicatorAnimation = false,
HeadingComponent = as || "h2", HeadingComponent = as || "h2",

View File

@ -1,8 +1,8 @@
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import type {SelectionBehavior, MultipleSelection} from "@react-types/shared"; import type {SelectionBehavior, MultipleSelection} from "@react-types/shared";
import type {AriaAccordionProps} from "@react-types/accordion"; import type {AriaAccordionProps} from "@react-types/accordion";
import type {AccordionGroupVariantProps} from "@nextui-org/theme"; import type {AccordionGroupVariantProps} from "@nextui-org/theme";
import {useProviderContext, type HTMLNextUIProps, type PropGetter} from "@nextui-org/system";
import {ReactRef, filterDOMProps} from "@nextui-org/react-utils"; import {ReactRef, filterDOMProps} from "@nextui-org/react-utils";
import React, {Key, useCallback} from "react"; import React, {Key, useCallback} from "react";
import {TreeState, useTreeState} from "@react-stately/tree"; import {TreeState, useTreeState} from "@react-stately/tree";
@ -73,6 +73,8 @@ export type ValuesType<T extends object = {}> = {
}; };
export function useAccordion<T extends object>(props: UseAccordionProps<T>) { export function useAccordion<T extends object>(props: UseAccordionProps<T>) {
const globalContext = useProviderContext();
const { const {
ref, ref,
as, as,
@ -97,7 +99,7 @@ export function useAccordion<T extends object>(props: UseAccordionProps<T>) {
isDisabled = false, isDisabled = false,
showDivider = true, showDivider = true,
hideIndicator = false, hideIndicator = false,
disableAnimation = false, disableAnimation = globalContext?.disableAnimation ?? false,
disableIndicatorAnimation = false, disableIndicatorAnimation = false,
itemClasses, itemClasses,
...otherProps ...otherProps

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -1,6 +1,7 @@
import type {AutocompleteVariantProps, SlotsToClasses, AutocompleteSlots} from "@nextui-org/theme"; import type {AutocompleteVariantProps, SlotsToClasses, AutocompleteSlots} from "@nextui-org/theme";
import type {DOMAttributes, HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import {DOMAttributes, HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {mapPropsVariants, useProviderContext} from "@nextui-org/system";
import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect"; import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect";
import {autocomplete} from "@nextui-org/theme"; import {autocomplete} from "@nextui-org/theme";
import {useFilter} from "@react-aria/i18n"; import {useFilter} from "@react-aria/i18n";
@ -120,8 +121,11 @@ export type UseAutocompleteProps<T> = Props<T> &
AutocompleteVariantProps; AutocompleteVariantProps;
export function useAutocomplete<T extends object>(originalProps: UseAutocompleteProps<T>) { export function useAutocomplete<T extends object>(originalProps: UseAutocompleteProps<T>) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, autocomplete.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, autocomplete.variantKeys);
const disableAnimation = originalProps.disableAnimation ?? false; const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
// TODO: Remove disableClearable prop in the next minor release. // TODO: Remove disableClearable prop in the next minor release.
const isClearable = const isClearable =

View File

@ -1,7 +1,7 @@
import type {AvatarSlots, AvatarVariantProps, SlotsToClasses} from "@nextui-org/theme"; import type {AvatarSlots, AvatarVariantProps, SlotsToClasses} from "@nextui-org/theme";
import {avatar} from "@nextui-org/theme"; import {avatar} from "@nextui-org/theme";
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system"; import {HTMLNextUIProps, PropGetter, useProviderContext} from "@nextui-org/system";
import {mergeProps} from "@react-aria/utils"; import {mergeProps} from "@react-aria/utils";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {clsx, safeText, dataAttr} from "@nextui-org/shared-utils"; import {clsx, safeText, dataAttr} from "@nextui-org/shared-utils";
@ -96,7 +96,8 @@ interface Props extends HTMLNextUIProps<"span"> {
export type UseAvatarProps = Props & export type UseAvatarProps = Props &
Omit<AvatarVariantProps, "children" | "isInGroup" | "isInGridGroup">; Omit<AvatarVariantProps, "children" | "isInGroup" | "isInGridGroup">;
export function useAvatar(props: UseAvatarProps = {}) { export function useAvatar(originalProps: UseAvatarProps = {}) {
const globalContext = useProviderContext();
const groupContext = useAvatarGroupContext(); const groupContext = useAvatarGroupContext();
const isInGroup = !!groupContext; const isInGroup = !!groupContext;
@ -124,7 +125,7 @@ export function useAvatar(props: UseAvatarProps = {}) {
className, className,
onError, onError,
...otherProps ...otherProps
} = props; } = originalProps;
const Component = as || "span"; const Component = as || "span";
@ -133,6 +134,8 @@ export function useAvatar(props: UseAvatarProps = {}) {
const {isFocusVisible, isFocused, focusProps} = useFocusRing(); const {isFocusVisible, isFocused, focusProps} = useFocusRing();
const {isHovered, hoverProps} = useHover({isDisabled}); const {isHovered, hoverProps} = useHover({isDisabled});
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const imageStatus = useImage({src, onError, ignoreFallback}); const imageStatus = useImage({src, onError, ignoreFallback});
@ -156,9 +159,19 @@ export function useAvatar(props: UseAvatarProps = {}) {
isBordered, isBordered,
isDisabled, isDisabled,
isInGroup, isInGroup,
disableAnimation,
isInGridGroup: groupContext?.isGrid ?? false, isInGridGroup: groupContext?.isGrid ?? false,
}), }),
[color, radius, size, isBordered, isDisabled, isInGroup, groupContext?.isGrid], [
color,
radius,
size,
isBordered,
isDisabled,
disableAnimation,
isInGroup,
groupContext?.isGrid,
],
); );
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);
@ -186,11 +199,12 @@ export function useAvatar(props: UseAvatarProps = {}) {
(props = {}) => ({ (props = {}) => ({
ref: imgRef, ref: imgRef,
src: src, src: src,
disableAnimation,
"data-loaded": dataAttr(isImgLoaded), "data-loaded": dataAttr(isImgLoaded),
className: slots.img({class: classNames?.img}), className: slots.img({class: classNames?.img}),
...mergeProps(imgProps, props), ...mergeProps(imgProps, props),
}), }),
[slots, isImgLoaded, imgProps, src, imgRef], [slots, isImgLoaded, imgProps, disableAnimation, src, imgRef],
); );
return { return {

View File

@ -36,14 +36,15 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"@nextui-org/theme": ">=2.1.0" "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0"
}, },
"dependencies": { "dependencies": {
"@nextui-org/system-rsc": "workspace:*",
"@nextui-org/shared-utils": "workspace:*", "@nextui-org/shared-utils": "workspace:*",
"@nextui-org/react-utils": "workspace:*" "@nextui-org/react-utils": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@nextui-org/system": "workspace:*",
"@nextui-org/theme": "workspace:*", "@nextui-org/theme": "workspace:*",
"@nextui-org/avatar": "workspace:*", "@nextui-org/avatar": "workspace:*",
"@nextui-org/shared-icons": "workspace:*", "@nextui-org/shared-icons": "workspace:*",

View File

@ -1,4 +1,4 @@
import {forwardRef} from "@nextui-org/system-rsc"; import {forwardRef} from "@nextui-org/system";
import {UseBadgeProps, useBadge} from "./use-badge"; import {UseBadgeProps, useBadge} from "./use-badge";

View File

@ -1,9 +1,9 @@
import type {BadgeSlots, BadgeVariantProps, SlotsToClasses} from "@nextui-org/theme"; import type {BadgeSlots, BadgeVariantProps, SlotsToClasses} from "@nextui-org/theme";
import type {ReactNode} from "react"; import type {ReactNode} from "react";
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system-rsc"; import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import {badge} from "@nextui-org/theme"; import {badge} from "@nextui-org/theme";
import {mapPropsVariants} from "@nextui-org/system-rsc"; import {mapPropsVariants, useProviderContext} from "@nextui-org/system";
import {clsx, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, objectToDeps} from "@nextui-org/shared-utils";
import {ReactRef} from "@nextui-org/react-utils"; import {ReactRef} from "@nextui-org/react-utils";
import {useMemo} from "react"; import {useMemo} from "react";
@ -45,6 +45,10 @@ interface Props extends HTMLNextUIProps<"span", "content"> {
export type UseBadgeProps = Props & BadgeVariantProps; export type UseBadgeProps = Props & BadgeVariantProps;
export function useBadge(originalProps: UseBadgeProps) { export function useBadge(originalProps: UseBadgeProps) {
const globalContext = useProviderContext();
const disableAnimation =
originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
const [props, variantProps] = mapPropsVariants(originalProps, badge.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, badge.variantKeys);
const {as, children, className, content, classNames, ...otherProps} = props; const {as, children, className, content, classNames, ...otherProps} = props;
@ -87,7 +91,7 @@ export function useBadge(originalProps: UseBadgeProps) {
content, content,
slots, slots,
classNames, classNames,
disableAnimation: originalProps?.disableAnimation, disableAnimation,
isInvisible: originalProps?.isInvisible, isInvisible: originalProps?.isInvisible,
getBadgeProps, getBadgeProps,
}; };

View File

@ -4,4 +4,5 @@ export default defineConfig({
clean: true, clean: true,
target: "es2019", target: "es2019",
format: ["cjs", "esm"], format: ["cjs", "esm"],
banner: {js: '"use client";'},
}); });

View File

@ -2,7 +2,12 @@ import type {BreadcrumbsVariantProps, SlotsToClasses, BreadcrumbsSlots} from "@n
import type {AriaBreadcrumbsProps} from "@react-types/breadcrumbs"; import type {AriaBreadcrumbsProps} from "@react-types/breadcrumbs";
import {Children, ReactNode, Key, ReactElement} from "react"; import {Children, ReactNode, Key, ReactElement} from "react";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {breadcrumbs} from "@nextui-org/theme"; import {breadcrumbs} from "@nextui-org/theme";
import {filterDOMProps, pickChildren, ReactRef, useDOMRef} from "@nextui-org/react-utils"; import {filterDOMProps, pickChildren, ReactRef, useDOMRef} from "@nextui-org/react-utils";
import {mergeProps} from "@react-aria/utils"; import {mergeProps} from "@react-aria/utils";
@ -103,6 +108,11 @@ export type UseBreadcrumbsProps = Props &
>; >;
export function useBreadcrumbs(originalProps: UseBreadcrumbsProps) { export function useBreadcrumbs(originalProps: UseBreadcrumbsProps) {
const globalContext = useProviderContext();
const disableAnimation =
originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
const [props, variantProps] = mapPropsVariants(originalProps, breadcrumbs.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, breadcrumbs.variantKeys);
const { const {
@ -117,7 +127,6 @@ export function useBreadcrumbs(originalProps: UseBreadcrumbsProps) {
itemsAfterCollapse = 2, itemsAfterCollapse = 2,
maxItems = 8, maxItems = 8,
hideSeparator, hideSeparator,
disableAnimation,
renderEllipsis, renderEllipsis,
className, className,
classNames, classNames,

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -3,7 +3,12 @@ import type {ReactRef} from "@nextui-org/react-utils";
import type {ButtonGroupVariantProps} from "@nextui-org/theme"; import type {ButtonGroupVariantProps} from "@nextui-org/theme";
import {buttonGroup} from "@nextui-org/theme"; import {buttonGroup} from "@nextui-org/theme";
import {HTMLNextUIProps, PropGetter, mapPropsVariants} from "@nextui-org/system"; import {
HTMLNextUIProps,
PropGetter,
mapPropsVariants,
useProviderContext,
} from "@nextui-org/system";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {useMemo, useCallback} from "react"; import {useMemo, useCallback} from "react";
import {objectToDeps} from "@nextui-org/shared-utils"; import {objectToDeps} from "@nextui-org/shared-utils";
@ -40,6 +45,7 @@ export type UseButtonGroupProps = Props &
>; >;
export function useButtonGroup(originalProps: UseButtonGroupProps) { export function useButtonGroup(originalProps: UseButtonGroupProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, buttonGroup.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, buttonGroup.variantKeys);
const { const {
@ -51,9 +57,9 @@ export function useButtonGroup(originalProps: UseButtonGroupProps) {
variant = "solid", variant = "solid",
radius, radius,
isDisabled = false, isDisabled = false,
disableAnimation = false,
disableRipple = false,
isIconOnly = false, isIconOnly = false,
disableRipple = globalContext?.disableRipple ?? false,
disableAnimation = globalContext?.disableAnimation ?? false,
className, className,
...otherProps ...otherProps
} = props; } = props;

View File

@ -1,9 +1,9 @@
import type {ButtonVariantProps} from "@nextui-org/theme"; import type {ButtonVariantProps} from "@nextui-org/theme";
import type {AriaButtonProps} from "@nextui-org/use-aria-button"; import type {AriaButtonProps} from "@nextui-org/use-aria-button";
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import type {ReactNode} from "react"; import type {ReactNode} from "react";
import type {RippleProps} from "@nextui-org/ripple"; import type {RippleProps} from "@nextui-org/ripple";
import {useProviderContext, type HTMLNextUIProps, type PropGetter} from "@nextui-org/system";
import {dataAttr} from "@nextui-org/shared-utils"; import {dataAttr} from "@nextui-org/shared-utils";
import {ReactRef} from "@nextui-org/react-utils"; import {ReactRef} from "@nextui-org/react-utils";
import {MouseEventHandler, useCallback} from "react"; import {MouseEventHandler, useCallback} from "react";
@ -65,6 +65,7 @@ export type UseButtonProps = Props &
export function useButton(props: UseButtonProps) { export function useButton(props: UseButtonProps) {
const groupContext = useButtonGroupContext(); const groupContext = useButtonGroupContext();
const globalContext = useProviderContext();
const isInGroup = !!groupContext; const isInGroup = !!groupContext;
const { const {
@ -76,16 +77,16 @@ export function useButton(props: UseButtonProps) {
autoFocus, autoFocus,
className, className,
spinner, spinner,
isLoading = false,
disableRipple: disableRippleProp = false,
fullWidth = groupContext?.fullWidth ?? false, fullWidth = groupContext?.fullWidth ?? false,
radius = groupContext?.radius,
size = groupContext?.size ?? "md", size = groupContext?.size ?? "md",
color = groupContext?.color ?? "default", color = groupContext?.color ?? "default",
variant = groupContext?.variant ?? "solid", variant = groupContext?.variant ?? "solid",
disableAnimation = groupContext?.disableAnimation ?? false, disableAnimation = groupContext?.disableAnimation ?? globalContext?.disableAnimation ?? false,
radius = groupContext?.radius,
disableRipple = groupContext?.disableRipple ?? false,
isDisabled: isDisabledProp = groupContext?.isDisabled ?? false, isDisabled: isDisabledProp = groupContext?.isDisabled ?? false,
isIconOnly = groupContext?.isIconOnly ?? false, isIconOnly = groupContext?.isIconOnly ?? false,
isLoading = false,
spinnerPlacement = "start", spinnerPlacement = "start",
onPress, onPress,
onClick, onClick,
@ -97,6 +98,8 @@ export function useButton(props: UseButtonProps) {
const domRef = useDOMRef(ref); const domRef = useDOMRef(ref);
const disableRipple = (disableRippleProp || globalContext?.disableRipple) ?? disableAnimation;
const {isFocusVisible, isFocused, focusProps} = useFocusRing({ const {isFocusVisible, isFocused, focusProps} = useFocusRing({
autoFocus, autoFocus,
}); });

View File

@ -10,7 +10,7 @@ import type {CalendarState, RangeCalendarState} from "@react-stately/calendar";
import type {RefObject, ReactNode} from "react"; import type {RefObject, ReactNode} from "react";
import {Calendar, CalendarDate} from "@internationalized/date"; import {Calendar, CalendarDate} from "@internationalized/date";
import {mapPropsVariants} from "@nextui-org/system"; import {mapPropsVariants, useProviderContext} from "@nextui-org/system";
import {useCallback, useMemo} from "react"; import {useCallback, useMemo} from "react";
import {calendar} from "@nextui-org/theme"; import {calendar} from "@nextui-org/theme";
import {useControlledState} from "@react-stately/utils"; import {useControlledState} from "@react-stately/utils";
@ -18,7 +18,6 @@ import {ReactRef, useDOMRef} from "@nextui-org/react-utils";
import {useLocale} from "@react-aria/i18n"; import {useLocale} from "@react-aria/i18n";
import {clamp, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clamp, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
import {mergeProps} from "@react-aria/utils"; import {mergeProps} from "@react-aria/utils";
import {useProviderContext} from "@nextui-org/system";
type NextUIBaseProps = Omit<HTMLNextUIProps<"div">, keyof AriaCalendarPropsBase | "onChange">; type NextUIBaseProps = Omit<HTMLNextUIProps<"div">, keyof AriaCalendarPropsBase | "onChange">;
@ -182,7 +181,7 @@ export type ContextType<T extends CalendarState | RangeCalendarState> = {
export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) { export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
const [props, variantProps] = mapPropsVariants(originalProps, calendar.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, calendar.variantKeys);
const providerContext = useProviderContext(); const globalContext = useProviderContext();
const { const {
ref, ref,
@ -199,9 +198,9 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
isHeaderExpanded: isHeaderExpandedProp, isHeaderExpanded: isHeaderExpandedProp,
isHeaderDefaultExpanded, isHeaderDefaultExpanded,
onHeaderExpandedChange = () => {}, onHeaderExpandedChange = () => {},
minValue = providerContext?.defaultDates?.minDate ?? new CalendarDate(1900, 1, 1), minValue = globalContext?.defaultDates?.minDate ?? new CalendarDate(1900, 1, 1),
maxValue = providerContext?.defaultDates?.maxDate ?? new CalendarDate(2099, 12, 31), maxValue = globalContext?.defaultDates?.maxDate ?? new CalendarDate(2099, 12, 31),
createCalendar: createCalendarProp = providerContext?.createCalendar ?? null, createCalendar: createCalendarProp = globalContext?.createCalendar ?? null,
prevButtonProps: prevButtonPropsProp, prevButtonProps: prevButtonPropsProp,
nextButtonProps: nextButtonPropsProp, nextButtonProps: nextButtonPropsProp,
errorMessage, errorMessage,
@ -254,7 +253,8 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
[objectToDeps(variantProps), showMonthAndYearPickers, isHeaderExpanded, className], [objectToDeps(variantProps), showMonthAndYearPickers, isHeaderExpanded, className],
); );
const disableAnimation = originalProps.disableAnimation ?? false; const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const commonButtonProps: ButtonProps = { const commonButtonProps: ButtonProps = {
size: "sm", size: "sm",
@ -317,6 +317,7 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
shouldFilterDOMProps, shouldFilterDOMProps,
isHeaderExpanded, isHeaderExpanded,
showMonthAndYearPickers, showMonthAndYearPickers,
disableAnimation,
createCalendar: createCalendarProp, createCalendar: createCalendarProp,
getPrevButtonProps, getPrevButtonProps,
getNextButtonProps, getNextButtonProps,

View File

@ -39,6 +39,7 @@ export function useCalendar<T extends DateValue>({
weekdayStyle, weekdayStyle,
visibleDuration, visibleDuration,
baseProps, baseProps,
disableAnimation,
shouldFilterDOMProps, shouldFilterDOMProps,
isHeaderExpanded, isHeaderExpanded,
visibleMonths, visibleMonths,
@ -73,7 +74,6 @@ export function useCalendar<T extends DateValue>({
useAriaCalendar(originalProps, state); useAriaCalendar(originalProps, state);
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);
const disableAnimation = originalProps.disableAnimation ?? false;
const buttonPickerProps: ButtonProps = { const buttonPickerProps: ButtonProps = {
...buttonPickerPropsProp, ...buttonPickerPropsProp,

View File

@ -39,6 +39,7 @@ export function useRangeCalendar<T extends DateValue>({
shouldFilterDOMProps, shouldFilterDOMProps,
isHeaderExpanded, isHeaderExpanded,
visibleMonths, visibleMonths,
disableAnimation,
createCalendar: createCalendarProp, createCalendar: createCalendarProp,
baseProps, baseProps,
getPrevButtonProps, getPrevButtonProps,
@ -70,7 +71,6 @@ export function useRangeCalendar<T extends DateValue>({
useAriaRangeCalendar(originalProps, state, domRef); useAriaRangeCalendar(originalProps, state, domRef);
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);
const disableAnimation = originalProps.disableAnimation ?? false;
const getBaseCalendarProps = (props = {}): CalendarBaseProps => { const getBaseCalendarProps = (props = {}): CalendarBaseProps => {
return { return {

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -9,7 +9,12 @@ import {chain, mergeProps} from "@react-aria/utils";
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
import {useHover} from "@react-aria/interactions"; import {useHover} from "@react-aria/interactions";
import {useAriaButton} from "@nextui-org/use-aria-button"; import {useAriaButton} from "@nextui-org/use-aria-button";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
import {ReactRef, filterDOMProps} from "@nextui-org/react-utils"; import {ReactRef, filterDOMProps} from "@nextui-org/react-utils";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
@ -64,13 +69,14 @@ export type ContextType = {
}; };
export function useCard(originalProps: UseCardProps) { export function useCard(originalProps: UseCardProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, card.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, card.variantKeys);
const { const {
ref, ref,
as, as,
children, children,
disableRipple = false,
onClick, onClick,
onPress, onPress,
autoFocus, autoFocus,
@ -84,12 +90,16 @@ export function useCard(originalProps: UseCardProps) {
const Component = as || (originalProps.isPressable ? "button" : "div"); const Component = as || (originalProps.isPressable ? "button" : "div");
const shouldFilterDOMProps = typeof Component === "string"; const shouldFilterDOMProps = typeof Component === "string";
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const disableRipple = originalProps.disableRipple ?? globalContext?.disableRipple ?? false;
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);
const {onClick: onRippleClickHandler, onClear: onClearRipple, ripples} = useRipple(); const {onClick: onRippleClickHandler, onClear: onClearRipple, ripples} = useRipple();
const handleClick = (e: MouseEvent<HTMLDivElement>) => { const handleClick = (e: MouseEvent<HTMLDivElement>) => {
if (!originalProps.disableAnimation && !disableRipple && domRef.current) { if (!disableAnimation && !disableRipple && domRef.current) {
onRippleClickHandler(e); onRippleClickHandler(e);
} }
}; };
@ -119,25 +129,26 @@ export function useCard(originalProps: UseCardProps) {
() => () =>
card({ card({
...variantProps, ...variantProps,
disableAnimation,
}), }),
[objectToDeps(variantProps)], [objectToDeps(variantProps), disableAnimation],
); );
const context = useMemo<ContextType>( const context = useMemo<ContextType>(
() => ({ () => ({
isDisabled: originalProps.isDisabled,
isFooterBlurred: originalProps.isFooterBlurred,
disableAnimation: originalProps.disableAnimation,
fullWidth: originalProps.fullWidth,
slots, slots,
classNames, classNames,
disableAnimation,
isDisabled: originalProps.isDisabled,
isFooterBlurred: originalProps.isFooterBlurred,
fullWidth: originalProps.fullWidth,
}), }),
[ [
slots, slots,
classNames, classNames,
originalProps.isDisabled, originalProps.isDisabled,
originalProps.isFooterBlurred, originalProps.isFooterBlurred,
originalProps.disableAnimation, disableAnimation,
originalProps.fullWidth, originalProps.fullWidth,
], ],
); );
@ -194,9 +205,9 @@ export function useCard(originalProps: UseCardProps) {
children, children,
isHovered, isHovered,
isPressed, isPressed,
disableAnimation,
isPressable: originalProps.isPressable, isPressable: originalProps.isPressable,
isHoverable: originalProps.isHoverable, isHoverable: originalProps.isHoverable,
disableAnimation: originalProps.disableAnimation,
disableRipple, disableRipple,
handleClick, handleClick,
isFocusVisible, isFocusVisible,

View File

@ -1,10 +1,10 @@
import type {CheckboxGroupSlots, SlotsToClasses} from "@nextui-org/theme"; import type {CheckboxGroupSlots, SlotsToClasses} from "@nextui-org/theme";
import type {AriaCheckboxGroupProps} from "@react-types/checkbox"; import type {AriaCheckboxGroupProps} from "@react-types/checkbox";
import type {Orientation} from "@react-types/shared"; import type {Orientation} from "@react-types/shared";
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import type {ReactRef} from "@nextui-org/react-utils"; import type {ReactRef} from "@nextui-org/react-utils";
import type {CheckboxGroupProps} from "@react-types/checkbox"; import type {CheckboxGroupProps} from "@react-types/checkbox";
import {useProviderContext, type HTMLNextUIProps, type PropGetter} from "@nextui-org/system";
import {useCallback, useMemo} from "react"; import {useCallback, useMemo} from "react";
import {chain, mergeProps} from "@react-aria/utils"; import {chain, mergeProps} from "@react-aria/utils";
import {checkboxGroup} from "@nextui-org/theme"; import {checkboxGroup} from "@nextui-org/theme";
@ -68,6 +68,8 @@ export type ContextType = {
}; };
export function useCheckboxGroup(props: UseCheckboxGroupProps) { export function useCheckboxGroup(props: UseCheckboxGroupProps) {
const globalContext = useProviderContext();
const { const {
as, as,
ref, ref,
@ -85,7 +87,7 @@ export function useCheckboxGroup(props: UseCheckboxGroupProps) {
orientation = "vertical", orientation = "vertical",
lineThrough = false, lineThrough = false,
isDisabled = false, isDisabled = false,
disableAnimation = false, disableAnimation = globalContext?.disableAnimation ?? false,
isReadOnly, isReadOnly,
isRequired, isRequired,
onValueChange, onValueChange,

View File

@ -1,7 +1,7 @@
import type {CheckboxVariantProps, CheckboxSlots, SlotsToClasses} from "@nextui-org/theme"; import type {CheckboxVariantProps, CheckboxSlots, SlotsToClasses} from "@nextui-org/theme";
import type {AriaCheckboxProps} from "@react-types/checkbox"; import type {AriaCheckboxProps} from "@react-types/checkbox";
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import {useProviderContext, type HTMLNextUIProps, type PropGetter} from "@nextui-org/system";
import {ReactNode, Ref, useCallback, useId, useState} from "react"; import {ReactNode, Ref, useCallback, useId, useState} from "react";
import {useMemo, useRef} from "react"; import {useMemo, useRef} from "react";
import {useToggleState} from "@react-stately/toggle"; import {useToggleState} from "@react-stately/toggle";
@ -72,6 +72,7 @@ export type UseCheckboxProps = Omit<Props, "defaultChecked"> &
CheckboxVariantProps; CheckboxVariantProps;
export function useCheckbox(props: UseCheckboxProps = {}) { export function useCheckbox(props: UseCheckboxProps = {}) {
const globalContext = useProviderContext();
const groupContext = useCheckboxGroupContext(); const groupContext = useCheckboxGroupContext();
const isInGroup = !!groupContext; const isInGroup = !!groupContext;
@ -92,7 +93,7 @@ export function useCheckbox(props: UseCheckboxProps = {}) {
radius = groupContext?.radius, radius = groupContext?.radius,
lineThrough = groupContext?.lineThrough ?? false, lineThrough = groupContext?.lineThrough ?? false,
isDisabled: isDisabledProp = groupContext?.isDisabled ?? false, isDisabled: isDisabledProp = groupContext?.isDisabled ?? false,
disableAnimation = groupContext?.disableAnimation ?? false, disableAnimation = groupContext?.disableAnimation ?? globalContext?.disableAnimation ?? false,
isInvalid = validationState ? validationState === "invalid" : groupContext?.isInvalid ?? false, isInvalid = validationState ? validationState === "invalid" : groupContext?.isInvalid ?? false,
isIndeterminate = false, isIndeterminate = false,
defaultSelected, defaultSelected,
@ -334,9 +335,9 @@ export function useCheckbox(props: UseCheckboxProps = {}) {
const getIconProps = useCallback( const getIconProps = useCallback(
() => () =>
({ ({
isSelected: isSelected, isSelected,
isIndeterminate: !!isIndeterminate, isIndeterminate,
disableAnimation: !!disableAnimation, disableAnimation,
className: slots.icon({class: classNames?.icon}), className: slots.icon({class: classNames?.icon}),
} as CheckboxIconProps), } as CheckboxIconProps),
[slots, classNames?.icon, isSelected, isIndeterminate, disableAnimation], [slots, classNames?.icon, isSelected, isIndeterminate, disableAnimation],

View File

@ -112,9 +112,9 @@ export type UseDateInputProps<T extends DateValue> = Props<T> &
AriaDateFieldProps<T>; AriaDateFieldProps<T>;
export function useDateInput<T extends DateValue>(originalProps: UseDateInputProps<T>) { export function useDateInput<T extends DateValue>(originalProps: UseDateInputProps<T>) {
const [props, variantProps] = mapPropsVariants(originalProps, dateInput.variantKeys); const globalContext = useProviderContext();
const providerContext = useProviderContext(); const [props, variantProps] = mapPropsVariants(originalProps, dateInput.variantKeys);
const { const {
ref, ref,
@ -134,9 +134,9 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
descriptionProps: descriptionPropsProp, descriptionProps: descriptionPropsProp,
validationBehavior, validationBehavior,
shouldForceLeadingZeros = true, shouldForceLeadingZeros = true,
minValue = providerContext?.defaultDates?.minDate ?? new CalendarDate(1900, 1, 1), minValue = globalContext?.defaultDates?.minDate ?? new CalendarDate(1900, 1, 1),
maxValue = providerContext?.defaultDates?.maxDate ?? new CalendarDate(2099, 12, 31), maxValue = globalContext?.defaultDates?.maxDate ?? new CalendarDate(2099, 12, 31),
createCalendar: createCalendarProp = providerContext?.createCalendar ?? null, createCalendar: createCalendarProp = globalContext?.createCalendar ?? null,
isInvalid: isInvalidProp = validationState ? validationState === "invalid" : false, isInvalid: isInvalidProp = validationState ? validationState === "invalid" : false,
errorMessage, errorMessage,
} = props; } = props;
@ -144,6 +144,8 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
const domRef = useDOMRef(ref); const domRef = useDOMRef(ref);
const inputRef = useDOMRef(inputRefProp); const inputRef = useDOMRef(inputRefProp);
const disableAnimation = originalProps.disableAnimation ?? globalContext?.disableAnimation;
const {locale} = useLocale(); const {locale} = useLocale();
const state = useDateFieldState({ const state = useDateFieldState({
@ -193,10 +195,11 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
() => () =>
dateInput({ dateInput({
...variantProps, ...variantProps,
disableAnimation,
labelPlacement, labelPlacement,
className, className,
}), }),
[objectToDeps(variantProps), labelPlacement, className], [objectToDeps(variantProps), disableAnimation, labelPlacement, className],
); );
const getLabelProps: PropGetter = (props) => { const getLabelProps: PropGetter = (props) => {

View File

@ -6,7 +6,7 @@ import type {DateInputGroupProps} from "./date-input-group";
import {useLocale} from "@react-aria/i18n"; import {useLocale} from "@react-aria/i18n";
import {mergeProps} from "@react-aria/utils"; import {mergeProps} from "@react-aria/utils";
import {PropGetter} from "@nextui-org/system"; import {PropGetter, useProviderContext} from "@nextui-org/system";
import {HTMLNextUIProps, mapPropsVariants} from "@nextui-org/system"; import {HTMLNextUIProps, mapPropsVariants} from "@nextui-org/system";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {useTimeField as useAriaTimeField} from "@react-aria/datepicker"; import {useTimeField as useAriaTimeField} from "@react-aria/datepicker";
@ -73,6 +73,8 @@ export type UseTimeInputProps<T extends TimeValue> = Props<T> &
Omit<AriaTimeFieldProps<T>, "validationBehavior">; Omit<AriaTimeFieldProps<T>, "validationBehavior">;
export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputProps<T>) { export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputProps<T>) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, dateInput.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, dateInput.variantKeys);
const { const {
@ -104,12 +106,15 @@ export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputPro
const {locale} = useLocale(); const {locale} = useLocale();
const disableAnimation = originalProps.disableAnimation ?? globalContext?.disableAnimation;
const state = useTimeFieldState({ const state = useTimeFieldState({
...originalProps, ...originalProps,
label, label,
locale, locale,
minValue, minValue,
maxValue, maxValue,
isInvalid: isInvalidProp, isInvalid: isInvalidProp,
shouldForceLeadingZeros, shouldForceLeadingZeros,
}); });
@ -150,10 +155,11 @@ export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputPro
() => () =>
dateInput({ dateInput({
...variantProps, ...variantProps,
disableAnimation,
labelPlacement, labelPlacement,
className, className,
}), }),
[objectToDeps(variantProps), labelPlacement, className], [objectToDeps(variantProps), labelPlacement, disableAnimation, className],
); );
const getLabelProps: PropGetter = (props) => { const getLabelProps: PropGetter = (props) => {

View File

@ -9,7 +9,7 @@ import type {ValueBase} from "@react-types/shared";
import {dateInput, DatePickerVariantProps} from "@nextui-org/theme"; import {dateInput, DatePickerVariantProps} from "@nextui-org/theme";
import {useState} from "react"; import {useState} from "react";
import {HTMLNextUIProps, mapPropsVariants} from "@nextui-org/system"; import {HTMLNextUIProps, mapPropsVariants, useProviderContext} from "@nextui-org/system";
import {mergeProps} from "@react-aria/utils"; import {mergeProps} from "@react-aria/utils";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {dataAttr} from "@nextui-org/shared-utils"; import {dataAttr} from "@nextui-org/shared-utils";
@ -112,6 +112,8 @@ export type UseDatePickerBaseProps<T extends DateValue> = Props<T> &
Omit<AriaDatePickerBaseProps<T>, keyof ValueBase<T> | "validate" | "validationBehavior">; Omit<AriaDatePickerBaseProps<T>, keyof ValueBase<T> | "validate" | "validationBehavior">;
export function useDatePickerBase<T extends DateValue>(originalProps: UseDatePickerBaseProps<T>) { export function useDatePickerBase<T extends DateValue>(originalProps: UseDatePickerBaseProps<T>) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, dateInput.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, dateInput.variantKeys);
const [isCalendarHeaderExpanded, setIsCalendarHeaderExpanded] = useState(false); const [isCalendarHeaderExpanded, setIsCalendarHeaderExpanded] = useState(false);
@ -145,7 +147,8 @@ export function useDatePickerBase<T extends DateValue>(originalProps: UseDatePic
} = props; } = props;
const domRef = useDOMRef(ref); const domRef = useDOMRef(ref);
const disableAnimation = originalProps.disableAnimation ?? false; const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
let stringFormatter = useLocalizedStringFormatter(intlMessages) as any; let stringFormatter = useLocalizedStringFormatter(intlMessages) as any;

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -1,8 +1,8 @@
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import type {PopoverProps} from "@nextui-org/popover"; import type {PopoverProps} from "@nextui-org/popover";
import type {MenuTriggerType} from "@react-types/menu"; import type {MenuTriggerType} from "@react-types/menu";
import type {Ref} from "react"; import type {Ref} from "react";
import {useProviderContext, type HTMLNextUIProps, type PropGetter} from "@nextui-org/system";
import {useMenuTriggerState} from "@react-stately/menu"; import {useMenuTriggerState} from "@react-stately/menu";
import {useMenuTrigger} from "@react-aria/menu"; import {useMenuTrigger} from "@react-aria/menu";
import {dropdown} from "@nextui-org/theme"; import {dropdown} from "@nextui-org/theme";
@ -41,6 +41,8 @@ interface Props extends HTMLNextUIProps<"div"> {
export type UseDropdownProps = Props & Omit<PopoverProps, "children" | "color" | "variant">; export type UseDropdownProps = Props & Omit<PopoverProps, "children" | "color" | "variant">;
export function useDropdown(props: UseDropdownProps) { export function useDropdown(props: UseDropdownProps) {
const globalContext = useProviderContext();
const { const {
as, as,
triggerRef: triggerRefProp, triggerRef: triggerRefProp,
@ -54,7 +56,7 @@ export function useDropdown(props: UseDropdownProps) {
closeOnSelect = true, closeOnSelect = true,
shouldBlockScroll = true, shouldBlockScroll = true,
classNames: classNamesProp, classNames: classNamesProp,
disableAnimation = false, disableAnimation = globalContext?.disableAnimation ?? false,
onClose, onClose,
className, className,
...otherProps ...otherProps

View File

@ -116,7 +116,6 @@ const defaultProps = {
offset: 7, offset: 7,
isDisabled: false, isDisabled: false,
defaultOpen: false, defaultOpen: false,
disableAnimation: false,
}; };
const items = [ const items = [

View File

@ -1,7 +1,12 @@
import type {ImageVariantProps, SlotsToClasses, ImageSlots} from "@nextui-org/theme"; import type {ImageVariantProps, SlotsToClasses, ImageSlots} from "@nextui-org/theme";
import {ImgHTMLAttributes, useCallback} from "react"; import {ImgHTMLAttributes, useCallback} from "react";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {image} from "@nextui-org/theme"; import {image} from "@nextui-org/theme";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
@ -70,6 +75,8 @@ interface Props extends HTMLNextUIProps<"img"> {
export type UseImageProps = Props & ImageVariantProps; export type UseImageProps = Props & ImageVariantProps;
export function useImage(originalProps: UseImageProps) { export function useImage(originalProps: UseImageProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, image.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, image.variantKeys);
const { const {
@ -103,6 +110,9 @@ export function useImage(originalProps: UseImageProps) {
crossOrigin, crossOrigin,
}); });
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const isImgLoaded = imageStatus === "loaded" && !isLoadingProp; const isImgLoaded = imageStatus === "loaded" && !isLoadingProp;
const isLoading = imageStatus === "loading" || isLoadingProp; const isLoading = imageStatus === "loading" || isLoadingProp;
const isZoomed = originalProps.isZoomed; const isZoomed = originalProps.isZoomed;
@ -128,9 +138,10 @@ export function useImage(originalProps: UseImageProps) {
() => () =>
image({ image({
...variantProps, ...variantProps,
disableAnimation,
showSkeleton, showSkeleton,
}), }),
[objectToDeps(variantProps), showSkeleton], [objectToDeps(variantProps), disableAnimation, showSkeleton],
); );
const baseStyles = clsx(className, classNames?.img); const baseStyles = clsx(className, classNames?.img);

View File

@ -30,6 +30,11 @@ export default {
type: "boolean", type: "boolean",
}, },
}, },
disableAnimation: {
control: {
type: "boolean",
},
},
showSkeleton: { showSkeleton: {
control: { control: {
disable: true, disable: true,

View File

@ -1,7 +1,12 @@
import type {InputVariantProps, SlotsToClasses, InputSlots} from "@nextui-org/theme"; import type {InputVariantProps, SlotsToClasses, InputSlots} from "@nextui-org/theme";
import type {AriaTextFieldOptions} from "@react-aria/textfield"; import type {AriaTextFieldOptions} from "@react-aria/textfield";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect"; import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect";
import {AriaTextFieldProps} from "@react-types/textfield"; import {AriaTextFieldProps} from "@react-types/textfield";
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
@ -86,6 +91,8 @@ export type UseInputProps<T extends HTMLInputElement | HTMLTextAreaElement = HTM
export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement>( export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement>(
originalProps: UseInputProps<T>, originalProps: UseInputProps<T>,
) { ) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, input.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, input.variantKeys);
const { const {
@ -120,6 +127,9 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
const Component = as || "div"; const Component = as || "div";
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const domRef = useDOMRef<T>(ref); const domRef = useDOMRef<T>(ref);
const baseDomRef = useDOMRef<HTMLDivElement>(baseRef); const baseDomRef = useDOMRef<HTMLDivElement>(baseRef);
const inputWrapperRef = useDOMRef<HTMLDivElement>(wrapperRef); const inputWrapperRef = useDOMRef<HTMLDivElement>(wrapperRef);
@ -239,8 +249,16 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
isInvalid, isInvalid,
labelPlacement, labelPlacement,
isClearable, isClearable,
disableAnimation,
}), }),
[objectToDeps(variantProps), isInvalid, labelPlacement, isClearable, hasStartContent], [
objectToDeps(variantProps),
isInvalid,
labelPlacement,
isClearable,
hasStartContent,
disableAnimation,
],
); );
const getBaseProps: PropGetter = useCallback( const getBaseProps: PropGetter = useCallback(

View File

@ -3,7 +3,12 @@ import type {LinkVariantProps} from "@nextui-org/theme";
import {link} from "@nextui-org/theme"; import {link} from "@nextui-org/theme";
import {useAriaLink} from "@nextui-org/use-aria-link"; import {useAriaLink} from "@nextui-org/use-aria-link";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
import {dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {dataAttr, objectToDeps} from "@nextui-org/shared-utils";
@ -36,6 +41,8 @@ interface Props extends HTMLNextUIProps<"a">, LinkVariantProps {
export type UseLinkProps = Props & AriaLinkProps; export type UseLinkProps = Props & AriaLinkProps;
export function useLink(originalProps: UseLinkProps) { export function useLink(originalProps: UseLinkProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, link.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, link.variantKeys);
const { const {
@ -57,6 +64,8 @@ export function useLink(originalProps: UseLinkProps) {
const Component = as || "a"; const Component = as || "a";
const domRef = useDOMRef(ref); const domRef = useDOMRef(ref);
const disableAnimation =
originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
const {linkProps} = useAriaLink( const {linkProps} = useAriaLink(
{ {
@ -85,9 +94,10 @@ export function useLink(originalProps: UseLinkProps) {
() => () =>
link({ link({
...variantProps, ...variantProps,
disableAnimation,
className, className,
}), }),
[objectToDeps(variantProps), className], [objectToDeps(variantProps), disableAnimation, className],
); );
const getLinkProps: PropGetter = useCallback(() => { const getLinkProps: PropGetter = useCallback(() => {

View File

@ -2,7 +2,12 @@ import type {ListboxItemBaseProps} from "./base/listbox-item-base";
import {useMemo, useRef, useCallback} from "react"; import {useMemo, useRef, useCallback} from "react";
import {listboxItem} from "@nextui-org/theme"; import {listboxItem} from "@nextui-org/theme";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
import {Node} from "@react-types/shared"; import {Node} from "@react-types/shared";
import {filterDOMProps} from "@nextui-org/react-utils"; import {filterDOMProps} from "@nextui-org/react-utils";
@ -22,6 +27,8 @@ export type UseListboxItemProps<T extends object> = Props<T> &
Omit<HTMLNextUIProps<"li">, keyof Props<T>>; Omit<HTMLNextUIProps<"li">, keyof Props<T>>;
export function useListboxItem<T extends object>(originalProps: UseListboxItemProps<T>) { export function useListboxItem<T extends object>(originalProps: UseListboxItemProps<T>) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, listboxItem.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, listboxItem.variantKeys);
const { const {
@ -44,7 +51,8 @@ export function useListboxItem<T extends object>(originalProps: UseListboxItemPr
...otherProps ...otherProps
} = props; } = props;
const disableAnimation = originalProps.disableAnimation; const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const domRef = useRef<HTMLLIElement>(null); const domRef = useRef<HTMLLIElement>(null);

View File

@ -1,7 +1,7 @@
import type {KeyboardDelegate} from "@react-types/shared"; import type {KeyboardDelegate} from "@react-types/shared";
import {AriaListBoxProps, useListBox as useAriaListbox} from "@react-aria/listbox"; import {AriaListBoxProps, useListBox as useAriaListbox} from "@react-aria/listbox";
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system"; import {HTMLNextUIProps, PropGetter, useProviderContext} from "@nextui-org/system";
import {listbox, ListboxVariantProps, ListboxSlots, SlotsToClasses} from "@nextui-org/theme"; import {listbox, ListboxVariantProps, ListboxSlots, SlotsToClasses} from "@nextui-org/theme";
import {ListState, useListState} from "@react-stately/list"; import {ListState, useListState} from "@react-stately/list";
import {filterDOMProps, ReactRef, useDOMRef} from "@nextui-org/react-utils"; import {filterDOMProps, ReactRef, useDOMRef} from "@nextui-org/react-utils";
@ -97,6 +97,8 @@ interface Props<T> extends Omit<HTMLNextUIProps<"ul">, "children"> {
export type UseListboxProps<T = object> = Props<T> & AriaListBoxOptions<T> & ListboxVariantProps; export type UseListboxProps<T = object> = Props<T> & AriaListBoxOptions<T> & ListboxVariantProps;
export function useListbox<T extends object>(props: UseListboxProps<T>) { export function useListbox<T extends object>(props: UseListboxProps<T>) {
const globalContext = useProviderContext();
const { const {
ref, ref,
as, as,
@ -106,7 +108,7 @@ export function useListbox<T extends object>(props: UseListboxProps<T>) {
onAction, onAction,
children, children,
onSelectionChange, onSelectionChange,
disableAnimation, disableAnimation = globalContext?.disableAnimation ?? false,
itemClasses, itemClasses,
className, className,
topContent, topContent,

View File

@ -3,7 +3,12 @@ import type {Node} from "@react-types/shared";
import {useMemo, useRef, useCallback} from "react"; import {useMemo, useRef, useCallback} from "react";
import {menuItem} from "@nextui-org/theme"; import {menuItem} from "@nextui-org/theme";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
import {TreeState} from "@react-stately/tree"; import {TreeState} from "@react-stately/tree";
import {clsx, dataAttr, objectToDeps, removeEvents} from "@nextui-org/shared-utils"; import {clsx, dataAttr, objectToDeps, removeEvents} from "@nextui-org/shared-utils";
@ -21,6 +26,8 @@ export type UseMenuItemProps<T extends object> = Props<T> &
Omit<HTMLNextUIProps<"li">, keyof Props<T>>; Omit<HTMLNextUIProps<"li">, keyof Props<T>>;
export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>) { export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, menuItem.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, menuItem.variantKeys);
const { const {
@ -50,7 +57,8 @@ export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>
...otherProps ...otherProps
} = props; } = props;
const disableAnimation = originalProps.disableAnimation; const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const domRef = useRef<HTMLLIElement>(null); const domRef = useRef<HTMLLIElement>(null);

View File

@ -1,5 +1,4 @@
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system"; import {useProviderContext, type HTMLNextUIProps, type PropGetter} from "@nextui-org/system";
import {AriaMenuProps} from "@react-types/menu"; import {AriaMenuProps} from "@react-types/menu";
import {AriaMenuOptions} from "@react-aria/menu"; import {AriaMenuOptions} from "@react-aria/menu";
import {useAriaMenu} from "@nextui-org/use-aria-menu"; import {useAriaMenu} from "@nextui-org/use-aria-menu";
@ -90,13 +89,15 @@ export type UseMenuProps<T = object> = Props<T> &
MenuVariantProps; MenuVariantProps;
export function useMenu<T extends object>(props: UseMenuProps<T>) { export function useMenu<T extends object>(props: UseMenuProps<T>) {
const globalContext = useProviderContext();
const { const {
as, as,
ref, ref,
variant, variant,
color, color,
children, children,
disableAnimation, disableAnimation = globalContext?.disableAnimation ?? false,
onAction, onAction,
closeOnSelect, closeOnSelect,
itemClasses, itemClasses,

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -5,7 +5,12 @@ import {AriaModalOverlayProps} from "@react-aria/overlays";
import {useAriaModalOverlay} from "@nextui-org/use-aria-modal-overlay"; import {useAriaModalOverlay} from "@nextui-org/use-aria-modal-overlay";
import {useCallback, useId, useRef, useState, useMemo, ReactNode} from "react"; import {useCallback, useId, useRef, useState, useMemo, ReactNode} from "react";
import {modal} from "@nextui-org/theme"; import {modal} from "@nextui-org/theme";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {useAriaButton} from "@nextui-org/use-aria-button"; import {useAriaButton} from "@nextui-org/use-aria-button";
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
@ -74,6 +79,8 @@ interface Props extends HTMLNextUIProps<"section"> {
export type UseModalProps = Props & OverlayTriggerProps & AriaModalOverlayProps & ModalVariantProps; export type UseModalProps = Props & OverlayTriggerProps & AriaModalOverlayProps & ModalVariantProps;
export function useModal(originalProps: UseModalProps) { export function useModal(originalProps: UseModalProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, modal.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, modal.variantKeys);
const { const {
@ -81,7 +88,7 @@ export function useModal(originalProps: UseModalProps) {
as, as,
className, className,
classNames, classNames,
disableAnimation = false,
isOpen, isOpen,
defaultOpen, defaultOpen,
onOpenChange, onOpenChange,
@ -104,6 +111,9 @@ export function useModal(originalProps: UseModalProps) {
const [headerMounted, setHeaderMounted] = useState(false); const [headerMounted, setHeaderMounted] = useState(false);
const [bodyMounted, setBodyMounted] = useState(false); const [bodyMounted, setBodyMounted] = useState(false);
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const dialogId = useId(); const dialogId = useId();
const headerId = useId(); const headerId = useId();
const bodyId = useId(); const bodyId = useId();
@ -139,8 +149,9 @@ export function useModal(originalProps: UseModalProps) {
() => () =>
modal({ modal({
...variantProps, ...variantProps,
disableAnimation,
}), }),
[objectToDeps(variantProps)], [objectToDeps(variantProps), disableAnimation],
); );
const getDialogProps: PropGetter = (props = {}, ref = null) => ({ const getDialogProps: PropGetter = (props = {}, ref = null) => ({

View File

@ -74,7 +74,6 @@ export default {
const defaultProps = { const defaultProps = {
...modal.defaultVariants, ...modal.defaultVariants,
disableAnimation: false,
isDismissable: true, isDismissable: true,
isKeyboardDismissDisabled: false, isKeyboardDismissDisabled: false,
}; };

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -1,6 +1,11 @@
import type {NavbarVariantProps, SlotsToClasses, NavbarSlots} from "@nextui-org/theme"; import type {NavbarVariantProps, SlotsToClasses, NavbarSlots} from "@nextui-org/theme";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {navbar} from "@nextui-org/theme"; import {navbar} from "@nextui-org/theme";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
@ -86,6 +91,8 @@ interface Props extends HTMLNextUIProps<"nav"> {
export type UseNavbarProps = Props & NavbarVariantProps; export type UseNavbarProps = Props & NavbarVariantProps;
export function useNavbar(originalProps: UseNavbarProps) { export function useNavbar(originalProps: UseNavbarProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, navbar.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, navbar.variantKeys);
const { const {
@ -106,6 +113,8 @@ export function useNavbar(originalProps: UseNavbarProps) {
} = props; } = props;
const Component = as || "nav"; const Component = as || "nav";
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const domRef = useDOMRef(ref); const domRef = useDOMRef(ref);
@ -159,9 +168,10 @@ export function useNavbar(originalProps: UseNavbarProps) {
() => () =>
navbar({ navbar({
...variantProps, ...variantProps,
disableAnimation,
hideOnScroll: shouldHideOnScroll, hideOnScroll: shouldHideOnScroll,
}), }),
[objectToDeps(variantProps), shouldHideOnScroll], [objectToDeps(variantProps), disableAnimation, shouldHideOnScroll],
); );
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);
@ -206,7 +216,7 @@ export function useNavbar(originalProps: UseNavbarProps) {
domRef, domRef,
height, height,
isHidden, isHidden,
disableAnimation: originalProps.disableAnimation ?? false, disableAnimation,
shouldHideOnScroll, shouldHideOnScroll,
isMenuOpen, isMenuOpen,
classNames, classNames,

View File

@ -10,7 +10,7 @@ import {
PaginationItemType, PaginationItemType,
} from "@nextui-org/use-pagination"; } from "@nextui-org/use-pagination";
import {useEffect, useRef, useMemo} from "react"; import {useEffect, useRef, useMemo} from "react";
import {mapPropsVariants} from "@nextui-org/system"; import {mapPropsVariants, useProviderContext} from "@nextui-org/system";
import {usePagination as useBasePagination} from "@nextui-org/use-pagination"; import {usePagination as useBasePagination} from "@nextui-org/use-pagination";
import scrollIntoView from "scroll-into-view-if-needed"; import scrollIntoView from "scroll-into-view-if-needed";
import {pagination} from "@nextui-org/theme"; import {pagination} from "@nextui-org/theme";
@ -163,6 +163,8 @@ export type UsePaginationProps = Props & UseBasePaginationProps & PaginationVari
export const CURSOR_TRANSITION_TIMEOUT = 300; // in ms export const CURSOR_TRANSITION_TIMEOUT = 300; // in ms
export function usePagination(originalProps: UsePaginationProps) { export function usePagination(originalProps: UsePaginationProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, pagination.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, pagination.variantKeys);
const { const {
@ -196,6 +198,10 @@ export function usePagination(originalProps: UsePaginationProps) {
const isRTL = direction === "rtl"; const isRTL = direction === "rtl";
const disableAnimation =
originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
const disableCursorAnimation = originalProps?.disableCursorAnimation ?? disableAnimation ?? false;
function getItemsRefMap() { function getItemsRefMap() {
if (!itemsRef.current) { if (!itemsRef.current) {
// Initialize the Map on first usage. // Initialize the Map on first usage.
@ -275,14 +281,14 @@ export function usePagination(originalProps: UsePaginationProps) {
const activePageRef = useRef(activePage); const activePageRef = useRef(activePage);
useEffect(() => { useEffect(() => {
if (activePage && !originalProps.disableAnimation) { if (activePage && !disableAnimation) {
scrollTo(activePage, activePage === activePageRef.current); scrollTo(activePage, activePage === activePageRef.current);
} }
activePageRef.current = activePage; activePageRef.current = activePage;
}, [ }, [
activePage, activePage,
originalProps.disableAnimation, disableAnimation,
originalProps.disableCursorAnimation, disableCursorAnimation,
originalProps.dotsJump, originalProps.dotsJump,
originalProps.isCompact, originalProps.isCompact,
originalProps.showControls, originalProps.showControls,
@ -292,10 +298,9 @@ export function usePagination(originalProps: UsePaginationProps) {
() => () =>
pagination({ pagination({
...variantProps, ...variantProps,
disableCursorAnimation: disableCursorAnimation: disableCursorAnimation || disableAnimation,
originalProps.disableCursorAnimation || originalProps.disableAnimation,
}), }),
[objectToDeps(variantProps)], [objectToDeps(variantProps), disableCursorAnimation, disableAnimation],
); );
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);
@ -400,8 +405,8 @@ export function usePagination(originalProps: UsePaginationProps) {
range, range,
activePage, activePage,
getItemRef, getItemRef,
disableCursorAnimation: originalProps.disableCursorAnimation, disableAnimation,
disableAnimation: originalProps.disableAnimation, disableCursorAnimation,
setPage, setPage,
onPrevious, onPrevious,
onNext, onNext,

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -8,7 +8,12 @@ import {OverlayTriggerState, useOverlayTriggerState} from "@react-stately/overla
import {useFocusRing} from "@react-aria/focus"; import {useFocusRing} from "@react-aria/focus";
import {ariaHideOutside, useOverlayTrigger} from "@react-aria/overlays"; import {ariaHideOutside, useOverlayTrigger} from "@react-aria/overlays";
import {OverlayTriggerProps} from "@react-types/overlays"; import {OverlayTriggerProps} from "@react-types/overlays";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {getArrowPlacement, getShouldUseAxisPlacement} from "@nextui-org/aria-utils"; import {getArrowPlacement, getShouldUseAxisPlacement} from "@nextui-org/aria-utils";
import {popover} from "@nextui-org/theme"; import {popover} from "@nextui-org/theme";
import {mergeProps, mergeRefs} from "@react-aria/utils"; import {mergeProps, mergeRefs} from "@react-aria/utils";
@ -82,6 +87,8 @@ export type UsePopoverProps = Props &
PopoverVariantProps; PopoverVariantProps;
export function usePopover(originalProps: UsePopoverProps) { export function usePopover(originalProps: UsePopoverProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, popover.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, popover.variantKeys);
const { const {
@ -127,7 +134,8 @@ export function usePopover(originalProps: UsePopoverProps) {
const dialogRef = useRef(null); const dialogRef = useRef(null);
const triggerRef = triggerRefProp || domTriggerRef; const triggerRef = triggerRefProp || domTriggerRef;
const disableAnimation = originalProps.disableAnimation ?? false; const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const innerState = useOverlayTriggerState({ const innerState = useOverlayTriggerState({
isOpen: isOpenProp, isOpen: isOpenProp,

View File

@ -106,7 +106,6 @@ const defaultProps = {
placement: "top", placement: "top",
offset: 7, offset: 7,
defaultOpen: false, defaultOpen: false,
disableAnimation: false,
}; };
const content = ( const content = (
@ -122,7 +121,7 @@ const Template = (args: PopoverProps) => {
return ( return (
<Popover {...args}> <Popover {...args}>
<PopoverTrigger> <PopoverTrigger>
<Button disableAnimation={!!args.disableAnimation}>Open Popover</Button> <Button>Open Popover</Button>
</PopoverTrigger> </PopoverTrigger>
{content} {content}
</Popover> </Popover>
@ -133,7 +132,7 @@ const WithTitlePropsTemplate = (args: PopoverProps) => {
return ( return (
<Popover {...args}> <Popover {...args}>
<PopoverTrigger> <PopoverTrigger>
<Button disableAnimation={!!args.disableAnimation}>Open Popover</Button> <Button>Open Popover</Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent> <PopoverContent>
{(titleProps) => ( {(titleProps) => (

View File

@ -6,7 +6,7 @@ import type {
import type {PropGetter} from "@nextui-org/system"; import type {PropGetter} from "@nextui-org/system";
import type {AriaProgressBarProps} from "@react-types/progress"; import type {AriaProgressBarProps} from "@react-types/progress";
import {HTMLNextUIProps, mapPropsVariants} from "@nextui-org/system"; import {HTMLNextUIProps, mapPropsVariants, useProviderContext} from "@nextui-org/system";
import {circularProgress} from "@nextui-org/theme"; import {circularProgress} from "@nextui-org/theme";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {clampPercentage, clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clampPercentage, clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
@ -53,6 +53,7 @@ export interface Props extends HTMLNextUIProps<"div"> {
export type UseCircularProgressProps = Props & AriaProgressBarProps & CircularProgressVariantProps; export type UseCircularProgressProps = Props & AriaProgressBarProps & CircularProgressVariantProps;
export function useCircularProgress(originalProps: UseCircularProgressProps) { export function useCircularProgress(originalProps: UseCircularProgressProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, circularProgress.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, circularProgress.variantKeys);
const { const {
@ -86,6 +87,8 @@ export function useCircularProgress(originalProps: UseCircularProgressProps) {
// default isIndeterminate to true // default isIndeterminate to true
const isIndeterminate = (originalProps.isIndeterminate ?? true) && value === undefined; const isIndeterminate = (originalProps.isIndeterminate ?? true) && value === undefined;
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const {progressBarProps, labelProps} = useAriaProgress({ const {progressBarProps, labelProps} = useAriaProgress({
id, id,
@ -104,12 +107,13 @@ export function useCircularProgress(originalProps: UseCircularProgressProps) {
() => () =>
circularProgress({ circularProgress({
...variantProps, ...variantProps,
disableAnimation,
isIndeterminate, isIndeterminate,
}), }),
[objectToDeps(variantProps), isIndeterminate], [objectToDeps(variantProps), disableAnimation, isIndeterminate],
); );
const selfMounted = originalProps.disableAnimation ? true : isMounted; const selfMounted = disableAnimation ? true : isMounted;
const center = 16; const center = 16;
const strokeWidth = strokeWidthProp || (originalProps.size === "sm" ? 2 : 3); const strokeWidth = strokeWidthProp || (originalProps.size === "sm" ? 2 : 3);

View File

@ -2,7 +2,7 @@ import type {ProgressVariantProps, SlotsToClasses, ProgressSlots} from "@nextui-
import type {PropGetter} from "@nextui-org/system"; import type {PropGetter} from "@nextui-org/system";
import type {AriaProgressBarProps} from "@react-types/progress"; import type {AriaProgressBarProps} from "@react-types/progress";
import {HTMLNextUIProps, mapPropsVariants} from "@nextui-org/system"; import {HTMLNextUIProps, mapPropsVariants, useProviderContext} from "@nextui-org/system";
import {progress} from "@nextui-org/theme"; import {progress} from "@nextui-org/theme";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {clampPercentage, clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clampPercentage, clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
@ -44,6 +44,7 @@ interface Props extends HTMLNextUIProps<"div"> {
export type UseProgressProps = Props & AriaProgressBarProps & ProgressVariantProps; export type UseProgressProps = Props & AriaProgressBarProps & ProgressVariantProps;
export function useProgress(originalProps: UseProgressProps) { export function useProgress(originalProps: UseProgressProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, progress.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, progress.variantKeys);
const { const {
@ -73,8 +74,12 @@ export function useProgress(originalProps: UseProgressProps) {
rerender: true, rerender: true,
delay: 100, delay: 100,
}); });
const isIndeterminate = originalProps.isIndeterminate; const isIndeterminate = originalProps.isIndeterminate;
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const {progressBarProps, labelProps} = useAriaProgress({ const {progressBarProps, labelProps} = useAriaProgress({
id, id,
label, label,
@ -92,11 +97,12 @@ export function useProgress(originalProps: UseProgressProps) {
() => () =>
progress({ progress({
...variantProps, ...variantProps,
disableAnimation,
}), }),
[objectToDeps(variantProps)], [objectToDeps(variantProps), disableAnimation],
); );
const selfMounted = originalProps.disableAnimation ? true : isMounted; const selfMounted = disableAnimation ? true : isMounted;
// Calculate the width of the progress bar as a percentage // Calculate the width of the progress bar as a percentage
const percentage = useMemo( const percentage = useMemo(

View File

@ -7,7 +7,7 @@ import {radioGroup} from "@nextui-org/theme";
import {useCallback, useMemo} from "react"; import {useCallback, useMemo} from "react";
import {RadioGroupState, useRadioGroupState} from "@react-stately/radio"; import {RadioGroupState, useRadioGroupState} from "@react-stately/radio";
import {useRadioGroup as useReactAriaRadioGroup} from "@react-aria/radio"; import {useRadioGroup as useReactAriaRadioGroup} from "@react-aria/radio";
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system"; import {HTMLNextUIProps, PropGetter, useProviderContext} from "@nextui-org/system";
import {filterDOMProps, useDOMRef} from "@nextui-org/react-utils"; import {filterDOMProps, useDOMRef} from "@nextui-org/react-utils";
import {clsx, safeAriaLabel} from "@nextui-org/shared-utils"; import {clsx, safeAriaLabel} from "@nextui-org/shared-utils";
import {mergeProps} from "@react-aria/utils"; import {mergeProps} from "@react-aria/utils";
@ -62,6 +62,8 @@ export type ContextType = {
}; };
export function useRadioGroup(props: UseRadioGroupProps) { export function useRadioGroup(props: UseRadioGroupProps) {
const globalContext = useProviderContext();
const { const {
as, as,
ref, ref,
@ -75,7 +77,7 @@ export function useRadioGroup(props: UseRadioGroupProps) {
size = "md", size = "md",
color = "primary", color = "primary",
isDisabled = false, isDisabled = false,
disableAnimation = false, disableAnimation = globalContext?.disableAnimation ?? false,
orientation = "vertical", orientation = "vertical",
isRequired = false, isRequired = false,
isReadOnly, isReadOnly,

View File

@ -7,7 +7,7 @@ import {useFocusRing} from "@react-aria/focus";
import {useHover, usePress} from "@react-aria/interactions"; import {useHover, usePress} from "@react-aria/interactions";
import {radio} from "@nextui-org/theme"; import {radio} from "@nextui-org/theme";
import {useRadio as useReactAriaRadio} from "@react-aria/radio"; import {useRadio as useReactAriaRadio} from "@react-aria/radio";
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system"; import {HTMLNextUIProps, PropGetter, useProviderContext} from "@nextui-org/system";
import {__DEV__, warn, clsx, dataAttr} from "@nextui-org/shared-utils"; import {__DEV__, warn, clsx, dataAttr} from "@nextui-org/shared-utils";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {chain, mergeProps} from "@react-aria/utils"; import {chain, mergeProps} from "@react-aria/utils";
@ -51,6 +51,7 @@ export type UseRadioProps = Omit<Props, "defaultChecked"> &
RadioVariantProps; RadioVariantProps;
export function useRadio(props: UseRadioProps) { export function useRadio(props: UseRadioProps) {
const globalContext = useProviderContext();
const groupContext = useRadioGroupContext(); const groupContext = useRadioGroupContext();
const { const {
@ -64,7 +65,7 @@ export function useRadio(props: UseRadioProps) {
size = groupContext?.size ?? "md", size = groupContext?.size ?? "md",
color = groupContext?.color ?? "primary", color = groupContext?.color ?? "primary",
isDisabled: isDisabledProp = groupContext?.isDisabled ?? false, isDisabled: isDisabledProp = groupContext?.isDisabled ?? false,
disableAnimation = groupContext?.disableAnimation ?? false, disableAnimation = groupContext?.disableAnimation ?? globalContext?.disableAnimation ?? false,
onChange = groupContext?.onChange, onChange = groupContext?.onChange,
autoFocus = false, autoFocus = false,
className, className,

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -1,9 +1,10 @@
import {FC} from "react"; import type {RippleType} from "./use-ripple";
import {AnimatePresence, HTMLMotionProps, m, LazyMotion, domAnimation} from "framer-motion"; import type {FC} from "react";
import {HTMLNextUIProps} from "@nextui-org/system"; import type {HTMLMotionProps} from "framer-motion";
import {clamp} from "@nextui-org/shared-utils"; import type {HTMLNextUIProps} from "@nextui-org/system";
import {RippleType} from "./use-ripple"; import {AnimatePresence, m, LazyMotion, domAnimation} from "framer-motion";
import {clamp} from "@nextui-org/shared-utils";
export interface RippleProps extends HTMLNextUIProps<"span"> { export interface RippleProps extends HTMLNextUIProps<"span"> {
ripples: RippleType[]; ripples: RippleType[];
@ -22,38 +23,36 @@ const Ripple: FC<RippleProps> = (props) => {
const duration = clamp(0.01 * ripple.size, 0.2, ripple.size > 100 ? 0.75 : 0.5); const duration = clamp(0.01 * ripple.size, 0.2, ripple.size > 100 ? 0.75 : 0.5);
return ( return (
<AnimatePresence key={ripple.key} mode="popLayout"> <LazyMotion key={ripple.key} features={domAnimation}>
<> <AnimatePresence mode="popLayout">
<LazyMotion features={domAnimation}> <m.span
<m.span animate={{transform: "scale(2)", opacity: 0}}
animate={{transform: "scale(2)", opacity: 0}} className="nextui-ripple"
className="nextui-ripple" exit={{opacity: 0}}
exit={{opacity: 0}} initial={{transform: "scale(0)", opacity: 0.35}}
initial={{transform: "scale(0)", opacity: 0.35}} style={{
style={{ position: "absolute",
position: "absolute", backgroundColor: color,
backgroundColor: color, borderRadius: "100%",
borderRadius: "100%", transformOrigin: "center",
transformOrigin: "center", pointerEvents: "none",
pointerEvents: "none", overflow: "hidden",
overflow: "hidden", inset: 0,
inset: 0, zIndex: 0,
zIndex: 0, top: ripple.y,
top: ripple.y, left: ripple.x,
left: ripple.x, width: `${ripple.size}px`,
width: `${ripple.size}px`, height: `${ripple.size}px`,
height: `${ripple.size}px`, ...style,
...style, }}
}} transition={{duration}}
transition={{duration}} onAnimationComplete={() => {
onAnimationComplete={() => { onClear(ripple.key);
onClear(ripple.key); }}
}} {...motionProps}
{...motionProps} />
/> </AnimatePresence>
</LazyMotion> </LazyMotion>
</>
</AnimatePresence>
); );
})} })}
</> </>

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -1,7 +1,13 @@
import type {SelectSlots, SelectVariantProps, SlotsToClasses} from "@nextui-org/theme"; import type {SelectSlots, SelectVariantProps, SlotsToClasses} from "@nextui-org/theme";
import type {HiddenSelectProps} from "./hidden-select"; import type {HiddenSelectProps} from "./hidden-select";
import {DOMAttributes, HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
DOMAttributes,
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {select} from "@nextui-org/theme"; import {select} from "@nextui-org/theme";
import {ReactRef, useDOMRef, filterDOMProps} from "@nextui-org/react-utils"; import {ReactRef, useDOMRef, filterDOMProps} from "@nextui-org/react-utils";
import {useMemo, useCallback, useRef, Key, ReactNode, useEffect} from "react"; import {useMemo, useCallback, useRef, Key, ReactNode, useEffect} from "react";
@ -137,8 +143,12 @@ export type UseSelectProps<T> = Omit<Props<T>, keyof MultiSelectProps<T>> &
SelectVariantProps; SelectVariantProps;
export function useSelect<T extends object>(originalProps: UseSelectProps<T>) { export function useSelect<T extends object>(originalProps: UseSelectProps<T>) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, select.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, select.variantKeys);
const disableAnimation = originalProps.disableAnimation ?? false;
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const { const {
ref, ref,
@ -317,9 +327,10 @@ export function useSelect<T extends object>(originalProps: UseSelectProps<T>) {
...variantProps, ...variantProps,
isInvalid, isInvalid,
labelPlacement, labelPlacement,
disableAnimation,
className, className,
}), }),
[objectToDeps(variantProps), isInvalid, labelPlacement, className], [objectToDeps(variantProps), isInvalid, labelPlacement, disableAnimation, className],
); );
// scroll the listbox to the selected item // scroll the listbox to the selected item

View File

@ -36,10 +36,10 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"@nextui-org/theme": ">=2.1.0" "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0"
}, },
"dependencies": { "dependencies": {
"@nextui-org/system-rsc": "workspace:*",
"@nextui-org/shared-utils": "workspace:*", "@nextui-org/shared-utils": "workspace:*",
"@nextui-org/react-utils": "workspace:*" "@nextui-org/react-utils": "workspace:*"
}, },
@ -47,6 +47,7 @@
"@nextui-org/theme": "workspace:*", "@nextui-org/theme": "workspace:*",
"@nextui-org/card": "workspace:*", "@nextui-org/card": "workspace:*",
"@nextui-org/button": "workspace:*", "@nextui-org/button": "workspace:*",
"@nextui-org/system": "workspace:*",
"clean-package": "2.2.0", "clean-package": "2.2.0",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0" "react-dom": "^18.0.0"

View File

@ -1,4 +1,4 @@
import {forwardRef} from "@nextui-org/system-rsc"; import {forwardRef} from "@nextui-org/system";
import {UseSkeletonProps, useSkeleton} from "./use-skeleton"; import {UseSkeletonProps, useSkeleton} from "./use-skeleton";

View File

@ -1,10 +1,11 @@
import type {SkeletonVariantProps, SkeletonSlots, SlotsToClasses} from "@nextui-org/theme"; import type {SkeletonVariantProps, SkeletonSlots, SlotsToClasses} from "@nextui-org/theme";
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system-rsc"; import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import {mapPropsVariants} from "@nextui-org/system-rsc"; import {mapPropsVariants} from "@nextui-org/system";
import {skeleton} from "@nextui-org/theme"; import {skeleton} from "@nextui-org/theme";
import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
import {useMemo, Ref} from "react"; import {useMemo, Ref} from "react";
import {useProviderContext} from "@nextui-org/system";
interface Props extends HTMLNextUIProps<"div"> { interface Props extends HTMLNextUIProps<"div"> {
/** /**
@ -34,18 +35,24 @@ interface Props extends HTMLNextUIProps<"div"> {
export type UseSkeletonProps = Props & SkeletonVariantProps; export type UseSkeletonProps = Props & SkeletonVariantProps;
export function useSkeleton(originalProps: UseSkeletonProps) { export function useSkeleton(originalProps: UseSkeletonProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, skeleton.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, skeleton.variantKeys);
const {as, children, isLoaded = false, className, classNames, ...otherProps} = props; const {as, children, isLoaded = false, className, classNames, ...otherProps} = props;
const Component = as || "div"; const Component = as || "div";
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const slots = useMemo( const slots = useMemo(
() => () =>
skeleton({ skeleton({
...variantProps, ...variantProps,
disableAnimation,
}), }),
[objectToDeps(variantProps), children], [objectToDeps(variantProps), disableAnimation, children],
); );
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);

View File

@ -4,4 +4,5 @@ export default defineConfig({
clean: true, clean: true,
target: "es2019", target: "es2019",
format: ["cjs", "esm"], format: ["cjs", "esm"],
banner: {js: '"use client";'},
}); });

View File

@ -1,6 +1,12 @@
import type {SliderSlots, SliderVariantProps, SlotsToClasses} from "@nextui-org/theme"; import type {SliderSlots, SliderVariantProps, SlotsToClasses} from "@nextui-org/theme";
import {DOMAttributes, HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
DOMAttributes,
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {slider} from "@nextui-org/theme"; import {slider} from "@nextui-org/theme";
import {ReactRef, useDOMRef, filterDOMProps} from "@nextui-org/react-utils"; import {ReactRef, useDOMRef, filterDOMProps} from "@nextui-org/react-utils";
import {useSliderState} from "@react-stately/slider"; import {useSliderState} from "@react-stately/slider";
@ -133,6 +139,8 @@ export type UseSliderProps = Omit<Props, keyof ValueBase<SliderValue>> &
SliderVariantProps; SliderVariantProps;
export function useSlider(originalProps: UseSliderProps) { export function useSlider(originalProps: UseSliderProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, slider.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, slider.variantKeys);
const { const {
@ -167,6 +175,8 @@ export function useSlider(originalProps: UseSliderProps) {
const Component = as || "div"; const Component = as || "div";
const shouldFilterDOMProps = typeof Component === "string"; const shouldFilterDOMProps = typeof Component === "string";
const disableAnimation =
originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
const domRef = useDOMRef(ref); const domRef = useDOMRef(ref);
const trackRef = useRef<HTMLDivElement>(null); const trackRef = useRef<HTMLDivElement>(null);
@ -231,11 +241,12 @@ export function useSlider(originalProps: UseSliderProps) {
slider({ slider({
...variantProps, ...variantProps,
hasMarks, hasMarks,
disableAnimation,
hasSingleThumb, hasSingleThumb,
isVertical, isVertical,
className, className,
}), }),
[objectToDeps(variantProps), isVertical, hasSingleThumb, hasMarks, className], [objectToDeps(variantProps), isVertical, disableAnimation, hasSingleThumb, hasMarks, className],
); );
const [startOffset, endOffset] = [ const [startOffset, endOffset] = [

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -1,7 +1,12 @@
import type {SnippetVariantProps, SnippetSlots, SlotsToClasses} from "@nextui-org/theme"; import type {SnippetVariantProps, SnippetSlots, SlotsToClasses} from "@nextui-org/theme";
import {snippet} from "@nextui-org/theme"; import {snippet} from "@nextui-org/theme";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {useDOMRef, filterDOMProps} from "@nextui-org/react-utils"; import {useDOMRef, filterDOMProps} from "@nextui-org/react-utils";
import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
import {ReactRef} from "@nextui-org/react-utils"; import {ReactRef} from "@nextui-org/react-utils";
@ -116,6 +121,8 @@ export interface UseSnippetProps extends Omit<HTMLNextUIProps, "onCopy">, Snippe
} }
export function useSnippet(originalProps: UseSnippetProps) { export function useSnippet(originalProps: UseSnippetProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, snippet.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, snippet.variantKeys);
const { const {
@ -142,6 +149,8 @@ export function useSnippet(originalProps: UseSnippetProps) {
const Component = as || "div"; const Component = as || "div";
const shouldFilterDOMProps = typeof Component === "string"; const shouldFilterDOMProps = typeof Component === "string";
const disableAnimation =
originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
const tooltipProps: Partial<TooltipProps> = { const tooltipProps: Partial<TooltipProps> = {
offset: 15, offset: 15,
@ -167,8 +176,9 @@ export function useSnippet(originalProps: UseSnippetProps) {
() => () =>
snippet({ snippet({
...variantProps, ...variantProps,
disableAnimation,
}), }),
[objectToDeps(variantProps)], [objectToDeps(variantProps), disableAnimation],
); );
const symbolBefore = useMemo(() => { const symbolBefore = useMemo(() => {

View File

@ -3,7 +3,7 @@ import type {AriaSwitchProps} from "@react-aria/switch";
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system"; import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
import {ReactNode, Ref, useCallback, useId, useRef, useState} from "react"; import {ReactNode, Ref, useCallback, useId, useRef, useState} from "react";
import {mapPropsVariants} from "@nextui-org/system"; import {mapPropsVariants, useProviderContext} from "@nextui-org/system";
import {mergeRefs} from "@nextui-org/react-utils"; import {mergeRefs} from "@nextui-org/react-utils";
import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect"; import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect";
import {useHover, usePress} from "@react-aria/interactions"; import {useHover, usePress} from "@react-aria/interactions";
@ -76,6 +76,8 @@ export type UseSwitchProps = Omit<Props, "defaultChecked"> &
ToggleVariantProps; ToggleVariantProps;
export function useSwitch(originalProps: UseSwitchProps = {}) { export function useSwitch(originalProps: UseSwitchProps = {}) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, toggle.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, toggle.variantKeys);
const { const {
@ -104,6 +106,9 @@ export function useSwitch(originalProps: UseSwitchProps = {}) {
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const labelId = useId(); const labelId = useId();
const ariaSwitchProps = useMemo(() => { const ariaSwitchProps = useMemo(() => {
@ -188,8 +193,9 @@ export function useSwitch(originalProps: UseSwitchProps = {}) {
() => () =>
toggle({ toggle({
...variantProps, ...variantProps,
disableAnimation,
}), }),
[objectToDeps(variantProps)], [objectToDeps(variantProps), disableAnimation],
); );
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);

View File

@ -12,7 +12,12 @@ import type {TableCollection} from "@react-types/table";
import {ReactNode, Key, useCallback} from "react"; import {ReactNode, Key, useCallback} from "react";
import {useTableState} from "@react-stately/table"; import {useTableState} from "@react-stately/table";
import {AriaTableProps, useTable as useReactAriaTable} from "@react-aria/table"; import {AriaTableProps, useTable as useReactAriaTable} from "@react-aria/table";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {table} from "@nextui-org/theme"; import {table} from "@nextui-org/theme";
import {useDOMRef, filterDOMProps} from "@nextui-org/react-utils"; import {useDOMRef, filterDOMProps} from "@nextui-org/react-utils";
import {mergeProps} from "@react-aria/utils"; import {mergeProps} from "@react-aria/utils";
@ -140,6 +145,8 @@ export type ValuesType<T = object> = {
}; };
export function useTable<T extends object>(originalProps: UseTableProps<T>) { export function useTable<T extends object>(originalProps: UseTableProps<T>) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, table.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, table.variantKeys);
const { const {
@ -151,7 +158,7 @@ export function useTable<T extends object>(originalProps: UseTableProps<T>) {
classNames, classNames,
layoutNode, layoutNode,
removeWrapper = false, removeWrapper = false,
disableAnimation = false, disableAnimation = globalContext?.disableAnimation ?? false,
selectionMode = "none", selectionMode = "none",
topContentPlacement = "inside", topContentPlacement = "inside",
bottomContentPlacement = "inside", bottomContentPlacement = "inside",

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -1,6 +1,11 @@
import type {TabsVariantProps, SlotsToClasses, TabsSlots, TabsReturnType} from "@nextui-org/theme"; import type {TabsVariantProps, SlotsToClasses, TabsSlots, TabsReturnType} from "@nextui-org/theme";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {tabs} from "@nextui-org/theme"; import {tabs} from "@nextui-org/theme";
import {useDOMRef} from "@nextui-org/react-utils"; import {useDOMRef} from "@nextui-org/react-utils";
import {clsx, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, objectToDeps} from "@nextui-org/shared-utils";
@ -83,6 +88,8 @@ export type ValuesType<T = object> = {
}; };
export function useTabs<T extends object>(originalProps: UseTabsProps<T>) { export function useTabs<T extends object>(originalProps: UseTabsProps<T>) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, tabs.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, tabs.variantKeys);
const { const {
@ -104,6 +111,9 @@ export function useTabs<T extends object>(originalProps: UseTabsProps<T>) {
const domRef = useDOMRef(ref); const domRef = useDOMRef(ref);
const disableAnimation =
originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
const state = useTabListState<T>({ const state = useTabListState<T>({
children: children as CollectionChildren<T>, children: children as CollectionChildren<T>,
...otherProps, ...otherProps,
@ -115,9 +125,10 @@ export function useTabs<T extends object>(originalProps: UseTabsProps<T>) {
tabs({ tabs({
...variantProps, ...variantProps,
className, className,
disableAnimation,
...(isVertical ? {placement: "start"} : {}), ...(isVertical ? {placement: "start"} : {}),
}), }),
[objectToDeps(variantProps), className, isVertical], [objectToDeps(variantProps), className, disableAnimation, isVertical],
); );
const baseStyles = clsx(classNames?.base, className); const baseStyles = clsx(classNames?.base, className);
@ -128,20 +139,20 @@ export function useTabs<T extends object>(originalProps: UseTabsProps<T>) {
slots, slots,
classNames, classNames,
motionProps, motionProps,
disableAnimation,
listRef: domRef, listRef: domRef,
shouldSelectOnPressUp, shouldSelectOnPressUp,
disableCursorAnimation, disableCursorAnimation,
isDisabled: originalProps?.isDisabled, isDisabled: originalProps?.isDisabled,
disableAnimation: originalProps?.disableAnimation,
}), }),
[ [
state, state,
slots, slots,
domRef, domRef,
motionProps, motionProps,
disableAnimation,
disableCursorAnimation, disableCursorAnimation,
shouldSelectOnPressUp, shouldSelectOnPressUp,
originalProps?.disableAnimation,
originalProps?.isDisabled, originalProps?.isDisabled,
classNames, classNames,
], ],

View File

@ -36,7 +36,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0", "framer-motion": ">=10.17.0",
"@nextui-org/theme": ">=2.1.0", "@nextui-org/theme": ">=2.1.0",
"@nextui-org/system": ">=2.0.0" "@nextui-org/system": ">=2.0.0"
}, },

View File

@ -9,7 +9,12 @@ import {useTooltipTriggerState} from "@react-stately/tooltip";
import {mergeProps} from "@react-aria/utils"; import {mergeProps} from "@react-aria/utils";
import {useTooltip as useReactAriaTooltip, useTooltipTrigger} from "@react-aria/tooltip"; import {useTooltip as useReactAriaTooltip, useTooltipTrigger} from "@react-aria/tooltip";
import {useOverlayPosition, useOverlay, AriaOverlayProps} from "@react-aria/overlays"; import {useOverlayPosition, useOverlay, AriaOverlayProps} from "@react-aria/overlays";
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system"; import {
HTMLNextUIProps,
mapPropsVariants,
PropGetter,
useProviderContext,
} from "@nextui-org/system";
import {popover} from "@nextui-org/theme"; import {popover} from "@nextui-org/theme";
import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
import {ReactRef, mergeRefs} from "@nextui-org/react-utils"; import {ReactRef, mergeRefs} from "@nextui-org/react-utils";
@ -87,6 +92,7 @@ export type UseTooltipProps = Props &
PopoverVariantProps; PopoverVariantProps;
export function useTooltip(originalProps: UseTooltipProps) { export function useTooltip(originalProps: UseTooltipProps) {
const globalContext = useProviderContext();
const [props, variantProps] = mapPropsVariants(originalProps, popover.variantKeys); const [props, variantProps] = mapPropsVariants(originalProps, popover.variantKeys);
const { const {
@ -122,6 +128,9 @@ export function useTooltip(originalProps: UseTooltipProps) {
const Component = as || "div"; const Component = as || "div";
const disableAnimation =
originalProps?.disableAnimation ?? globalContext?.disableAnimation ?? false;
const state = useTooltipTriggerState({ const state = useTooltipTriggerState({
delay, delay,
closeDelay, closeDelay,
@ -203,11 +212,18 @@ export function useTooltip(originalProps: UseTooltipProps) {
() => () =>
popover({ popover({
...variantProps, ...variantProps,
disableAnimation,
radius: originalProps?.radius ?? "md", radius: originalProps?.radius ?? "md",
size: originalProps?.size ?? "md", size: originalProps?.size ?? "md",
shadow: originalProps?.shadow ?? "sm", shadow: originalProps?.shadow ?? "sm",
}), }),
[objectToDeps(variantProps), originalProps?.radius, originalProps?.size, originalProps?.shadow], [
objectToDeps(variantProps),
disableAnimation,
originalProps?.radius,
originalProps?.size,
originalProps?.shadow,
],
); );
const getTriggerProps = useCallback<PropGetter>( const getTriggerProps = useCallback<PropGetter>(
@ -269,7 +285,7 @@ export function useTooltip(originalProps: UseTooltipProps) {
showArrow, showArrow,
portalContainer, portalContainer,
placement: placementProp, placement: placementProp,
disableAnimation: originalProps?.disableAnimation, disableAnimation,
isDisabled, isDisabled,
motionProps, motionProps,
getTooltipContentProps, getTooltipContentProps,

View File

@ -104,7 +104,6 @@ const defaultProps = {
offset: 7, offset: 7,
defaultOpen: false, defaultOpen: false,
isDisabled: false, isDisabled: false,
disableAnimation: false,
content: "I am a tooltip", content: "I am a tooltip",
children: <Button>Hover me</Button>, children: <Button>Hover me</Button>,
}; };

View File

@ -89,7 +89,7 @@
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18", "react-dom": ">=18",
"framer-motion": ">=4.0.0" "framer-motion": ">=10.17.0"
}, },
"devDependencies": { "devDependencies": {
"react": "^18.0.0", "react": "^18.0.0",

View File

@ -35,12 +35,14 @@
}, },
"peerDependencies": { "peerDependencies": {
"react": ">=18", "react": ">=18",
"react-dom": ">=18" "react-dom": ">=18",
"framer-motion": ">=10.17.0"
}, },
"devDependencies": { "devDependencies": {
"clean-package": "2.2.0",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0" "react-dom": "^18.0.0",
"clean-package": "2.2.0",
"framer-motion": "^11.0.22"
}, },
"clean-package": "../../../clean-package.config.json", "clean-package": "../../../clean-package.config.json",
"tsup": { "tsup": {

View File

@ -4,6 +4,19 @@ import type {CalendarDate, Calendar} from "@internationalized/date";
import {createContext} from "@nextui-org/react-utils"; import {createContext} from "@nextui-org/react-utils";
export type ProviderContextProps = { export type ProviderContextProps = {
/**
* Whether to disable animations in the whole application.
*
* @default false
*/
disableAnimation?: boolean;
/**
* Whether to disable the ripple effect in the whole application.
* If `disableAnimation` is set to `true`, this prop will be ignored.
*
* @default false
*/
disableRipple?: boolean;
/** /**
* The default dates range that can be selected in the calendar. * The default dates range that can be selected in the calendar.
*/ */

View File

@ -6,6 +6,7 @@ import {RouterProvider} from "@react-aria/utils";
import {OverlayProvider} from "@react-aria/overlays"; import {OverlayProvider} from "@react-aria/overlays";
import {useMemo} from "react"; import {useMemo} from "react";
import {CalendarDate} from "@internationalized/date"; import {CalendarDate} from "@internationalized/date";
import {MotionGlobalConfig} from "framer-motion";
import {ProviderContext} from "./provider-context"; import {ProviderContext} from "./provider-context";
@ -13,6 +14,14 @@ export interface NextUIProviderProps
extends Omit<ModalProviderProps, "children">, extends Omit<ModalProviderProps, "children">,
ProviderContextProps { ProviderContextProps {
children: React.ReactNode; children: React.ReactNode;
/**
* Controls whether `framer-motion` animations are skipped within the application.
* This property is automatically enabled (`true`) when the `disableAnimation` prop is set to `true`,
* effectively skipping all `framer-motion` animations. To retain `framer-motion` animations while
* using the `disableAnimation` prop for other purposes, set this to `false`. However, note that
* animations in NextUI Components are still omitted if the `disableAnimation` prop is `true`.
*/
skipFramerMotionAnimations?: boolean;
/** /**
* The locale to apply to the children. * The locale to apply to the children.
* @default "en-US" * @default "en-US"
@ -28,6 +37,9 @@ export interface NextUIProviderProps
export const NextUIProvider: React.FC<NextUIProviderProps> = ({ export const NextUIProvider: React.FC<NextUIProviderProps> = ({
children, children,
navigate, navigate,
disableAnimation = false,
disableRipple = false,
skipFramerMotionAnimations = disableAnimation,
locale = "en-US", locale = "en-US",
defaultDates = { defaultDates = {
minDate: new CalendarDate(1900, 1, 1), minDate: new CalendarDate(1900, 1, 1),
@ -42,10 +54,24 @@ export const NextUIProvider: React.FC<NextUIProviderProps> = ({
contents = <RouterProvider navigate={navigate}>{contents}</RouterProvider>; contents = <RouterProvider navigate={navigate}>{contents}</RouterProvider>;
} }
const context = useMemo<ProviderContextProps>( const context = useMemo<ProviderContextProps>(() => {
() => ({createCalendar, defaultDates}), if (disableAnimation && skipFramerMotionAnimations) {
[createCalendar, defaultDates?.maxDate, defaultDates?.minDate], MotionGlobalConfig.skipAnimations = true;
); }
return {
createCalendar,
defaultDates,
disableAnimation,
disableRipple,
};
}, [
createCalendar,
defaultDates?.maxDate,
defaultDates?.minDate,
disableAnimation,
disableRipple,
]);
return ( return (
<ProviderContext value={context}> <ProviderContext value={context}>

View File

@ -119,7 +119,6 @@ const accordionItem = tv({
radius: "lg", radius: "lg",
isDisabled: false, isDisabled: false,
hideIndicator: false, hideIndicator: false,
disableAnimation: false,
disableIndicatorAnimation: false, disableIndicatorAnimation: false,
}, },
}); });

View File

@ -46,7 +46,6 @@ const autocomplete = tv({
}, },
}, },
defaultVariants: { defaultVariants: {
disableAnimation: false,
isClearable: true, isClearable: true,
disableSelectorIconRotation: false, disableSelectorIconRotation: false,
}, },

View File

@ -124,6 +124,13 @@ const avatar = tv({
base: "m-0 data-[hover=true]:translate-x-0", base: "m-0 data-[hover=true]:translate-x-0",
}, },
}, },
disableAnimation: {
true: {
base: "transition-none",
img: "transition-none",
},
false: {},
},
}, },
defaultVariants: { defaultVariants: {
size: "md", size: "md",

View File

@ -111,7 +111,6 @@ const badge = tv({
shape: "rectangle", shape: "rectangle",
placement: "top-right", placement: "top-right",
showOutline: true, showOutline: true,
disableAnimation: false,
isInvisible: false, isInvisible: false,
}, },
compoundVariants: [ compoundVariants: [

View File

@ -108,7 +108,6 @@ const breadcrumbItem = tv({
color: "foreground", color: "foreground",
underline: "hover", underline: "hover",
isDisabled: false, isDisabled: false,
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// isCurrent && color // isCurrent && color

View File

@ -37,6 +37,8 @@ const button = tv({
"subpixel-antialiased", "subpixel-antialiased",
"overflow-hidden", "overflow-hidden",
"tap-highlight-transparent", "tap-highlight-transparent",
"data-[pressed=true]:scale-[0.97]",
"origin-bottom",
// focus ring // focus ring
...dataFocusVisibleClasses, ...dataFocusVisibleClasses,
], ],
@ -85,8 +87,7 @@ const button = tv({
}, },
disableAnimation: { disableAnimation: {
true: "!transition-none", true: "!transition-none",
false: false: "transition-transform-colors-opacity motion-reduce:transition-none",
"data-[pressed=true]:scale-[0.97] transition-transform-colors-opacity motion-reduce:transition-none",
}, },
}, },
defaultVariants: { defaultVariants: {
@ -96,7 +97,6 @@ const button = tv({
fullWidth: false, fullWidth: false,
isDisabled: false, isDisabled: false,
isInGroup: false, isInGroup: false,
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// solid / color // solid / color

View File

@ -154,7 +154,6 @@ const calendar = tv({
showShadow: false, showShadow: false,
hideDisabledDates: false, hideDisabledDates: false,
showMonthAndYearPickers: false, showMonthAndYearPickers: false,
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// !isRange & colors --> Calendar // !isRange & colors --> Calendar

View File

@ -149,7 +149,6 @@ const card = tv({
compoundVariants: [ compoundVariants: [
{ {
isPressable: true, isPressable: true,
disableAnimation: false,
class: "data-[pressed=true]:scale-[0.97] tap-highlight-transparent", class: "data-[pressed=true]:scale-[0.97] tap-highlight-transparent",
}, },
], ],
@ -160,7 +159,6 @@ const card = tv({
isHoverable: false, isHoverable: false,
isPressable: false, isPressable: false,
isDisabled: false, isDisabled: false,
disableAnimation: false,
isFooterBlurred: false, isFooterBlurred: false,
}, },
}); });

View File

@ -189,7 +189,6 @@ const checkbox = tv({
size: "md", size: "md",
isDisabled: false, isDisabled: false,
lineThrough: false, lineThrough: false,
disableAnimation: false,
}, },
}); });
@ -235,7 +234,6 @@ const checkboxGroup = tv({
defaultVariants: { defaultVariants: {
isInvalid: false, isInvalid: false,
isRequired: false, isRequired: false,
disableAnimation: false,
}, },
}); });

View File

@ -90,7 +90,6 @@ const circularProgress = tv({
color: "primary", color: "primary",
size: "md", size: "md",
isDisabled: false, isDisabled: false,
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// disableAnimation && !isIndeterminate // disableAnimation && !isIndeterminate

View File

@ -218,7 +218,6 @@ const dateInput = tv({
fullWidth: true, fullWidth: true,
labelPlacement: "inside", labelPlacement: "inside",
isDisabled: false, isDisabled: false,
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// flat & color // flat & color

View File

@ -124,7 +124,6 @@ const dropdownItem = tv({
defaultVariants: { defaultVariants: {
variant: "solid", variant: "solid",
color: "default", color: "default",
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// solid / color // solid / color

View File

@ -71,11 +71,32 @@ const image = tv({
}, },
showSkeleton: { showSkeleton: {
true: { true: {
wrapper: ["group", "relative", "overflow-hidden", "bg-content3 dark:bg-content2"],
img: "opacity-0",
},
},
disableAnimation: {
true: {
img: "transition-none",
},
false: {
img: "transition-transform-opacity motion-reduce:transition-none !duration-300",
},
},
},
defaultVariants: {
radius: "lg",
shadow: "none",
isZoomed: false,
isBlurred: false,
showSkeleton: false,
},
compoundVariants: [
{
showSkeleton: true,
disableAnimation: false,
class: {
wrapper: [ wrapper: [
"group",
"relative",
"overflow-hidden",
"bg-content3 dark:bg-content2",
// before // before
"before:opacity-100", "before:opacity-100",
"before:absolute", "before:absolute",
@ -97,26 +118,9 @@ const image = tv({
"after:bg-content3", "after:bg-content3",
"dark:after:bg-content2", "dark:after:bg-content2",
], ],
img: "opacity-0",
}, },
}, },
disableAnimation: { ],
true: {
img: "transition-none",
},
false: {
img: "transition-transform-opacity motion-reduce:transition-none !duration-300",
},
},
},
defaultVariants: {
radius: "lg",
shadow: "none",
isZoomed: false,
isBlurred: false,
showSkeleton: false,
disableAnimation: false,
},
compoundSlots: [ compoundSlots: [
{ {
slots: ["wrapper", "img", "blurredImg", "zoomedWrapper"], slots: ["wrapper", "img", "blurredImg", "zoomedWrapper"],

View File

@ -245,7 +245,6 @@ const input = tv({
labelPlacement: "inside", labelPlacement: "inside",
isDisabled: false, isDisabled: false,
isMultiline: false, isMultiline: false,
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// flat & color // flat & color

View File

@ -101,7 +101,6 @@ const link = tv({
isBlock: false, isBlock: false,
underline: "none", underline: "none",
isDisabled: false, isDisabled: false,
disableAnimation: false,
}, },
}); });

View File

@ -148,7 +148,6 @@ const menuItem = tv({
defaultVariants: { defaultVariants: {
variant: "solid", variant: "solid",
color: "default", color: "default",
disableAnimation: false,
showDivider: false, showDivider: false,
}, },
compoundVariants: [ compoundVariants: [

View File

@ -32,16 +32,6 @@ const modal = tv({
"z-50", "z-50",
"overflow-x-auto", "overflow-x-auto",
"justify-center", "justify-center",
// mobile animation vars
"[--scale-enter:100%]",
"[--scale-exit:100%]",
"[--slide-enter:0px]",
"[--slide-exit:80px]",
// tablet/desktop animation vars
"sm:[--scale-enter:100%]",
"sm:[--scale-exit:103%]",
"sm:[--slide-enter:0px]",
"sm:[--slide-exit:0px]",
], ],
base: [ base: [
"flex", "flex",
@ -175,6 +165,22 @@ const modal = tv({
base: "my-16", base: "my-16",
}, },
}, },
disableAnimation: {
false: {
wrapper: [
// mobile animation vars
"[--scale-enter:100%]",
"[--scale-exit:100%]",
"[--slide-enter:0px]",
"[--slide-exit:80px]",
// tablet/desktop animation vars
"sm:[--scale-enter:100%]",
"sm:[--scale-exit:103%]",
"sm:[--slide-enter:0px]",
"sm:[--slide-exit:0px]",
],
},
},
}, },
defaultVariants: { defaultVariants: {
size: "md", size: "md",

View File

@ -154,7 +154,6 @@ const pagination = tv({
isCompact: false, isCompact: false,
isDisabled: false, isDisabled: false,
showShadow: false, showShadow: false,
disableAnimation: false,
disableCursorAnimation: false, disableCursorAnimation: false,
}, },
compoundVariants: [ compoundVariants: [

View File

@ -175,7 +175,6 @@ const popover = tv({
size: "md", size: "md",
shadow: "md", shadow: "md",
backdrop: "transparent", backdrop: "transparent",
disableAnimation: false,
triggerScaleOnOpen: true, triggerScaleOnOpen: true,
}, },
compoundVariants: [ compoundVariants: [

View File

@ -119,7 +119,6 @@ const progress = tv(
isStriped: false, isStriped: false,
isIndeterminate: false, isIndeterminate: false,
isDisabled: false, isDisabled: false,
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// disableAnimation && !isIndeterminate // disableAnimation && !isIndeterminate

View File

@ -141,7 +141,6 @@ const radio = tv({
size: "md", size: "md",
isDisabled: false, isDisabled: false,
isInvalid: false, isInvalid: false,
disableAnimation: false,
}, },
}); });
@ -187,7 +186,6 @@ const radioGroup = tv({
defaultVariants: { defaultVariants: {
isInvalid: false, isInvalid: false,
isRequired: false, isRequired: false,
disableAnimation: false,
}, },
}); });

View File

@ -208,7 +208,6 @@ const select = tv({
fullWidth: true, fullWidth: true,
isDisabled: false, isDisabled: false,
isMultiline: false, isMultiline: false,
disableAnimation: false,
disableSelectorIconRotation: false, disableSelectorIconRotation: false,
}, },
compoundVariants: [ compoundVariants: [

View File

@ -59,9 +59,7 @@ const skeleton = tv({
}, },
}, },
}, },
defaultVariants: { defaultVariants: {},
disableAnimation: false,
},
}); });
export type SkeletonVariantProps = VariantProps<typeof skeleton>; export type SkeletonVariantProps = VariantProps<typeof skeleton>;

View File

@ -418,7 +418,6 @@ const slider = tv({
hideThumb: false, hideThumb: false,
isDisabled: false, isDisabled: false,
disableThumbScale: false, disableThumbScale: false,
disableAnimation: false,
showOutline: false, showOutline: false,
}, },
}); });

View File

@ -100,7 +100,6 @@ const snippet = tv({
variant: "flat", variant: "flat",
size: "md", size: "md",
fullWidth: false, fullWidth: false,
disableAnimation: false,
}, },
compoundVariants: [ compoundVariants: [
// solid - shadow / color // solid - shadow / color

View File

@ -259,7 +259,6 @@ const table = tv({
hideHeader: false, hideHeader: false,
isStriped: false, isStriped: false,
fullWidth: true, fullWidth: true,
disableAnimation: false,
}, },
}); });

Some files were not shown because too many files have changed in this diff Show More