Skip to content

Commit

Permalink
Fix error when transition classes contain new lines (#2871)
Browse files Browse the repository at this point in the history
* fix DOMException when remove class with '\n' character in react 'transition' component

* Split classes on all whitespace

* Revert "fix DOMException when remove class with '\n' character in react 'transition' component"

This reverts commit 76e8354.

* fix typo

* Add test

* Fix CS

* Update changelog

---------

Co-authored-by: Jordan Pittman <[email protected]>
  • Loading branch information
KingManiya and thecrypticace authored Dec 12, 2023
1 parent c25e2e6 commit c24ba86
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/@headlessui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix infinite render-loop for `<Disclosure.Panel>` and `<Popover.Panel>` 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

Expand Down
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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 (
<div>
<button onClick={() => setShow((v) => !v)}>toggle</button>

<Transition show={show} as="div" className={`foo1\nfoo2`} enter="enter" leave="leave">
Children
</Transition>
</div>
)
}

let { container } = await act(() => render(<Example />))

expect(container.firstChild).toMatchInlineSnapshot(`
<div>
<button>
toggle
</button>
<div
class="foo1
foo2"
>
Children
</div>
</div>
`)

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(`
<div>
<button>
toggle
</button>
<div
class="foo1
foo2 foo1 foo2 leave"
>
Children
</div>
</div>
`)
})

it('should be possible to passthrough the transition classes', () => {
let { container } = render(
<Transition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,14 @@ type ContainerElement = MutableRefObject<HTMLElement | null>

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 {
Expand Down
1 change: 1 addition & 0 deletions packages/@headlessui-vue/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ import { Reason, transition } from './utils/transition'

type ID = ReturnType<typeof useId>

/**
* 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 {
Expand Down

2 comments on commit c24ba86

@vercel
Copy link

@vercel vercel bot commented on c24ba86 Dec 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

headlessui-vue – ./packages/playground-vue

headlessui-vue.vercel.app
headlessui-vue-tailwindlabs.vercel.app
headlessui-vue-git-main-tailwindlabs.vercel.app

@vercel
Copy link

@vercel vercel bot commented on c24ba86 Dec 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

headlessui-react – ./packages/playground-react

headlessui-react-tailwindlabs.vercel.app
headlessui-react-git-main-tailwindlabs.vercel.app
headlessui-react.vercel.app

Please sign in to comment.