diff --git a/packages/@headlessui-react/CHANGELOG.md b/packages/@headlessui-react/CHANGELOG.md index fee91340dd..c8df987199 100644 --- a/packages/@headlessui-react/CHANGELOG.md +++ b/packages/@headlessui-react/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix infinite render-loop for `` and `` when `as={Fragment}` ([#2760](https://github.com/tailwindlabs/headlessui/pull/2760)) - Fix VoiceOver bug for `Listbox` component in Chrome ([#2824](https://github.com/tailwindlabs/headlessui/pull/2824)) - Fix outside click detection when component is mounted in the Shadow DOM ([#2866](https://github.com/tailwindlabs/headlessui/pull/2866)) +- Fix error when transition classes contain new lines ([#2871](https://github.com/tailwindlabs/headlessui/pull/2871)) ### Added diff --git a/packages/@headlessui-react/src/components/transitions/transition.test.tsx b/packages/@headlessui-react/src/components/transitions/transition.test.tsx index da017f1007..458b2fd0fb 100644 --- a/packages/@headlessui-react/src/components/transitions/transition.test.tsx +++ b/packages/@headlessui-react/src/components/transitions/transition.test.tsx @@ -1,6 +1,8 @@ import { act as _act, fireEvent, render } from '@testing-library/react' import React, { Fragment, useEffect, useLayoutEffect, useRef, useState } from 'react' +import { getByText } from '../../test-utils/accessibility-assertions' import { executeTimeline } from '../../test-utils/execute-timeline' +import { click } from '../../test-utils/interactions' import { createSnapshot } from '../../test-utils/snapshot' import { suppressConsoleLogs } from '../../test-utils/suppress-console-logs' import { Transition } from './transition' @@ -402,6 +404,57 @@ describe('Setup API', () => { }) describe('transition classes', () => { + it('should support new lines in class lists', async () => { + function Example() { + let [show, setShow] = useState(true) + + return ( +
+ + + + Children + +
+ ) + } + + let { container } = await act(() => render()) + + expect(container.firstChild).toMatchInlineSnapshot(` +
+ +
+ Children +
+
+ `) + + await click(getByText('toggle')) + + // TODO: This is not quite right + // The `foo1\nfoo2` should be gone + // I think this is a qurk of JSDOM + expect(container.firstChild).toMatchInlineSnapshot(` +
+ +
+ Children +
+
+ `) + }) + it('should be possible to passthrough the transition classes', () => { let { container } = render( type TransitionDirection = 'enter' | 'leave' | 'idle' +/** + * Split class lists by whitespace + * + * We can't check for just spaces as all whitespace characters are + * invalid in a class name, so we have to split on ANY whitespace. + */ function splitClasses(classes: string = '') { - return classes.split(' ').filter((className) => className.trim().length > 1) + return classes.split(/\s+/).filter((className) => className.length > 1) } interface TransitionContextValues { diff --git a/packages/@headlessui-vue/CHANGELOG.md b/packages/@headlessui-vue/CHANGELOG.md index 450703aab7..c72ba70c22 100644 --- a/packages/@headlessui-vue/CHANGELOG.md +++ b/packages/@headlessui-vue/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix missing `data-headlessui-state` attribute when `as="template"` ([#2787](https://github.com/tailwindlabs/headlessui/pull/2787)) - Fix VoiceOver bug for `Listbox` component in Chrome ([#2824](https://github.com/tailwindlabs/headlessui/pull/2824)) - Fix outside click detection when component is mounted in the Shadow DOM ([6846231](https://github.com/tailwindlabs/headlessui/commit/684623131b99d9e75dfc1c1f6d27244c334a95d9)) +- Fix error when transition classes contain new lines ([#2871](https://github.com/tailwindlabs/headlessui/pull/2871)) ### Added diff --git a/packages/@headlessui-vue/src/components/transitions/transition.ts b/packages/@headlessui-vue/src/components/transitions/transition.ts index b10eae07bc..b75d0f030d 100644 --- a/packages/@headlessui-vue/src/components/transitions/transition.ts +++ b/packages/@headlessui-vue/src/components/transitions/transition.ts @@ -29,8 +29,14 @@ import { Reason, transition } from './utils/transition' type ID = ReturnType +/** + * Split class lists by whitespace + * + * We can't check for just spaces as all whitespace characters are + * invalid in a class name, so we have to split on ANY whitespace. + */ function splitClasses(classes: string = '') { - return classes.split(' ').filter((className) => className.trim().length > 1) + return classes.split(/\s+/).filter((className) => className.length > 1) } interface TransitionContextValues {