Open MrOxMasTer opened 1 month ago
Quite a strange feature request. Why do you want to inert content? You should be able to pass any attribute following the following pattern
<FocusLock lockProps={{inert: isOpen ? undefined : ''}} />
Note that in React (and preact) implementation inert
is not a boolean prop.
Quite a strange feature request. Why do you want to inert content? You should be able to pass any attribute following the following pattern
The problem is that you don't always need to mount/unmount a component. For example a menu component implemented with html/CSS. Especially in server/client combination in next.js
I just wanted to have a flag like: disabledAddInert
, but your option is not bad either.
The prop disabled
has functionality built in and it works the way I need it to when js is disabled/enabled.
But to do it this way is quite inconvenient and looks unpleasant:
export const Menu = () => {
const [isOpened, setIsOpened] = useState<boolean | null>(null);
useLayoutEffect(() => setIsOpened(false), []);
...
return (
<>
...
<FocusLock
lockProps={{ inert: isOpened === null ? false : !isOpened }}
disabled={!isOpened}
>
...
</FocusLock>
</aside>
</>
}
The thing is that if I set the same condition as for disabled, namely !isOpened
, then with the default false/null/undefined, AND with js disabled, it will treat it as true
. So when I disable js, it becomes inert=true
.
This doesn't happen with disabled
To solve this problem, I need another type to compare it with, like null
and if js is on the client, then use useEffect/useLayoutEffect
and write this horror:
useLayoutEffect(() => setIsOpened(false), []);
I don't know how FocusLock works under the hood, but it would be handy if I didn't have to write a hook every time.
using useLayoutEffect
seems to be fair solution for it. Not sure how else it could be.
Frankly this functionality should be build somewhere before or after FocusLock as it sounds a little unrelated. Sorry, I still cannot understand the usecase.
Frankly this functionality should be build somewhere before or after FocusLock as it sounds a little unrelated. Sorry, I still cannot understand the usecase.
I want js to be enabled:
disabled = !isOpened
inert = true
- when the menu is closed, that is isOpened = false
(in fact the same !isOpened
)With js: FocusLock turned off:
inert = false
- because there's no way I can control it since the js is not there
!! If I have !isOpened
here, then any value in the absence of: undefined/null/false
, will take true
and then I will have this field inert always.disabled = true
(or I don't know what happens to FocusLock
when the js is disabled)I just want inert
to depend on disabled
, as there is a built-in functionality for that, I don't see the point of writing an extra useLayoutEffect
.
and whatever you have to invent with these types null / false
.
You are missing the key point here - the gap between "no js" and "js". Think "hydration"
//-- some file
export const HydrationContext = createContext(false);
export const isHydrated = () => useContext(HydrationContext);
//-- nextjs layout
"use client";
export const Layout = ({children}) => {
const [hydrated,setHydrated] = useState(false);
useEffect(() => setHydrated(true), []);
return <HydrationContext value={hydrated}>{children}</HydrationContext>
}
// your code
<FocusLock
lockProps={{ inert: !isOpened && isHydrated() ? '' : undefined}}
disabled={!isOpened}
>
That's it. This is not your particular component to handle this moment, nor FocusLock's. Dont forget about main principles and you were right not liking useLayoutEffect
in the incorrect place.
add for
FocusLock
itself when disabled, be able to make all components inert. I can't pass this attribute. But I can for thediv
below it.I'm asking because maybe there is already a similar functionality, but I don't see it.