Fix SSR support in Deno (#1671)
* check typeof document in addition to typeof window * remove unused import * Extract SSR check to a central spot * Fix CS * Update changelog Co-authored-by: Jordan Pittman <jordan@cryptica.me>
This commit is contained in:
@@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add `by` prop for `Listbox`, `Combobox` and `RadioGroup` ([#1482](https://github.com/tailwindlabs/headlessui/pull/1482))
|
||||
- Add `@headlessui/tailwindcss` plugin ([#1487](https://github.com/tailwindlabs/headlessui/pull/1487))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed SSR support on Deno ([#1671](https://github.com/tailwindlabs/headlessui/pull/1671))
|
||||
|
||||
## [1.6.6] - 2022-07-07
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -21,6 +21,7 @@ import { useServerHandoffComplete } from '../../hooks/use-server-handoff-complet
|
||||
import { optionalRef, useSyncRefs } from '../../hooks/use-sync-refs'
|
||||
import { useOwnerDocument } from '../../hooks/use-owner'
|
||||
import { microTask } from '../../utils/micro-task'
|
||||
import { isServer } from '../../utils/ssr'
|
||||
|
||||
function usePortalTarget(ref: MutableRefObject<HTMLElement | null>): HTMLElement | null {
|
||||
let forceInRoot = usePortalRoot()
|
||||
@@ -33,7 +34,7 @@ function usePortalTarget(ref: MutableRefObject<HTMLElement | null>): HTMLElement
|
||||
if (!forceInRoot && groupTarget !== null) return null
|
||||
|
||||
// No group context is used, let's create a default portal root
|
||||
if (typeof window === 'undefined') return null
|
||||
if (isServer) return null
|
||||
let existingRoot = ownerDocument?.getElementById('headlessui-portal-root')
|
||||
if (existingRoot) return existingRoot
|
||||
|
||||
@@ -81,7 +82,7 @@ let PortalRoot = forwardRefWithAs(function Portal<
|
||||
let ownerDocument = useOwnerDocument(internalPortalRootRef)
|
||||
let target = usePortalTarget(internalPortalRootRef)
|
||||
let [element] = useState<HTMLDivElement | null>(() =>
|
||||
typeof window === 'undefined' ? null : ownerDocument?.createElement('div') ?? null
|
||||
isServer ? null : ownerDocument?.createElement('div') ?? null
|
||||
)
|
||||
|
||||
let ready = useServerHandoffComplete()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useLayoutEffect, useEffect } from 'react'
|
||||
import { isServer } from '../utils/ssr'
|
||||
|
||||
export let useIsoMorphicEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect
|
||||
export let useIsoMorphicEffect = isServer ? useEffect : useLayoutEffect
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { MutableRefObject } from 'react'
|
||||
import { isServer } from './ssr'
|
||||
|
||||
export function getOwnerDocument<T extends Element | MutableRefObject<Element | null>>(
|
||||
element: T | null | undefined
|
||||
) {
|
||||
if (typeof window === 'undefined') return null
|
||||
if (isServer) return null
|
||||
if (element instanceof Node) return element.ownerDocument
|
||||
if (element?.hasOwnProperty('current')) {
|
||||
if (element.current instanceof Node) return element.current.ownerDocument
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const isServer = typeof window === 'undefined' || typeof document === 'undefined'
|
||||
@@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add `by` prop for `Listbox`, `Combobox` and `RadioGroup` ([#1482](https://github.com/tailwindlabs/headlessui/pull/1482))
|
||||
- Add `@headlessui/tailwindcss` plugin ([#1487](https://github.com/tailwindlabs/headlessui/pull/1487))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed SSR support on Deno ([#1671](https://github.com/tailwindlabs/headlessui/pull/1671))
|
||||
|
||||
## [1.6.7] - 2022-07-12
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ref, nextTick, onMounted } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
import { FocusTrap } from './focus-trap'
|
||||
import { assertActiveElement, getByText } from '../../test-utils/accessibility-assertions'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { watchEffect } from 'vue'
|
||||
import { isServer } from '../utils/ssr'
|
||||
|
||||
export function useEventListener<TType extends keyof WindowEventMap>(
|
||||
element: HTMLElement | Document | Window | EventTarget | null | undefined,
|
||||
@@ -6,7 +7,7 @@ export function useEventListener<TType extends keyof WindowEventMap>(
|
||||
listener: (event: WindowEventMap[TType]) => any,
|
||||
options?: boolean | AddEventListenerOptions
|
||||
) {
|
||||
if (typeof window === 'undefined') return
|
||||
if (isServer) return
|
||||
|
||||
watchEffect((onInvalidate) => {
|
||||
element = element ?? window
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { watchEffect } from 'vue'
|
||||
import { isServer } from '../utils/ssr'
|
||||
|
||||
export function useWindowEvent<TType extends keyof WindowEventMap>(
|
||||
type: TType,
|
||||
listener: (this: Window, ev: WindowEventMap[TType]) => any,
|
||||
options?: boolean | AddEventListenerOptions
|
||||
) {
|
||||
if (typeof window === 'undefined') return
|
||||
if (isServer) return
|
||||
|
||||
watchEffect((onInvalidate) => {
|
||||
window.addEventListener(type, listener, options)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Ref } from 'vue'
|
||||
import { dom } from './dom'
|
||||
import { isServer } from './ssr'
|
||||
|
||||
export function getOwnerDocument<T extends Element | Ref<Element | null>>(
|
||||
element: T | null | undefined
|
||||
) {
|
||||
if (typeof window === 'undefined') return null
|
||||
if (isServer) return null
|
||||
if (element instanceof Node) return element.ownerDocument
|
||||
if (element?.hasOwnProperty('value')) {
|
||||
let domElement = dom(element)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const isServer = typeof window === 'undefined' || typeof document === 'undefined'
|
||||
@@ -20,7 +20,9 @@ let people = [
|
||||
let locations = ['New York', 'London', 'Paris', 'Berlin']
|
||||
|
||||
export default function App() {
|
||||
let [result, setResult] = useState(() => (typeof window === 'undefined' ? [] : new FormData()))
|
||||
let [result, setResult] = useState(() =>
|
||||
typeof window === 'undefined' || typeof document === 'undefined' ? [] : new FormData()
|
||||
)
|
||||
let [notifications, setNotifications] = useState(false)
|
||||
let [apple, setApple] = useState(false)
|
||||
let [banana, setBanana] = useState(false)
|
||||
|
||||
Reference in New Issue
Block a user