Closed viveleroi closed 8 months ago
Add way to rerender when isCollapsed changes
The recommended way to do that is like so:
// Your component
const [isCollapsed, setIsCollapsed] = useState(false);
<Panel onCollapse={() => setIsCollapsed(true)} onExpand={() => setIsCollapsed(false)} />
I've written some non-trivial apps with the current API and found it to be pretty easy/efficient to work with (not overly cumbersome).
I dislike having to duplicate "state" like that - the value is already contained and controlled inside your logic, and I dislike having to duplicate those 3 extra things for each panel we need this logic for.
Maybe a solution could be adding a
useResizer
hook that returns theref
, and theisCollapsed
and related booleans as state, allowing anyone who needs to trigger a render to do so.
I understand why you'd prefer not to have the redundant state, but that's a subjective preference and the approach you describe (useResize
) is not one that I'm inclined to add to this library.
If you dislike the "extra state" you could always write a custom hook, or a wrapper/higher-order component, that exposes it in a different way. I think the primary thing that's missing from doing this in a "nice" way is an API to subscribe to changes in collapsed state. I would probably be willing to add that, which would enable you to do this:
const panelRef = useRef(null);
// You could wrap this into a custom hook so you didn't need to repeat it
const isCollapsed = useSyncExternalStore(
(change) => {
const panel = panelRef.current;
if (panel) {
return panel.listenForResize(change);
} else {
return () => {};
}
},
() => panelRef.current?.isCollapsed(),
() => panelRef.current?.isCollapsed(),
);
<Panel ref={panelRef} />
That's fine, that's what we do and I figured this would be your reply. Thanks
Would you find an API like listenForResize
to be particularly useful?
Would that be a way to cover onCollapse/onExpand with a single listener? I'd use that, although depending on how it fires during actual resizing it may get spammy, although we could debounce/etc.
Is there a discord or a more appropriate place to ask questions? Normally I'd use the discussions for some of these things. We've realized that because we use pixel values we need to specifically re-set the panel's size when it's collapsed and the user resizes the window.
There is no Discord. Most of my OSS projects are maintained by me alone, so I wouldn't really be able to keep up with a chat. I did just enable the discussion feature though.
Would that be a way to cover onCollapse/onExpand with a single listener?
Well, yes, essentially. It would provide a way to listen without mirroring state (if you wanted to write a custom hook for this). Otherwise you'd have to wrap with an HOC (or just copy/paste the mirrored state pattern I showed above).
One problem with the ref API approach is that when something changes value, a render is not triggered. That's the point of
ref
s obviously. Until we can support container queries in CSS we need to rely on theisCollapsed
api method to set a CSS class in a collapsible panel.In order to implement this we need to add a custom
isCollapsed
useState value/setter, set it usingonCollapse
andonExpand
, and read it in our css class logic.I dislike having to duplicate "state" like that - the value is already contained and controlled inside your logic, and I dislike having to duplicate those 3 extra things for each panel we need this logic for.
Maybe a solution could be adding a
useResizer
hook that returns theref
, and theisCollapsed
and related booleans as state, allowing anyone who needs to trigger a render to do so.