diff --git a/.changeset/pretty-parrots-guess.md b/.changeset/pretty-parrots-guess.md new file mode 100644 index 0000000000..444998fd5b --- /dev/null +++ b/.changeset/pretty-parrots-guess.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/system": patch +--- + +Add reducedMotion setting to Provider (#3395) diff --git a/apps/docs/content/docs/api-references/nextui-provider.mdx b/apps/docs/content/docs/api-references/nextui-provider.mdx index dcc6abb52f..530077ac4a 100644 --- a/apps/docs/content/docs/api-references/nextui-provider.mdx +++ b/apps/docs/content/docs/api-references/nextui-provider.mdx @@ -116,12 +116,12 @@ interface AppProviderProps { import {GregorianCalendar} from '@internationalized/date'; function createCalendar(identifier) { - switch (identifier) { - case 'gregory': - return new GregorianCalendar(); - default: - throw new Error(`Unsupported calendar ${identifier}`); - } + switch (identifier) { + case 'gregory': + return new GregorianCalendar(); + default: + throw new Error(`Unsupported calendar ${identifier}`); + } } ``` @@ -167,6 +167,15 @@ or mark the field as required or invalid via ARIA. - **Type**: `native | aria` - **Default**: `aria` +`reducedMotion` + +- **Description**: Controls the motion preferences for the entire application, allowing developers to respect user settings for reduced motion. +The available options are: + - `"user"`: Adapts to the user's device settings for reduced motion. + - `"always"`: Disables all animations. + - `"never"`: Keeps all animations active. +- **Type**: `"user" | "always" | "never"` +- **Default**: `"never"` --- ## Types diff --git a/packages/components/calendar/stories/calendar.stories.tsx b/packages/components/calendar/stories/calendar.stories.tsx index 9cd707b47e..cf8f410c76 100644 --- a/packages/components/calendar/stories/calendar.stories.tsx +++ b/packages/components/calendar/stories/calendar.stories.tsx @@ -13,6 +13,7 @@ import {I18nProvider, useLocale} from "@react-aria/i18n"; import {Button, ButtonGroup} from "@nextui-org/button"; import {Radio, RadioGroup} from "@nextui-org/radio"; import {cn} from "@nextui-org/theme"; +import {NextUIProvider} from "@nextui-org/system"; import {Calendar, CalendarProps, DateValue} from "../src"; @@ -38,6 +39,11 @@ export default { }, options: ["narrow", "short", "long"], }, + disableAnimation: { + control: { + type: "boolean", + }, + }, }, } as Meta; @@ -241,7 +247,6 @@ const CalendarWidthTemplate = (args: CalendarProps) => { return (
-

calendarWidth: 300

calendarWidth: 300

@@ -257,6 +262,31 @@ const CalendarWidthTemplate = (args: CalendarProps) => { ); }; +const ReducedMotionTemplate = (args: CalendarProps) => { + return ( +
+
+

reducedMotion: never

+ + + +
+
+

reducedMotion: always

+ + + +
+
+

reducedMotion: user

+ + + +
+
+ ); +}; + export const Default = { render: Template, args: { @@ -375,3 +405,10 @@ export const CalendarWidth = { ...defaultProps, }, }; + +export const ReducedMotion = { + render: ReducedMotionTemplate, + args: { + ...defaultProps, + }, +}; diff --git a/packages/core/system/src/provider.tsx b/packages/core/system/src/provider.tsx index 1c10249c7b..d30c8316c3 100644 --- a/packages/core/system/src/provider.tsx +++ b/packages/core/system/src/provider.tsx @@ -6,7 +6,7 @@ import {I18nProvider, I18nProviderProps} from "@react-aria/i18n"; import {RouterProvider} from "@react-aria/utils"; import {OverlayProvider} from "@react-aria/overlays"; import {useMemo} from "react"; -import {MotionGlobalConfig} from "framer-motion"; +import {MotionConfig, MotionGlobalConfig} from "framer-motion"; import {ProviderContext} from "./provider-context"; @@ -22,6 +22,12 @@ export interface NextUIProviderProps * animations in NextUI Components are still omitted if the `disableAnimation` prop is `true`. */ skipFramerMotionAnimations?: boolean; + /** + * Defines a new default transition for the entire tree. + * @default "never" + * See: https://www.framer.com/motion/motion-config/#props + */ + reducedMotion?: "user" | "always" | "never"; /** * The locale to apply to the children. * @default "en-US" @@ -45,10 +51,11 @@ export interface NextUIProviderProps export const NextUIProvider: React.FC = ({ children, navigate, + disableAnimation, useHref, - disableAnimation = false, disableRipple = false, skipFramerMotionAnimations = disableAnimation, + reducedMotion = "never", validationBehavior = "aria", locale = "en-US", // if minDate / maxDate are not specified in `defaultDates` @@ -91,7 +98,9 @@ export const NextUIProvider: React.FC = ({ return ( - {contents} + + {contents} + );