@adea-ai/ui 0.123.0 → 0.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/NOTICE +18 -0
- package/dist/components/layout/split-layout/resize-controller-core-retry.d.ts +13 -0
- package/dist/components/layout/split-layout/resize-controller-core-retry.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-core-retry.js +63 -0
- package/dist/components/layout/split-layout/resize-controller-core-retry.js.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-core.d.ts +13 -0
- package/dist/components/layout/split-layout/resize-controller-core.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-core.js +63 -0
- package/dist/components/layout/split-layout/resize-controller-core.js.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-retry-2.d.ts +3 -0
- package/dist/components/layout/split-layout/resize-controller-retry-2.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-retry-2.js +2 -0
- package/dist/components/layout/split-layout/resize-controller-retry.d.ts +2 -0
- package/dist/components/layout/split-layout/resize-controller-retry.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-retry.js +2 -0
- package/dist/components/layout/split-layout/resize-controller.d.ts +2 -0
- package/dist/components/layout/split-layout/resize-controller.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller.js +2 -0
- package/dist/components/layout/split-layout/split-layout.d.ts.map +1 -1
- package/dist/components/layout/split-layout/split-layout.js +171 -60
- package/dist/components/layout/split-layout/split-layout.js.map +1 -1
- package/dist/components/theme/appearance-panel.js +1 -1
- package/dist/components/theme/index.d.ts +1 -1
- package/dist/components/theme/index.d.ts.map +1 -1
- package/dist/components/theme/index.js +5 -2
- package/dist/components/theme/theme-context.d.ts +13 -0
- package/dist/components/theme/theme-context.d.ts.map +1 -0
- package/dist/components/theme/theme-context.js +41 -0
- package/dist/components/theme/theme-context.js.map +1 -0
- package/dist/components/theme/theme-document.d.ts +76 -0
- package/dist/components/theme/theme-document.d.ts.map +1 -0
- package/dist/components/theme/theme-document.js +93 -0
- package/dist/components/theme/theme-document.js.map +1 -0
- package/dist/components/theme/theme-persistence.d.ts +50 -0
- package/dist/components/theme/theme-persistence.d.ts.map +1 -0
- package/dist/components/theme/theme-persistence.js +86 -0
- package/dist/components/theme/theme-persistence.js.map +1 -0
- package/dist/components/theme/theme-provider.d.ts +43 -75
- package/dist/components/theme/theme-provider.d.ts.map +1 -1
- package/dist/components/theme/theme-provider.js +50 -116
- package/dist/components/theme/theme-provider.js.map +1 -1
- package/dist/components/theme/theme-state.d.ts +142 -0
- package/dist/components/theme/theme-state.d.ts.map +1 -0
- package/dist/components/theme/theme-state.js +104 -0
- package/dist/components/theme/theme-state.js.map +1 -0
- package/dist/components/theme/theme-toggle.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/lib/appearance-font-settings.d.ts +1 -1
- package/dist/lib/appearance-font-settings.d.ts.map +1 -1
- package/dist/lib/appearance-font-settings.js.map +1 -1
- package/dist/lib/themes.d.ts +48 -0
- package/dist/lib/themes.d.ts.map +1 -1
- package/dist/lib/themes.js +150 -36
- package/dist/lib/themes.js.map +1 -1
- package/dist/r/registry.json +46 -0
- package/dist/r/split-layout.json +26 -0
- package/dist/r/src/components/layout/split-layout/resize-controller-core-retry.tsx +66 -0
- package/dist/r/src/components/layout/split-layout/resize-controller-core.tsx +66 -0
- package/dist/r/src/components/layout/split-layout/resize-controller-retry-2.tsx +2 -0
- package/dist/r/src/components/layout/split-layout/resize-controller-retry.tsx +1 -0
- package/dist/r/src/components/layout/split-layout/resize-controller.tsx +1 -0
- package/dist/r/src/components/layout/split-layout/split-layout.tsx +197 -49
- package/dist/r/src/components/theme/index.ts +3 -0
- package/dist/r/src/components/theme/theme-context.ts +43 -0
- package/dist/r/src/components/theme/theme-document.ts +168 -0
- package/dist/r/src/components/theme/theme-persistence.ts +140 -0
- package/dist/r/src/components/theme/theme-provider.tsx +126 -253
- package/dist/r/src/components/theme/theme-state.ts +225 -0
- package/dist/r/src/lib/appearance-font-settings.ts +1 -1
- package/dist/r/src/lib/themes.ts +181 -40
- package/dist/r/theming.json +20 -0
- package/package.json +1 -1
- package/registry.json +46 -0
- package/src/components/layout/split-layout/resize-controller-core-retry.tsx +66 -0
- package/src/components/layout/split-layout/resize-controller-core.tsx +66 -0
- package/src/components/layout/split-layout/resize-controller-retry-2.tsx +2 -0
- package/src/components/layout/split-layout/resize-controller-retry.tsx +1 -0
- package/src/components/layout/split-layout/resize-controller.tsx +1 -0
- package/src/components/layout/split-layout/split-layout.tsx +197 -49
- package/src/components/theme/index.ts +3 -0
- package/src/components/theme/theme-context.ts +43 -0
- package/src/components/theme/theme-document.ts +168 -0
- package/src/components/theme/theme-persistence.ts +140 -0
- package/src/components/theme/theme-provider.tsx +126 -253
- package/src/components/theme/theme-state.ts +225 -0
- package/src/index.ts +3 -0
- package/src/lib/appearance-font-settings.ts +1 -1
- package/src/lib/themes.ts +181 -40
package/dist/NOTICE
CHANGED
|
@@ -300,6 +300,24 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
300
300
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
301
301
|
SOFTWARE.
|
|
302
302
|
|
|
303
|
+
## Theme resolution fallback translated from Zeron
|
|
304
|
+
|
|
305
|
+
`resolveVariant` in `packages/ui/src/lib/themes.ts` translates the fallback order
|
|
306
|
+
of Zeron's `ThemeRegistry::resolve` (https://github.com/zeronsh/zeron), as Adea's
|
|
307
|
+
accepted port of it in `packages/ui/src/components/appearance.ts` expresses it:
|
|
308
|
+
an id the registry does not hold resolves to the default variant of the same
|
|
309
|
+
appearance, then to any variant of that appearance, and never to a variant of the
|
|
310
|
+
other one. The provider's use of it, which leaves the stored id untouched, is the
|
|
311
|
+
Adea behaviour that port retains.
|
|
312
|
+
|
|
313
|
+
Copyright (c) 2026 Wing
|
|
314
|
+
Licensed under the MIT License.
|
|
315
|
+
|
|
316
|
+
Zeron's MIT notice, reproduced in full under "Appearance editor translated from
|
|
317
|
+
Zeron" above, applies to the translated portion. The ThemeProvider's preview,
|
|
318
|
+
persistence and document-application seams are written against Adea's provider
|
|
319
|
+
contract and introduce no further upstream source.
|
|
320
|
+
|
|
303
321
|
## Strict binary layout extracted from the accepted Adea donor port
|
|
304
322
|
|
|
305
323
|
`packages/ui/src/components/layout/split-layout/model.ts` is extracted from
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Accessor, type JSX } from 'solid-js';
|
|
2
|
+
import { type SplitLayoutBranch, type SplitLayoutLeaf } from './model';
|
|
3
|
+
export type SplitLayoutResizeControllerProps<L extends SplitLayoutLeaf> = {
|
|
4
|
+
branch: Accessor<SplitLayoutBranch<L>>;
|
|
5
|
+
rect: Accessor<JSX.CSSProperties>;
|
|
6
|
+
domId: (id: string) => string;
|
|
7
|
+
root: () => HTMLDivElement | undefined;
|
|
8
|
+
labelForSeparator?: (branch: SplitLayoutBranch<L>) => string;
|
|
9
|
+
onResize: (splitId: string, ratio: number) => void;
|
|
10
|
+
};
|
|
11
|
+
/** Corvu stays behind the first real split while the pane owners remain mounted. */
|
|
12
|
+
export default function SplitLayoutResizeController<L extends SplitLayoutLeaf>(props: SplitLayoutResizeControllerProps<L>): JSX.Element;
|
|
13
|
+
//# sourceMappingURL=resize-controller-core-retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-controller-core-retry.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/resize-controller-core-retry.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,gCAAgC,CAAC,CAAC,SAAS,eAAe,IAAI;IACxE,MAAM,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IACjC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAA;IAC7B,IAAI,EAAE,MAAM,cAAc,GAAG,SAAS,CAAA;IACtC,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;IAC5D,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACnD,CAAA;AAED,oFAAoF;AACpF,MAAM,CAAC,OAAO,UAAU,2BAA2B,CAAC,CAAC,SAAS,eAAe,EAC3E,KAAK,EAAE,gCAAgC,CAAC,CAAC,CAAC,eA4C3C"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, listLeaves } from "./tree.js";
|
|
2
|
+
import { createComponent } from "solid-js/web";
|
|
3
|
+
import "solid-js";
|
|
4
|
+
import Resizable from "@corvu/resizable";
|
|
5
|
+
//#region src/components/layout/split-layout/resize-controller-core-retry.tsx
|
|
6
|
+
/** Corvu stays behind the first real split while the pane owners remain mounted. */
|
|
7
|
+
function SplitLayoutResizeController(props) {
|
|
8
|
+
const id = () => props.branch().id;
|
|
9
|
+
return createComponent(Resizable, {
|
|
10
|
+
get orientation() {
|
|
11
|
+
return props.branch().direction === "row" ? "horizontal" : "vertical";
|
|
12
|
+
},
|
|
13
|
+
get sizes() {
|
|
14
|
+
return [props.branch().ratio, 1 - props.branch().ratio];
|
|
15
|
+
},
|
|
16
|
+
keyboardDelta: .05,
|
|
17
|
+
onSizesChange: (sizes) => {
|
|
18
|
+
const root = props.root();
|
|
19
|
+
if (!root?.isConnected || root.getClientRects().length === 0) return;
|
|
20
|
+
if (sizes.length !== 2 || sizes.some((size) => !Number.isFinite(size)) || Math.abs(sizes[0] + sizes[1] - 1) > 1e-6) return;
|
|
21
|
+
if (sizes[0] !== void 0 && Math.abs(sizes[0] - props.branch().ratio) > 1e-6) props.onResize(id(), sizes[0]);
|
|
22
|
+
},
|
|
23
|
+
get style() {
|
|
24
|
+
return props.rect();
|
|
25
|
+
},
|
|
26
|
+
"class": "pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col",
|
|
27
|
+
get children() {
|
|
28
|
+
return [
|
|
29
|
+
createComponent(Resizable.Panel, {
|
|
30
|
+
minSize: MIN_SPLIT_RATIO,
|
|
31
|
+
maxSize: MAX_SPLIT_RATIO,
|
|
32
|
+
"aria-hidden": "true"
|
|
33
|
+
}),
|
|
34
|
+
createComponent(Resizable.Handle, {
|
|
35
|
+
get ["aria-label"]() {
|
|
36
|
+
return props.labelForSeparator?.(props.branch()) ?? (props.branch().direction === "row" ? "Resize pane columns" : "Resize pane rows");
|
|
37
|
+
},
|
|
38
|
+
get ["aria-orientation"]() {
|
|
39
|
+
return props.branch().direction === "row" ? "vertical" : "horizontal";
|
|
40
|
+
},
|
|
41
|
+
get ["aria-controls"]() {
|
|
42
|
+
return listLeaves(props.branch()).map((leaf) => props.domId(leaf.id)).join(" ");
|
|
43
|
+
},
|
|
44
|
+
"aria-valuemin": 10,
|
|
45
|
+
"aria-valuemax": 90,
|
|
46
|
+
get ["aria-valuenow"]() {
|
|
47
|
+
return Math.round(props.branch().ratio * 100);
|
|
48
|
+
},
|
|
49
|
+
"class": "pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full"
|
|
50
|
+
}),
|
|
51
|
+
createComponent(Resizable.Panel, {
|
|
52
|
+
minSize: MIN_SPLIT_RATIO,
|
|
53
|
+
maxSize: MAX_SPLIT_RATIO,
|
|
54
|
+
"aria-hidden": "true"
|
|
55
|
+
})
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { SplitLayoutResizeController as default };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=resize-controller-core-retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-controller-core-retry.js","names":["Resizable","Accessor","JSX","listLeaves","MIN_SPLIT_RATIO","MAX_SPLIT_RATIO","SplitLayoutBranch","SplitLayoutLeaf","SplitLayoutResizeControllerProps","branch","L","rect","CSSProperties","domId","id","root","HTMLDivElement","labelForSeparator","onResize","splitId","ratio","SplitLayoutResizeController","props","_$createComponent","orientation","direction","sizes","keyboardDelta","onSizesChange","isConnected","getClientRects","length","some","size","Number","isFinite","Math","abs","undefined","style","children","Panel","minSize","maxSize","Handle","aria-label","aria-orientation","aria-controls","map","leaf","join","aria-valuenow","round","_$createComponent"],"sources":["../../../../src/components/layout/split-layout/resize-controller-core-retry.tsx"],"sourcesContent":["import Resizable from '@corvu/resizable'\nimport { type Accessor, type JSX } from 'solid-js'\nimport {\n listLeaves,\n MIN_SPLIT_RATIO,\n MAX_SPLIT_RATIO,\n type SplitLayoutBranch,\n type SplitLayoutLeaf,\n} from './model'\n\nexport type SplitLayoutResizeControllerProps<L extends SplitLayoutLeaf> = {\n branch: Accessor<SplitLayoutBranch<L>>\n rect: Accessor<JSX.CSSProperties>\n domId: (id: string) => string\n root: () => HTMLDivElement | undefined\n labelForSeparator?: (branch: SplitLayoutBranch<L>) => string\n onResize: (splitId: string, ratio: number) => void\n}\n\n/** Corvu stays behind the first real split while the pane owners remain mounted. */\nexport default function SplitLayoutResizeController<L extends SplitLayoutLeaf>(\n props: SplitLayoutResizeControllerProps<L>\n) {\n const id = () => props.branch().id\n return (\n <Resizable\n orientation={props.branch().direction === 'row' ? 'horizontal' : 'vertical'}\n sizes={[props.branch().ratio, 1 - props.branch().ratio]}\n keyboardDelta={0.05}\n onSizesChange={(sizes) => {\n // Corvu also reports panel registration/unregistration while\n // mounting or disposing a controller. Those incomplete or\n // hidden-host sizes are not user resize intent.\n const root = props.root()\n if (!root?.isConnected || root.getClientRects().length === 0) return\n if (\n sizes.length !== 2 ||\n sizes.some((size) => !Number.isFinite(size)) ||\n Math.abs(sizes[0]! + sizes[1]! - 1) > 0.000001\n )\n return\n if (sizes[0] !== undefined && Math.abs(sizes[0] - props.branch().ratio) > 0.000001)\n props.onResize(id(), sizes[0])\n }}\n style={props.rect()}\n class=\"pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col\"\n >\n <Resizable.Panel minSize={MIN_SPLIT_RATIO} maxSize={MAX_SPLIT_RATIO} aria-hidden=\"true\" />\n <Resizable.Handle\n aria-label={\n props.labelForSeparator?.(props.branch()) ??\n (props.branch().direction === 'row' ? 'Resize pane columns' : 'Resize pane rows')\n }\n aria-orientation={props.branch().direction === 'row' ? 'vertical' : 'horizontal'}\n aria-controls={listLeaves(props.branch())\n .map((leaf) => props.domId(leaf.id))\n .join(' ')}\n aria-valuemin={10}\n aria-valuemax={90}\n aria-valuenow={Math.round(props.branch().ratio * 100)}\n class=\"pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full\"\n />\n <Resizable.Panel minSize={MIN_SPLIT_RATIO} maxSize={MAX_SPLIT_RATIO} aria-hidden=\"true\" />\n </Resizable>\n )\n}\n"],"mappings":";;;;;;AAoBA,SAAwBqB,4BACtBC,OACA;CACA,MAAMR,WAAWQ,MAAMb,OAAO,CAAC,CAACK;CAChC,OAAAS,gBACGvB,WAAS;EAAA,IACRwB,cAAW;GAAA,OAAEF,MAAMb,OAAO,CAAC,CAACgB,cAAc,QAAQ,eAAe;EAAU;EAAA,IAC3EC,QAAK;GAAA,OAAE,CAACJ,MAAMb,OAAO,CAAC,CAACW,OAAO,IAAIE,MAAMb,OAAO,CAAC,CAACW,KAAK;EAAC;EACvDO,eAAe;EACfC,gBAAgBF,UAAU;GAIxB,MAAMX,OAAOO,MAAMP,KAAK;GACxB,IAAI,CAACA,MAAMc,eAAed,KAAKe,eAAe,CAAC,CAACC,WAAW,GAAG;GAC9D,IACEL,MAAMK,WAAW,KACjBL,MAAMM,MAAMC,SAAS,CAACC,OAAOC,SAASF,IAAI,CAAC,KAC3CG,KAAKC,IAAIX,MAAM,KAAMA,MAAM,KAAM,CAAC,IAAI,MAEtC;GACF,IAAIA,MAAM,OAAOY,KAAAA,KAAaF,KAAKC,IAAIX,MAAM,KAAKJ,MAAMb,OAAO,CAAC,CAACW,KAAK,IAAI,MACxEE,MAAMJ,SAASJ,GAAG,GAAGY,MAAM,EAAE;EACjC;EAAC,IACDa,QAAK;GAAA,OAAEjB,MAAMX,KAAK;EAAC;EAAA,SAAA;EAAA,IAAA6B,WAAA;GAAA,OAAA;IAAAjB,gBAGlBvB,UAAUyC,OAAK;KAACC,SAAStC;KAAiBuC,SAAStC;KAAe,eAAA;IAAA,CAAA;IAAAkB,gBAClEvB,UAAU4C,QAAM;KAAA,KAAA,gBAAA;MAAA,OAEbtB,MAAML,oBAAoBK,MAAMb,OAAO,CAAC,MACvCa,MAAMb,OAAO,CAAC,CAACgB,cAAc,QAAQ,wBAAwB;KAAmB;KAAA,KAAA,sBAAA;MAAA,OAEjEH,MAAMb,OAAO,CAAC,CAACgB,cAAc,QAAQ,aAAa;KAAY;KAAA,KAAA,mBAAA;MAAA,OACjEtB,WAAWmB,MAAMb,OAAO,CAAC,CAAC,CACtCuC,KAAKC,SAAS3B,MAAMT,MAAMoC,KAAKnC,EAAE,CAAC,CAAC,CACnCoC,KAAK,GAAG;KAAC;KAAA,iBACG;KAAE,iBACF;KAAE,KAAA,mBAAA;MAAA,OACFd,KAAKgB,MAAM9B,MAAMb,OAAO,CAAC,CAACW,QAAQ,GAAG;KAAC;KAAA,SAAA;IAAA,CAAA;IAAAG,gBAGtDvB,UAAUyC,OAAK;KAACC,SAAStC;KAAiBuC,SAAStC;KAAe,eAAA;IAAA,CAAA;GAAA;EAAA;CAAA,CAAA;AAGzE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Accessor, type JSX } from 'solid-js';
|
|
2
|
+
import { type SplitLayoutBranch, type SplitLayoutLeaf } from './model';
|
|
3
|
+
export type SplitLayoutResizeControllerProps<L extends SplitLayoutLeaf> = {
|
|
4
|
+
branch: Accessor<SplitLayoutBranch<L>>;
|
|
5
|
+
rect: Accessor<JSX.CSSProperties>;
|
|
6
|
+
domId: (id: string) => string;
|
|
7
|
+
root: () => HTMLDivElement | undefined;
|
|
8
|
+
labelForSeparator?: (branch: SplitLayoutBranch<L>) => string;
|
|
9
|
+
onResize: (splitId: string, ratio: number) => void;
|
|
10
|
+
};
|
|
11
|
+
/** Corvu stays behind the first real split while the pane owners remain mounted. */
|
|
12
|
+
export default function SplitLayoutResizeController<L extends SplitLayoutLeaf>(props: SplitLayoutResizeControllerProps<L>): JSX.Element;
|
|
13
|
+
//# sourceMappingURL=resize-controller-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-controller-core.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/resize-controller-core.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,gCAAgC,CAAC,CAAC,SAAS,eAAe,IAAI;IACxE,MAAM,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IACjC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAA;IAC7B,IAAI,EAAE,MAAM,cAAc,GAAG,SAAS,CAAA;IACtC,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;IAC5D,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACnD,CAAA;AAED,oFAAoF;AACpF,MAAM,CAAC,OAAO,UAAU,2BAA2B,CAAC,CAAC,SAAS,eAAe,EAC3E,KAAK,EAAE,gCAAgC,CAAC,CAAC,CAAC,eA4C3C"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, listLeaves } from "./tree.js";
|
|
2
|
+
import { createComponent } from "solid-js/web";
|
|
3
|
+
import "solid-js";
|
|
4
|
+
import Resizable from "@corvu/resizable";
|
|
5
|
+
//#region src/components/layout/split-layout/resize-controller-core.tsx
|
|
6
|
+
/** Corvu stays behind the first real split while the pane owners remain mounted. */
|
|
7
|
+
function SplitLayoutResizeController(props) {
|
|
8
|
+
const id = () => props.branch().id;
|
|
9
|
+
return createComponent(Resizable, {
|
|
10
|
+
get orientation() {
|
|
11
|
+
return props.branch().direction === "row" ? "horizontal" : "vertical";
|
|
12
|
+
},
|
|
13
|
+
get sizes() {
|
|
14
|
+
return [props.branch().ratio, 1 - props.branch().ratio];
|
|
15
|
+
},
|
|
16
|
+
keyboardDelta: .05,
|
|
17
|
+
onSizesChange: (sizes) => {
|
|
18
|
+
const root = props.root();
|
|
19
|
+
if (!root?.isConnected || root.getClientRects().length === 0) return;
|
|
20
|
+
if (sizes.length !== 2 || sizes.some((size) => !Number.isFinite(size)) || Math.abs(sizes[0] + sizes[1] - 1) > 1e-6) return;
|
|
21
|
+
if (sizes[0] !== void 0 && Math.abs(sizes[0] - props.branch().ratio) > 1e-6) props.onResize(id(), sizes[0]);
|
|
22
|
+
},
|
|
23
|
+
get style() {
|
|
24
|
+
return props.rect();
|
|
25
|
+
},
|
|
26
|
+
"class": "pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col",
|
|
27
|
+
get children() {
|
|
28
|
+
return [
|
|
29
|
+
createComponent(Resizable.Panel, {
|
|
30
|
+
minSize: MIN_SPLIT_RATIO,
|
|
31
|
+
maxSize: MAX_SPLIT_RATIO,
|
|
32
|
+
"aria-hidden": "true"
|
|
33
|
+
}),
|
|
34
|
+
createComponent(Resizable.Handle, {
|
|
35
|
+
get ["aria-label"]() {
|
|
36
|
+
return props.labelForSeparator?.(props.branch()) ?? (props.branch().direction === "row" ? "Resize pane columns" : "Resize pane rows");
|
|
37
|
+
},
|
|
38
|
+
get ["aria-orientation"]() {
|
|
39
|
+
return props.branch().direction === "row" ? "vertical" : "horizontal";
|
|
40
|
+
},
|
|
41
|
+
get ["aria-controls"]() {
|
|
42
|
+
return listLeaves(props.branch()).map((leaf) => props.domId(leaf.id)).join(" ");
|
|
43
|
+
},
|
|
44
|
+
"aria-valuemin": 10,
|
|
45
|
+
"aria-valuemax": 90,
|
|
46
|
+
get ["aria-valuenow"]() {
|
|
47
|
+
return Math.round(props.branch().ratio * 100);
|
|
48
|
+
},
|
|
49
|
+
"class": "pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full"
|
|
50
|
+
}),
|
|
51
|
+
createComponent(Resizable.Panel, {
|
|
52
|
+
minSize: MIN_SPLIT_RATIO,
|
|
53
|
+
maxSize: MAX_SPLIT_RATIO,
|
|
54
|
+
"aria-hidden": "true"
|
|
55
|
+
})
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { SplitLayoutResizeController as default };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=resize-controller-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-controller-core.js","names":["Resizable","Accessor","JSX","listLeaves","MIN_SPLIT_RATIO","MAX_SPLIT_RATIO","SplitLayoutBranch","SplitLayoutLeaf","SplitLayoutResizeControllerProps","branch","L","rect","CSSProperties","domId","id","root","HTMLDivElement","labelForSeparator","onResize","splitId","ratio","SplitLayoutResizeController","props","_$createComponent","orientation","direction","sizes","keyboardDelta","onSizesChange","isConnected","getClientRects","length","some","size","Number","isFinite","Math","abs","undefined","style","children","Panel","minSize","maxSize","Handle","aria-label","aria-orientation","aria-controls","map","leaf","join","aria-valuenow","round","_$createComponent"],"sources":["../../../../src/components/layout/split-layout/resize-controller-core.tsx"],"sourcesContent":["import Resizable from '@corvu/resizable'\nimport { type Accessor, type JSX } from 'solid-js'\nimport {\n listLeaves,\n MIN_SPLIT_RATIO,\n MAX_SPLIT_RATIO,\n type SplitLayoutBranch,\n type SplitLayoutLeaf,\n} from './model'\n\nexport type SplitLayoutResizeControllerProps<L extends SplitLayoutLeaf> = {\n branch: Accessor<SplitLayoutBranch<L>>\n rect: Accessor<JSX.CSSProperties>\n domId: (id: string) => string\n root: () => HTMLDivElement | undefined\n labelForSeparator?: (branch: SplitLayoutBranch<L>) => string\n onResize: (splitId: string, ratio: number) => void\n}\n\n/** Corvu stays behind the first real split while the pane owners remain mounted. */\nexport default function SplitLayoutResizeController<L extends SplitLayoutLeaf>(\n props: SplitLayoutResizeControllerProps<L>\n) {\n const id = () => props.branch().id\n return (\n <Resizable\n orientation={props.branch().direction === 'row' ? 'horizontal' : 'vertical'}\n sizes={[props.branch().ratio, 1 - props.branch().ratio]}\n keyboardDelta={0.05}\n onSizesChange={(sizes) => {\n // Corvu also reports panel registration/unregistration while\n // mounting or disposing a controller. Those incomplete or\n // hidden-host sizes are not user resize intent.\n const root = props.root()\n if (!root?.isConnected || root.getClientRects().length === 0) return\n if (\n sizes.length !== 2 ||\n sizes.some((size) => !Number.isFinite(size)) ||\n Math.abs(sizes[0]! + sizes[1]! - 1) > 0.000001\n )\n return\n if (sizes[0] !== undefined && Math.abs(sizes[0] - props.branch().ratio) > 0.000001)\n props.onResize(id(), sizes[0])\n }}\n style={props.rect()}\n class=\"pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col\"\n >\n <Resizable.Panel minSize={MIN_SPLIT_RATIO} maxSize={MAX_SPLIT_RATIO} aria-hidden=\"true\" />\n <Resizable.Handle\n aria-label={\n props.labelForSeparator?.(props.branch()) ??\n (props.branch().direction === 'row' ? 'Resize pane columns' : 'Resize pane rows')\n }\n aria-orientation={props.branch().direction === 'row' ? 'vertical' : 'horizontal'}\n aria-controls={listLeaves(props.branch())\n .map((leaf) => props.domId(leaf.id))\n .join(' ')}\n aria-valuemin={10}\n aria-valuemax={90}\n aria-valuenow={Math.round(props.branch().ratio * 100)}\n class=\"pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full\"\n />\n <Resizable.Panel minSize={MIN_SPLIT_RATIO} maxSize={MAX_SPLIT_RATIO} aria-hidden=\"true\" />\n </Resizable>\n )\n}\n"],"mappings":";;;;;;AAoBA,SAAwBqB,4BACtBC,OACA;CACA,MAAMR,WAAWQ,MAAMb,OAAO,CAAC,CAACK;CAChC,OAAAS,gBACGvB,WAAS;EAAA,IACRwB,cAAW;GAAA,OAAEF,MAAMb,OAAO,CAAC,CAACgB,cAAc,QAAQ,eAAe;EAAU;EAAA,IAC3EC,QAAK;GAAA,OAAE,CAACJ,MAAMb,OAAO,CAAC,CAACW,OAAO,IAAIE,MAAMb,OAAO,CAAC,CAACW,KAAK;EAAC;EACvDO,eAAe;EACfC,gBAAgBF,UAAU;GAIxB,MAAMX,OAAOO,MAAMP,KAAK;GACxB,IAAI,CAACA,MAAMc,eAAed,KAAKe,eAAe,CAAC,CAACC,WAAW,GAAG;GAC9D,IACEL,MAAMK,WAAW,KACjBL,MAAMM,MAAMC,SAAS,CAACC,OAAOC,SAASF,IAAI,CAAC,KAC3CG,KAAKC,IAAIX,MAAM,KAAMA,MAAM,KAAM,CAAC,IAAI,MAEtC;GACF,IAAIA,MAAM,OAAOY,KAAAA,KAAaF,KAAKC,IAAIX,MAAM,KAAKJ,MAAMb,OAAO,CAAC,CAACW,KAAK,IAAI,MACxEE,MAAMJ,SAASJ,GAAG,GAAGY,MAAM,EAAE;EACjC;EAAC,IACDa,QAAK;GAAA,OAAEjB,MAAMX,KAAK;EAAC;EAAA,SAAA;EAAA,IAAA6B,WAAA;GAAA,OAAA;IAAAjB,gBAGlBvB,UAAUyC,OAAK;KAACC,SAAStC;KAAiBuC,SAAStC;KAAe,eAAA;IAAA,CAAA;IAAAkB,gBAClEvB,UAAU4C,QAAM;KAAA,KAAA,gBAAA;MAAA,OAEbtB,MAAML,oBAAoBK,MAAMb,OAAO,CAAC,MACvCa,MAAMb,OAAO,CAAC,CAACgB,cAAc,QAAQ,wBAAwB;KAAmB;KAAA,KAAA,sBAAA;MAAA,OAEjEH,MAAMb,OAAO,CAAC,CAACgB,cAAc,QAAQ,aAAa;KAAY;KAAA,KAAA,mBAAA;MAAA,OACjEtB,WAAWmB,MAAMb,OAAO,CAAC,CAAC,CACtCuC,KAAKC,SAAS3B,MAAMT,MAAMoC,KAAKnC,EAAE,CAAC,CAAC,CACnCoC,KAAK,GAAG;KAAC;KAAA,iBACG;KAAE,iBACF;KAAE,KAAA,mBAAA;MAAA,OACFd,KAAKgB,MAAM9B,MAAMb,OAAO,CAAC,CAACW,QAAQ,GAAG;KAAC;KAAA,SAAA;IAAA,CAAA;IAAAG,gBAGtDvB,UAAUyC,OAAK;KAACC,SAAStC;KAAiBuC,SAAStC;KAAe,eAAA;IAAA,CAAA;GAAA;EAAA;CAAA,CAAA;AAGzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-controller-retry-2.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/resize-controller-retry-2.tsx"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-controller-retry.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/resize-controller-retry.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-controller.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/resize-controller.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split-layout.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"split-layout.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAWL,KAAK,QAAQ,EACb,KAAK,GAAG,EACT,MAAM,UAAU,CAAA;AAOjB,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAI5C,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAA;AAQhB,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,eAAe,IAAI;IACxD,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IACjC,yFAAyF;IACzF,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IAC9C,yFAAyF;IACzF,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACpD,+GAA+G;IAC/G,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;IAC5D,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,sFAAsF;IACtF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAChD,qGAAqG;IACrG,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAA;IAC3E,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AA+HD,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,eAwdhF"}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { Button } from "../../ui/button/button.js";
|
|
2
3
|
import { ActionButton } from "../../composites/action-button/action-button.js";
|
|
3
|
-
import {
|
|
4
|
+
import { listLeaves } from "./tree.js";
|
|
4
5
|
import { computeLayoutFrames } from "./geometry.js";
|
|
5
6
|
import { paneDropIntent } from "./drop.js";
|
|
6
|
-
import { className, createComponent, delegateEvents, effect, insert, memo, setAttribute, style, template, use } from "solid-js/web";
|
|
7
|
+
import { Dynamic, className, createComponent, delegateEvents, effect, insert, memo, setAttribute, style, template, use } from "solid-js/web";
|
|
7
8
|
import { GripVertical, X } from "lucide-solid";
|
|
8
|
-
import { For, createComputed, createMemo, createSignal, createUniqueId, on, onCleanup } from "solid-js";
|
|
9
|
-
import Resizable from "@corvu/resizable";
|
|
9
|
+
import { For, Show, createComputed, createEffect, createMemo, createSignal, createUniqueId, on, onCleanup, onMount } from "solid-js";
|
|
10
10
|
//#region src/components/layout/split-layout/split-layout.tsx
|
|
11
11
|
var _tmpl$ = /*#__PURE__*/ template(`<div role=group data-slot=split-layout><span class=sr-only role=status>`);
|
|
12
12
|
var _tmpl$2 = /*#__PURE__*/ template(`<section role=region class="absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border transition-opacity motion-reduce:transition-none data-[drag-source]:opacity-40 data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"><header class="flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2"><span data-pane-drag-handle><span class="min-w-0 flex-1 truncate"></span></span></header><div class="min-h-0 min-w-0 flex-1 overflow-auto">`);
|
|
13
13
|
var _tmpl$3 = /*#__PURE__*/ template(`<div aria-hidden=true>`);
|
|
14
|
+
var _tmpl$4 = /*#__PURE__*/ template(`<div role=separator aria-valuemin=10 aria-valuemax=90 aria-disabled=true tabindex=-1 class="pointer-events-none absolute bg-border">`);
|
|
15
|
+
var _tmpl$5 = /*#__PURE__*/ template(`<div class="absolute top-2 right-2 z-(--z-menu) flex max-w-sm flex-col items-end gap-2">`);
|
|
16
|
+
var _tmpl$6 = /*#__PURE__*/ template(`<p role=alert class="rounded-md border bg-background p-2 text-sm shadow-md">Reloading may discard unsaved pane content.`);
|
|
14
17
|
var PANE_DRAG_TYPE = "application/x-adea-pane-move";
|
|
15
18
|
var DRAG_PREVIEW_MAX_WIDTH = 384;
|
|
16
19
|
var DRAG_PREVIEW_MAX_HEIGHT = 256;
|
|
@@ -22,6 +25,16 @@ function rectStyle(rect) {
|
|
|
22
25
|
height: `${rect.height * 100}%`
|
|
23
26
|
};
|
|
24
27
|
}
|
|
28
|
+
function separatorPlaceholderStyle(branch, rect) {
|
|
29
|
+
const horizontal = branch.direction === "row";
|
|
30
|
+
return {
|
|
31
|
+
left: `${(rect.x + (horizontal ? rect.width * branch.ratio : 0)) * 100}%`,
|
|
32
|
+
top: `${(rect.y + (horizontal ? 0 : rect.height * branch.ratio)) * 100}%`,
|
|
33
|
+
width: horizontal ? "1px" : `${rect.width * 100}%`,
|
|
34
|
+
height: horizontal ? `${rect.height * 100}%` : "1px",
|
|
35
|
+
transform: horizontal ? "translateX(-50%)" : "translateY(-50%)"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
25
38
|
function dragPreviewPlaceholder(source, message) {
|
|
26
39
|
const placeholder = document.createElement("div");
|
|
27
40
|
placeholder.className = cn(source.getAttribute("class"), "flex min-h-8 min-w-0 items-center justify-center bg-muted px-2 text-center text-xs text-muted-foreground");
|
|
@@ -119,14 +132,40 @@ function cloneDragPreviewNode(source) {
|
|
|
119
132
|
function SplitLayout(props) {
|
|
120
133
|
let root;
|
|
121
134
|
let pendingFrame;
|
|
135
|
+
let disposed = false;
|
|
136
|
+
let resizeLoadGeneration = 0;
|
|
137
|
+
let retryWithAlternateImport = false;
|
|
138
|
+
let alternateImportAttempts = 0;
|
|
139
|
+
let focusHandleAfterRetry = false;
|
|
140
|
+
let focusRecoveryButtonAfterError = false;
|
|
141
|
+
let focusRestoreEpoch = 0;
|
|
142
|
+
let focusEpoch = 0;
|
|
143
|
+
let pendingFocusFrame;
|
|
122
144
|
const refs = /* @__PURE__ */ new Map();
|
|
123
145
|
const domIds = /* @__PURE__ */ new Map();
|
|
124
146
|
const prefix = createUniqueId();
|
|
147
|
+
const resizeReloadWarningId = `${prefix}-resize-reload-warning`;
|
|
125
148
|
let nextDomId = 0;
|
|
126
149
|
let nextDragId = 0;
|
|
127
150
|
let dragPreview;
|
|
128
151
|
const [drag, setDrag] = createSignal();
|
|
129
152
|
const [drop, setDrop] = createSignal();
|
|
153
|
+
const [resizeController, setResizeController] = createSignal();
|
|
154
|
+
const cancelPendingFocusRestore = () => {
|
|
155
|
+
if (pendingFocusFrame !== void 0) cancelAnimationFrame(pendingFocusFrame);
|
|
156
|
+
pendingFocusFrame = void 0;
|
|
157
|
+
};
|
|
158
|
+
const trackFocusChange = (event) => {
|
|
159
|
+
if (event.target === document.body) return;
|
|
160
|
+
focusEpoch += 1;
|
|
161
|
+
focusHandleAfterRetry = false;
|
|
162
|
+
focusRecoveryButtonAfterError = false;
|
|
163
|
+
cancelPendingFocusRestore();
|
|
164
|
+
};
|
|
165
|
+
onMount(() => {
|
|
166
|
+
document.addEventListener("focusin", trackFocusChange);
|
|
167
|
+
onCleanup(() => document.removeEventListener("focusin", trackFocusChange));
|
|
168
|
+
});
|
|
130
169
|
const clearDrag = () => {
|
|
131
170
|
setDrag(void 0);
|
|
132
171
|
setDrop(void 0);
|
|
@@ -164,6 +203,46 @@ function SplitLayout(props) {
|
|
|
164
203
|
const leafMap = createMemo(() => new Map(leaves().map((leaf) => [leaf.id, leaf])));
|
|
165
204
|
const frames = createMemo(() => computeLayoutFrames(props.state.center));
|
|
166
205
|
const branches = createMemo(() => Array.from(frames().values()).flatMap((frame) => frame.node.kind === "split" ? [frame.node] : []));
|
|
206
|
+
createEffect(() => {
|
|
207
|
+
if (branches().length === 0) {
|
|
208
|
+
resizeLoadGeneration += 1;
|
|
209
|
+
focusHandleAfterRetry = false;
|
|
210
|
+
focusRecoveryButtonAfterError = false;
|
|
211
|
+
cancelPendingFocusRestore();
|
|
212
|
+
if (resizeController() === false || resizeController() === "error") setResizeController(void 0);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (resizeController() !== void 0) return;
|
|
216
|
+
const retry = retryWithAlternateImport;
|
|
217
|
+
const generation = ++resizeLoadGeneration;
|
|
218
|
+
setResizeController(false);
|
|
219
|
+
(retry ? alternateImportAttempts++ === 0 ? import("./resize-controller-retry.js") : import("./resize-controller-retry-2.js") : import("./resize-controller.js")).then(({ default: Controller }) => {
|
|
220
|
+
if (disposed || generation !== resizeLoadGeneration || branches().length === 0) return;
|
|
221
|
+
const shouldFocusHandle = focusHandleAfterRetry && focusEpoch === focusRestoreEpoch;
|
|
222
|
+
focusHandleAfterRetry = false;
|
|
223
|
+
focusRecoveryButtonAfterError = false;
|
|
224
|
+
retryWithAlternateImport = false;
|
|
225
|
+
alternateImportAttempts = 0;
|
|
226
|
+
setResizeController(() => Controller);
|
|
227
|
+
if (shouldFocusHandle) pendingFocusFrame = requestAnimationFrame(() => {
|
|
228
|
+
pendingFocusFrame = void 0;
|
|
229
|
+
if (disposed || generation !== resizeLoadGeneration || branches().length === 0 || focusEpoch !== focusRestoreEpoch) return;
|
|
230
|
+
const currentFocus = root?.ownerDocument.activeElement;
|
|
231
|
+
if (currentFocus && currentFocus !== root?.ownerDocument.body && currentFocus !== root) return;
|
|
232
|
+
root?.querySelector("[data-corvu-resizable-handle]")?.focus({ preventScroll: true });
|
|
233
|
+
});
|
|
234
|
+
}, () => {
|
|
235
|
+
retryWithAlternateImport = true;
|
|
236
|
+
if (!disposed && generation === resizeLoadGeneration && branches().length > 0) {
|
|
237
|
+
setResizeController("error");
|
|
238
|
+
if (focusRecoveryButtonAfterError && focusEpoch === focusRestoreEpoch) pendingFocusFrame = requestAnimationFrame(() => {
|
|
239
|
+
pendingFocusFrame = void 0;
|
|
240
|
+
if (disposed || generation !== resizeLoadGeneration || branches().length === 0 || focusEpoch !== focusRestoreEpoch) return;
|
|
241
|
+
root?.querySelector("[data-resize-retry]")?.focus({ preventScroll: true });
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
});
|
|
167
246
|
createComputed(() => {
|
|
168
247
|
const current = drag();
|
|
169
248
|
if (current && (!props.onMove || !leafMap().has(current.id))) clearDrag();
|
|
@@ -205,6 +284,10 @@ function SplitLayout(props) {
|
|
|
205
284
|
});
|
|
206
285
|
}));
|
|
207
286
|
onCleanup(() => {
|
|
287
|
+
disposed = true;
|
|
288
|
+
focusHandleAfterRetry = false;
|
|
289
|
+
focusRecoveryButtonAfterError = false;
|
|
290
|
+
cancelPendingFocusRestore();
|
|
208
291
|
if (pendingFrame !== void 0) cancelAnimationFrame(pendingFrame);
|
|
209
292
|
clearDrag();
|
|
210
293
|
refs.clear();
|
|
@@ -291,8 +374,8 @@ function SplitLayout(props) {
|
|
|
291
374
|
}
|
|
292
375
|
});
|
|
293
376
|
insert(_el$5, (() => {
|
|
294
|
-
var _c$ = memo(() => !!props.onMove);
|
|
295
|
-
return () => _c$() ? createComponent(GripVertical, {
|
|
377
|
+
var _c$2 = memo(() => !!props.onMove);
|
|
378
|
+
return () => _c$2() ? createComponent(GripVertical, {
|
|
296
379
|
"class": "size-3 shrink-0",
|
|
297
380
|
"aria-hidden": "true"
|
|
298
381
|
}) : null;
|
|
@@ -300,8 +383,8 @@ function SplitLayout(props) {
|
|
|
300
383
|
insert(_el$6, () => paneLabel ?? props.labelForLeaf(leaf()));
|
|
301
384
|
insert(_el$4, actions, null);
|
|
302
385
|
insert(_el$4, (() => {
|
|
303
|
-
var _c$
|
|
304
|
-
return () => _c$
|
|
386
|
+
var _c$3 = memo(() => !!props.onClose);
|
|
387
|
+
return () => _c$3() ? createComponent(ActionButton, {
|
|
305
388
|
variant: "ghost",
|
|
306
389
|
size: "icon-xs",
|
|
307
390
|
get ["aria-label"]() {
|
|
@@ -318,8 +401,8 @@ function SplitLayout(props) {
|
|
|
318
401
|
})(), null);
|
|
319
402
|
insert(_el$7, content);
|
|
320
403
|
insert(_el$3, (() => {
|
|
321
|
-
var _c$
|
|
322
|
-
return () => _c$
|
|
404
|
+
var _c$4 = memo(() => !!intent());
|
|
405
|
+
return () => _c$4() ? (() => {
|
|
323
406
|
var _el$8 = _tmpl$3();
|
|
324
407
|
effect(() => className(_el$8, cn("pointer-events-none absolute border-2 border-primary bg-primary/10", {
|
|
325
408
|
"inset-y-0 left-0 w-1/2": intent()?.direction === "row" && intent()?.placement === "before",
|
|
@@ -369,7 +452,7 @@ function SplitLayout(props) {
|
|
|
369
452
|
})();
|
|
370
453
|
}
|
|
371
454
|
}), _el$2);
|
|
372
|
-
insert(_el$2, dropLabel);
|
|
455
|
+
insert(_el$2, () => dropLabel() || (resizeController() === "error" ? alternateImportAttempts >= 2 ? "Resize controls did not load after repeated attempts. Reloading may discard unsaved pane content." : "Resize controls did not load." : ""));
|
|
373
456
|
insert(_el$, createComponent(For, {
|
|
374
457
|
get each() {
|
|
375
458
|
return branches().map((branch) => branch.id);
|
|
@@ -377,62 +460,90 @@ function SplitLayout(props) {
|
|
|
377
460
|
children: (id) => {
|
|
378
461
|
const initial = branchMap().get(id);
|
|
379
462
|
const branch = () => branchMap().get(id) ?? initial;
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
463
|
+
const rect = () => frames().get(id)?.rect ?? {
|
|
464
|
+
x: 0,
|
|
465
|
+
y: 0,
|
|
466
|
+
width: 0,
|
|
467
|
+
height: 0
|
|
468
|
+
};
|
|
469
|
+
return createComponent(Show, {
|
|
470
|
+
get when() {
|
|
471
|
+
return typeof resizeController() === "function";
|
|
386
472
|
},
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
473
|
+
get fallback() {
|
|
474
|
+
return (() => {
|
|
475
|
+
var _el$9 = _tmpl$4();
|
|
476
|
+
effect((_p$) => {
|
|
477
|
+
var _v$13 = props.labelForSeparator?.(branch()) ?? (branch().direction === "row" ? "Resize pane columns" : "Resize pane rows"), _v$14 = branch().direction === "row" ? "vertical" : "horizontal", _v$15 = listLeaves(branch()).map((leaf) => domId(leaf.id)).join(" "), _v$16 = Math.round(branch().ratio * 100), _v$17 = branch().direction, _v$18 = separatorPlaceholderStyle(branch(), rect());
|
|
478
|
+
_v$13 !== _p$.e && setAttribute(_el$9, "aria-label", _p$.e = _v$13);
|
|
479
|
+
_v$14 !== _p$.t && setAttribute(_el$9, "aria-orientation", _p$.t = _v$14);
|
|
480
|
+
_v$15 !== _p$.a && setAttribute(_el$9, "aria-controls", _p$.a = _v$15);
|
|
481
|
+
_v$16 !== _p$.o && setAttribute(_el$9, "aria-valuenow", _p$.o = _v$16);
|
|
482
|
+
_v$17 !== _p$.i && setAttribute(_el$9, "data-direction", _p$.i = _v$17);
|
|
483
|
+
_p$.n = style(_el$9, _v$18, _p$.n);
|
|
484
|
+
return _p$;
|
|
485
|
+
}, {
|
|
486
|
+
e: void 0,
|
|
487
|
+
t: void 0,
|
|
488
|
+
a: void 0,
|
|
489
|
+
o: void 0,
|
|
490
|
+
i: void 0,
|
|
491
|
+
n: void 0
|
|
492
|
+
});
|
|
493
|
+
return _el$9;
|
|
494
|
+
})();
|
|
392
495
|
},
|
|
393
|
-
get style() {
|
|
394
|
-
return rectStyle(frames().get(id)?.rect ?? {
|
|
395
|
-
x: 0,
|
|
396
|
-
y: 0,
|
|
397
|
-
width: 0,
|
|
398
|
-
height: 0
|
|
399
|
-
});
|
|
400
|
-
},
|
|
401
|
-
"class": "pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col",
|
|
402
496
|
get children() {
|
|
403
|
-
return
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
},
|
|
419
|
-
"aria-valuemin": 10,
|
|
420
|
-
"aria-valuemax": 90,
|
|
421
|
-
get ["aria-valuenow"]() {
|
|
422
|
-
return Math.round(branch().ratio * 100);
|
|
423
|
-
},
|
|
424
|
-
"class": "pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full"
|
|
425
|
-
}),
|
|
426
|
-
createComponent(Resizable.Panel, {
|
|
427
|
-
minSize: MIN_SPLIT_RATIO,
|
|
428
|
-
maxSize: MAX_SPLIT_RATIO,
|
|
429
|
-
"aria-hidden": "true"
|
|
430
|
-
})
|
|
431
|
-
];
|
|
497
|
+
return createComponent(Dynamic, {
|
|
498
|
+
get component() {
|
|
499
|
+
return resizeController();
|
|
500
|
+
},
|
|
501
|
+
branch,
|
|
502
|
+
rect: () => rectStyle(rect()),
|
|
503
|
+
domId,
|
|
504
|
+
root: () => root,
|
|
505
|
+
get labelForSeparator() {
|
|
506
|
+
return props.labelForSeparator;
|
|
507
|
+
},
|
|
508
|
+
get onResize() {
|
|
509
|
+
return props.onResize;
|
|
510
|
+
}
|
|
511
|
+
});
|
|
432
512
|
}
|
|
433
513
|
});
|
|
434
514
|
}
|
|
435
515
|
}), null);
|
|
516
|
+
insert(_el$, (() => {
|
|
517
|
+
var _c$ = memo(() => resizeController() === "error");
|
|
518
|
+
return () => _c$() ? (() => {
|
|
519
|
+
var _el$0 = _tmpl$5();
|
|
520
|
+
insert(_el$0, alternateImportAttempts >= 2 ? (() => {
|
|
521
|
+
var _el$1 = _tmpl$6();
|
|
522
|
+
setAttribute(_el$1, "id", resizeReloadWarningId);
|
|
523
|
+
return _el$1;
|
|
524
|
+
})() : null, null);
|
|
525
|
+
insert(_el$0, createComponent(Button, {
|
|
526
|
+
variant: "outline",
|
|
527
|
+
size: "sm",
|
|
528
|
+
"data-resize-retry": true,
|
|
529
|
+
"aria-describedby": alternateImportAttempts >= 2 ? resizeReloadWarningId : void 0,
|
|
530
|
+
onClick: (event) => {
|
|
531
|
+
if (alternateImportAttempts >= 2) {
|
|
532
|
+
window.location.reload();
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
const ownsFocus = document.activeElement === event.currentTarget;
|
|
536
|
+
focusHandleAfterRetry = ownsFocus;
|
|
537
|
+
focusRecoveryButtonAfterError = ownsFocus;
|
|
538
|
+
focusRestoreEpoch = focusEpoch;
|
|
539
|
+
retryWithAlternateImport = true;
|
|
540
|
+
setResizeController(void 0);
|
|
541
|
+
},
|
|
542
|
+
children: alternateImportAttempts >= 2 ? "Reload page to retry resizing" : "Retry pane resizing"
|
|
543
|
+
}), null);
|
|
544
|
+
return _el$0;
|
|
545
|
+
})() : null;
|
|
546
|
+
})(), null);
|
|
436
547
|
effect((_p$) => {
|
|
437
548
|
var _v$ = props.label, _v$2 = drag() ? "" : void 0, _v$3 = cn("relative size-full min-h-0 min-w-0 data-[dragging]:cursor-grabbing", props.class);
|
|
438
549
|
_v$ !== _p$.e && setAttribute(_el$, "aria-label", _p$.e = _v$);
|