@@ -45591,16 +45591,23 @@ const writeInSignal = (signal, value, { history }) => {
4559145591// those writes: they are spelled into the url first (only the signal knows
4559245592// how "closed" reads there), and that url is written onto the entry the back
4559345593// lands on.
45594- const writeOpenedInSignal = (signal, opened, event) => {
45595- if (signal.peek() === opened) {
45594+ //
45595+ // What "open" is worth in the signal is `true`, or the popup's `value`
45596+ // when it has one: several popups then share one signal saying WHICH of them
45597+ // is open (`?seat=<gameId>` over a list of cards), and closed is the signal
45598+ // holding none of their values — `undefined`, which a state signal reads as
45599+ // its default.
45600+ const writeOpenedInSignal = (signal, opened, event, popupValue) => {
45601+ if (readOpened(signal.peek(), popupValue) === opened) {
4559645602 // The signal already says so, meaning this open/close IS what it asked
4559745603 // for: a back press that took the popup out of the url, the application
4559845604 // writing it. Nothing to write back — and nothing to go back to either,
4559945605 // since the navigation navBack would undo is the one that asked for this.
4560045606 return;
4560145607 }
45608+ const closedValue = popupValue === undefined ? false : undefined;
4560245609 if (opened) {
45603- signal.value = true;
45610+ signal.value = popupValue === undefined ? true : popupValue ;
4560445611 return;
4560545612 }
4560645613 if (
@@ -45615,11 +45622,17 @@ const writeOpenedInSignal = (signal, opened, event) => {
4561545622 navBack();
4561645623 return;
4561745624 }
45618- writeInSignal(signal, false , { history: "replace" });
45625+ writeInSignal(signal, closedValue , { history: "replace" });
4561945626 navBack({ landOn: { url: window.location.href } });
4562045627 return;
4562145628 }
45622- writeInSignal(signal, false, { history: "replace" });
45629+ writeInSignal(signal, closedValue, { history: "replace" });
45630+ };
45631+ const readOpened = (signalValue, popupValue) => {
45632+ if (popupValue === undefined) {
45633+ return signalValue;
45634+ }
45635+ return signalValue === popupValue;
4562345636};
4562445637
4562545638/**
@@ -45634,15 +45647,15 @@ const writeOpenedInSignal = (signal, opened, event) => {
4563445647 * `expandable.jsx` (open in flow rather than on a layer, same decision).
4563545648 *
4563645649 * @param {{ open: (e: Event, detail?: object) => void, requestClose: (e: Event, detail?: object) => void, opened: boolean }} openController
45637- * @param {{ id?: string, open?: boolean|"interaction", defaultOpen?: boolean|"interaction", signal?: import("@preact/signals").Signal<boolean> , navState?: boolean|string|{id?: string, type?: "push"|"replace"} }} props
45650+ * @param {{ id?: string, open?: boolean|"interaction", defaultOpen?: boolean|"interaction", signal?: import("@preact/signals").Signal, value?: any , navState?: boolean|string|{id?: string, type?: "push"|"replace"} }} props
4563845651 * @param {string} [name] What the dev warnings call the thing being opened.
4563945652 */
4564045653const useOpenPropsEffectOnOpenController = (
4564145654 openController,
4564245655 props,
4564345656 name = "popup",
4564445657) => {
45645- const { signal, defaultOpen, navState } = props;
45658+ const { signal, value, defaultOpen, navState } = props;
4564645659 const { id: navStateId, type: navStateType } = resolveNavStateProp(
4564745660 navState,
4564845661 props.id,
@@ -45672,7 +45685,7 @@ const useOpenPropsEffectOnOpenController = (
4567245685 const open = navStateId
4567345686 ? Boolean(navStateValue)
4567445687 : signal
45675- ? signal.value
45688+ ? readOpened( signal.value, value)
4567645689 : props.open;
4567745690 // Assigned on every render, like openEffect, so it always closes over the
4567845691 // latest prop: a popup that opens or closes on its own (Escape, backdrop, a
@@ -45692,7 +45705,7 @@ const useOpenPropsEffectOnOpenController = (
4569245705 }
4569345706 }
4569445707 if (signal) {
45695- writeOpenedInSignal(signal, opened, event);
45708+ writeOpenedInSignal(signal, opened, event, value );
4569645709 }
4569745710 }
4569845711 : null;
@@ -45750,9 +45763,16 @@ const useOpenPropsEffectOnOpenController = (
4575045763 // then stays where it was, and whoever holds the open state is told so —
4575145764 // otherwise it would keep saying "closed" about a popup still open.
4575245765 // Written over rather than stacked on: a refusal corrects the state that
45753- // asked, it is not a place one came from.
45754- if (signal) {
45755- writeInSignal(signal, openController.opened, { history: "replace" });
45766+ // asked, it is not a place one came from. Only on a refusal: an accepted
45767+ // request already reads in the signal, and with a `value` what the
45768+ // signal holds may be another popup's, which the write would erase.
45769+ if (signal && openController.opened !== open) {
45770+ const opened = openController.opened;
45771+ writeInSignal(
45772+ signal,
45773+ value === undefined ? opened : opened ? value : undefined,
45774+ { history: "replace" },
45775+ );
4575645776 }
4575745777 if (navStateId && openController.opened) {
4575845778 enterNavState();
@@ -46650,7 +46670,8 @@ const useExpandableContext = partName => {
4665046670 * ui?: import("ignore:preact").ComponentChildren | ((state: { open: boolean }) => import("ignore:preact").ComponentChildren),
4665146671 * open?: boolean,
4665246672 * defaultOpen?: boolean,
46653- * signal?: import("@preact/signals").Signal<boolean>,
46673+ * signal?: import("@preact/signals").Signal,
46674+ * value?: any,
4665446675 * navState?: boolean | string | { id?: string, type?: "push" | "replace" },
4665546676 * onClose?: (event: Event) => void,
4665646677 * onToggle?: (event: Event) => void,
@@ -46679,6 +46700,10 @@ const useExpandableContext = partName => {
4667946700 * @param defaultOpen - Uncontrolled, mount-only initial state.
4668046701 * @param signal - Two-way binding: the expandable follows the signal and
4668146702 * writes back into it whenever it toggles on its own. Excludes `open`.
46703+ * @param value - What `signal` holds while THIS expandable is open, for
46704+ * several sharing one signal that says which is open (an accordion): open
46705+ * while `signal.value` is this value, closed otherwise; opening writes it,
46706+ * closing writes `undefined`. Without it the signal holds a boolean.
4668246707 * @param navState - Keeps the open state in the history entry, so a screen
4668346708 * left and come back to finds its sections as they were: `true` uses the
4668446709 * expandable's own `id`, a string names the key, `{ id, type }` chooses
@@ -46739,6 +46764,7 @@ const Expandable = props => {
4673946764 open,
4674046765 defaultOpen,
4674146766 signal,
46767+ value,
4674246768 navState,
4674346769 onClose,
4674446770 action,
@@ -58619,6 +58645,11 @@ const css$E = /* css */`
5861958645 * Excludes `open`; `onOpen`/`onClose` still fire. A signal holding `true` at
5862058646 * mount behaves like `defaultOpen`: the dialog was already open, no entrance
5862158647 * plays.
58648+ * @param {any} [props.value] - What `signal` holds while THIS dialog is
58649+ * open, for several of them sharing one signal that says which is open
58650+ * (`?seat=<gameId>` over a list of cards): open while `signal.value` is this
58651+ * value, closed otherwise; opening writes it, closing writes `undefined`
58652+ * (a state signal's default). Without it the signal holds a boolean.
5862258653 * @param {boolean|"interaction"} [props.defaultOpen] - Uncontrolled, mount-only
5862358654 * initial open state. `true` plays no entrance animation: the dialog was
5862458655 * already open when the page appeared, and nothing was ever shown as "closed"
@@ -58715,6 +58746,7 @@ const UncontrolledDialog = props => {
5871558746 ...props,
5871658747 open: undefined,
5871758748 signal: undefined,
58749+ value: undefined,
5871858750 defaultOpen: undefined,
5871958751 navState: undefined,
5872058752 onClose: undefined,
@@ -60221,6 +60253,11 @@ const css$D = /* css */`
6022160253 * put it. Excludes `open`; `onOpen`/`onClose` still fire. A signal holding
6022260254 * `true` at mount behaves like `defaultOpen`: the popover was already open,
6022360255 * no entrance plays.
60256+ * @param {any} [props.value] - What `signal` holds while THIS popover is
60257+ * open, for several of them sharing one signal that says which is open
60258+ * (`?seat=<gameId>` over a list of cards): open while `signal.value` is this
60259+ * value, closed otherwise; opening writes it, closing writes `undefined`
60260+ * (a state signal's default). Without it the signal holds a boolean.
6022460261 * @param {boolean|"interaction"} [props.defaultOpen] - Uncontrolled, mount-only
6022560262 * initial open state. `true` plays no entrance animation: the popover was
6022660263 * already open when the page appeared, and nothing was ever shown as "closed"
@@ -60315,6 +60352,7 @@ const UncontrolledPopover = props => {
6031560352 ...props,
6031660353 open: undefined,
6031760354 signal: undefined,
60355+ value: undefined,
6031860356 defaultOpen: undefined,
6031960357 navState: undefined,
6032060358 onClose: undefined,
@@ -83298,6 +83336,9 @@ const css = /* css */`.navi_side_panel {
8329883336 * own (Escape, swipe, a --navi-close command) — one binding to both drive
8329983337 * the panel and know where it is. Forwarded as-is to `Popup`; excludes
8330083338 * `open` (see `Dialog`/`Popover`'s own `signal`).
83339+ * @param {any} [props.value] - What `signal` holds while this panel is
83340+ * open, for several panels sharing one signal that says which is open.
83341+ * Forwarded as-is to `Popup` (see `Dialog`/`Popover`'s own `value`).
8330183342 * @param {boolean} [props.defaultOpen] - Uncontrolled, mount-only initial
8330283343 * open state, forwarded as-is to `Popup`. Neither this nor `open` is
8330383344 * required at all for a purely command-driven panel (an `id` plus a
@@ -83385,6 +83426,7 @@ const css = /* css */`.navi_side_panel {
8338583426const SidePanel = ({
8338683427 open,
8338783428 signal,
83429+ value,
8338883430 defaultOpen,
8338983431 onClose,
8339083432 children,
@@ -83414,6 +83456,7 @@ const SidePanel = ({
8341483456 open
8341583457 }),
8341683458 signal: signal,
83459+ value: value,
8341783460 defaultOpen: defaultOpen,
8341883461 onClose: onClose,
8341983462 layer: layer,
0 commit comments