@adea-ai/ui 0.82.2 → 0.83.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/components/layout/orbit-layout/index.d.ts +3 -0
- package/dist/components/layout/orbit-layout/index.d.ts.map +1 -0
- package/dist/components/layout/orbit-layout/index.js +2 -0
- package/dist/components/layout/orbit-layout/orbit-layout.d.ts +38 -0
- package/dist/components/layout/orbit-layout/orbit-layout.d.ts.map +1 -0
- package/dist/components/layout/orbit-layout/orbit-layout.js +83 -0
- package/dist/components/layout/orbit-layout/orbit-layout.js.map +1 -0
- package/dist/components/layout/virtual-window/index.d.ts +3 -0
- package/dist/components/layout/virtual-window/index.d.ts.map +1 -0
- package/dist/components/layout/virtual-window/index.js +2 -0
- package/dist/components/layout/virtual-window/virtual-window.d.ts +22 -0
- package/dist/components/layout/virtual-window/virtual-window.d.ts.map +1 -0
- package/dist/components/layout/virtual-window/virtual-window.js +45 -0
- package/dist/components/layout/virtual-window/virtual-window.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/r/orbit-layout.json +22 -0
- package/dist/r/registry.json +44 -0
- package/dist/r/src/components/layout/orbit-layout/index.ts +8 -0
- package/dist/r/src/components/layout/orbit-layout/orbit-layout.tsx +112 -0
- package/dist/r/src/components/layout/virtual-window/index.ts +2 -0
- package/dist/r/src/components/layout/virtual-window/virtual-window.tsx +55 -0
- package/dist/r/virtual-window.json +22 -0
- package/package.json +1 -1
- package/registry.json +44 -0
- package/src/components/layout/orbit-layout/index.ts +8 -0
- package/src/components/layout/orbit-layout/orbit-layout.tsx +112 -0
- package/src/components/layout/virtual-window/index.ts +2 -0
- package/src/components/layout/virtual-window/virtual-window.tsx +55 -0
- package/src/index.ts +2 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/orbit-layout/index.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,OAAO,EACL,SAAS,EACT,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,WAAW,GACjB,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ComponentProps } from 'solid-js';
|
|
2
|
+
/** A CSS length or expression used to place an item away from the orbit center. */
|
|
3
|
+
export type OrbitRadius = number | string;
|
|
4
|
+
export type OrbitLayoutMode = 'radial' | 'flow';
|
|
5
|
+
/**
|
|
6
|
+
* OrbitLayout.
|
|
7
|
+
*
|
|
8
|
+
* Provides a positioned canvas and a shared radius for its OrbitItems. It does
|
|
9
|
+
* not assign list semantics or alter DOM order: callers choose semantics, and
|
|
10
|
+
* keyboard and screen-reader order remain the source order of the children.
|
|
11
|
+
*/
|
|
12
|
+
export type OrbitLayoutProps = Omit<ComponentProps<'div'>, 'style'> & {
|
|
13
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
14
|
+
style?: never;
|
|
15
|
+
/** Responsive radius used by every OrbitItem unless that item overrides it. */
|
|
16
|
+
radius?: OrbitRadius;
|
|
17
|
+
/** `flow` places items in source order; `radial` positions them around the host. */
|
|
18
|
+
mode?: OrbitLayoutMode;
|
|
19
|
+
};
|
|
20
|
+
export declare function OrbitLayout(props: OrbitLayoutProps): import("solid-js").JSX.Element;
|
|
21
|
+
/**
|
|
22
|
+
* OrbitItem.
|
|
23
|
+
*
|
|
24
|
+
* Positions one ordinary child around its OrbitLayout. This is geometry only:
|
|
25
|
+
* the wrapper has no role, tabindex, or interaction of its own.
|
|
26
|
+
*/
|
|
27
|
+
export type OrbitItemProps = Omit<ComponentProps<'div'>, 'style'> & {
|
|
28
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
29
|
+
style?: never;
|
|
30
|
+
/** Zero-based position in the rendered sequence. */
|
|
31
|
+
index: number;
|
|
32
|
+
/** Number of items sharing this orbit. */
|
|
33
|
+
count: number;
|
|
34
|
+
/** Per-item override for OrbitLayout's responsive radius. */
|
|
35
|
+
radius?: OrbitRadius;
|
|
36
|
+
};
|
|
37
|
+
export declare function OrbitItem(props: OrbitItemProps): import("solid-js").JSX.Element;
|
|
38
|
+
//# sourceMappingURL=orbit-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orbit-layout.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/orbit-layout/orbit-layout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAI9C,mFAAmF;AACnF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAA;AACzC,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,CAAA;AAW/C;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,GAAG;IACpE,4DAA4D;IAC5D,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,+EAA+E;IAC/E,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,oFAAoF;IACpF,IAAI,CAAC,EAAE,eAAe,CAAA;CACvB,CAAA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,kCAkBlD;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,GAAG;IAClE,4DAA4D;IAC5D,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,kCAyC9C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { createComponent, insert, mergeProps, spread, template } from "solid-js/web";
|
|
3
|
+
import { createContext, createMemo, splitProps, useContext } from "solid-js";
|
|
4
|
+
//#region src/components/layout/orbit-layout/orbit-layout.tsx
|
|
5
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div>`);
|
|
6
|
+
var DEFAULT_ORBIT_RADIUS = "calc(50% - 2rem)";
|
|
7
|
+
var OrbitRadiusContext = createContext();
|
|
8
|
+
var OrbitModeContext = createContext();
|
|
9
|
+
function resolveRadius(radius) {
|
|
10
|
+
if (typeof radius === "number") return `${Number.isFinite(radius) ? Math.max(0, radius) : 0}px`;
|
|
11
|
+
return radius?.trim() || DEFAULT_ORBIT_RADIUS;
|
|
12
|
+
}
|
|
13
|
+
function OrbitLayout(props) {
|
|
14
|
+
const [local, rest] = splitProps(props, [
|
|
15
|
+
"class",
|
|
16
|
+
"radius",
|
|
17
|
+
"mode",
|
|
18
|
+
"style",
|
|
19
|
+
"children"
|
|
20
|
+
]);
|
|
21
|
+
const radius = createMemo(() => resolveRadius(local.radius));
|
|
22
|
+
const mode = createMemo(() => local.mode ?? "radial");
|
|
23
|
+
return createComponent(OrbitRadiusContext.Provider, {
|
|
24
|
+
value: radius,
|
|
25
|
+
get children() {
|
|
26
|
+
return createComponent(OrbitModeContext.Provider, {
|
|
27
|
+
value: mode,
|
|
28
|
+
get children() {
|
|
29
|
+
var _el$ = _tmpl$();
|
|
30
|
+
spread(_el$, mergeProps(rest, {
|
|
31
|
+
"data-slot": "orbit-layout",
|
|
32
|
+
get ["class"]() {
|
|
33
|
+
return cn(mode() === "flow" ? "grid gap-3" : "relative size-full", local.class);
|
|
34
|
+
}
|
|
35
|
+
}), false, true);
|
|
36
|
+
insert(_el$, () => local.children);
|
|
37
|
+
return _el$;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function OrbitItem(props) {
|
|
44
|
+
const [local, rest] = splitProps(props, [
|
|
45
|
+
"class",
|
|
46
|
+
"index",
|
|
47
|
+
"count",
|
|
48
|
+
"radius",
|
|
49
|
+
"style",
|
|
50
|
+
"children"
|
|
51
|
+
]);
|
|
52
|
+
const inheritedRadius = useContext(OrbitRadiusContext);
|
|
53
|
+
const inheritedMode = useContext(OrbitModeContext);
|
|
54
|
+
const mode = () => inheritedMode?.() ?? "radial";
|
|
55
|
+
const radius = () => local.radius !== void 0 ? resolveRadius(local.radius) : inheritedRadius?.() ?? DEFAULT_ORBIT_RADIUS;
|
|
56
|
+
const angle = createMemo(() => {
|
|
57
|
+
const count = Number.isFinite(local.count) ? Math.max(1, Math.trunc(local.count)) : 1;
|
|
58
|
+
return `${((Number.isFinite(local.index) ? Math.trunc(local.index) : 0) % count + count) % count / count * Math.PI * 2}rad`;
|
|
59
|
+
});
|
|
60
|
+
const positionStyle = () => mode() === "flow" ? void 0 : {
|
|
61
|
+
top: `calc(50% + sin(${angle()}) * ${radius()})`,
|
|
62
|
+
left: `calc(50% + cos(${angle()}) * ${radius()})`,
|
|
63
|
+
translate: "-50% -50%"
|
|
64
|
+
};
|
|
65
|
+
return (() => {
|
|
66
|
+
var _el$2 = _tmpl$();
|
|
67
|
+
spread(_el$2, mergeProps(rest, {
|
|
68
|
+
"data-slot": "orbit-item",
|
|
69
|
+
get ["class"]() {
|
|
70
|
+
return cn(mode() === "flow" ? void 0 : "absolute", local.class);
|
|
71
|
+
},
|
|
72
|
+
get style() {
|
|
73
|
+
return positionStyle();
|
|
74
|
+
}
|
|
75
|
+
}), false, true);
|
|
76
|
+
insert(_el$2, () => local.children);
|
|
77
|
+
return _el$2;
|
|
78
|
+
})();
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { OrbitItem, OrbitLayout };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=orbit-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orbit-layout.js","names":["ComponentProps","createContext","createMemo","splitProps","useContext","Accessor","cn","OrbitRadius","OrbitLayoutMode","DEFAULT_ORBIT_RADIUS","OrbitRadiusContext","OrbitModeContext","resolveRadius","radius","Number","isFinite","Math","max","trim","OrbitLayoutProps","Omit","style","mode","OrbitLayout","props","local","rest","_$createComponent","Provider","value","children","_el$","_tmpl$","_$spread","_$mergeProps","class","_$insert","OrbitItemProps","index","count","OrbitItem","inheritedRadius","inheritedMode","undefined","angle","trunc","rawIndex","PI","positionStyle","top","left","translate","_el$2","_$createComponent","_$mergeProps"],"sources":["../../../../src/components/layout/orbit-layout/orbit-layout.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { createContext, createMemo, splitProps, useContext, type Accessor } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/** A CSS length or expression used to place an item away from the orbit center. */\nexport type OrbitRadius = number | string\nexport type OrbitLayoutMode = 'radial' | 'flow'\n\nconst DEFAULT_ORBIT_RADIUS = 'calc(50% - 2rem)'\nconst OrbitRadiusContext = createContext<Accessor<string>>()\nconst OrbitModeContext = createContext<Accessor<OrbitLayoutMode>>()\n\nfunction resolveRadius(radius: OrbitRadius | undefined): string {\n if (typeof radius === 'number') return `${Number.isFinite(radius) ? Math.max(0, radius) : 0}px`\n return radius?.trim() || DEFAULT_ORBIT_RADIUS\n}\n\n/**\n * OrbitLayout.\n *\n * Provides a positioned canvas and a shared radius for its OrbitItems. It does\n * not assign list semantics or alter DOM order: callers choose semantics, and\n * keyboard and screen-reader order remain the source order of the children.\n */\nexport type OrbitLayoutProps = Omit<ComponentProps<'div'>, 'style'> & {\n /** JSX style props are owned by this geometry primitive. */\n style?: never\n /** Responsive radius used by every OrbitItem unless that item overrides it. */\n radius?: OrbitRadius\n /** `flow` places items in source order; `radial` positions them around the host. */\n mode?: OrbitLayoutMode\n}\n\nexport function OrbitLayout(props: OrbitLayoutProps) {\n const [local, rest] = splitProps(props, ['class', 'radius', 'mode', 'style', 'children'])\n const radius = createMemo(() => resolveRadius(local.radius))\n const mode = createMemo(() => local.mode ?? 'radial')\n\n return (\n <OrbitRadiusContext.Provider value={radius}>\n <OrbitModeContext.Provider value={mode}>\n <div\n {...rest}\n data-slot=\"orbit-layout\"\n class={cn(mode() === 'flow' ? 'grid gap-3' : 'relative size-full', local.class)}\n >\n {local.children}\n </div>\n </OrbitModeContext.Provider>\n </OrbitRadiusContext.Provider>\n )\n}\n\n/**\n * OrbitItem.\n *\n * Positions one ordinary child around its OrbitLayout. This is geometry only:\n * the wrapper has no role, tabindex, or interaction of its own.\n */\nexport type OrbitItemProps = Omit<ComponentProps<'div'>, 'style'> & {\n /** JSX style props are owned by this geometry primitive. */\n style?: never\n /** Zero-based position in the rendered sequence. */\n index: number\n /** Number of items sharing this orbit. */\n count: number\n /** Per-item override for OrbitLayout's responsive radius. */\n radius?: OrbitRadius\n}\n\nexport function OrbitItem(props: OrbitItemProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'index',\n 'count',\n 'radius',\n 'style',\n 'children',\n ])\n const inheritedRadius = useContext(OrbitRadiusContext)\n const inheritedMode = useContext(OrbitModeContext)\n const mode = () => inheritedMode?.() ?? 'radial'\n const radius = () =>\n local.radius !== undefined\n ? resolveRadius(local.radius)\n : (inheritedRadius?.() ?? DEFAULT_ORBIT_RADIUS)\n const angle = createMemo(() => {\n const count = Number.isFinite(local.count) ? Math.max(1, Math.trunc(local.count)) : 1\n const rawIndex = Number.isFinite(local.index) ? Math.trunc(local.index) : 0\n const index = ((rawIndex % count) + count) % count\n return `${(index / count) * Math.PI * 2}rad`\n })\n const positionStyle = () =>\n mode() === 'flow'\n ? undefined\n : {\n top: `calc(50% + sin(${angle()}) * ${radius()})`,\n left: `calc(50% + cos(${angle()}) * ${radius()})`,\n translate: '-50% -50%',\n }\n\n return (\n <div\n {...rest}\n data-slot=\"orbit-item\"\n class={cn(mode() === 'flow' ? undefined : 'absolute', local.class)}\n style={positionStyle()}\n >\n {local.children}\n </div>\n )\n}\n"],"mappings":";;;;;AAQA,IAAMS,uBAAuB;AAC7B,IAAMC,qBAAqBT,cAAgC;AAC3D,IAAMU,mBAAmBV,cAAyC;AAElE,SAASW,cAAcC,QAAyC;CAC9D,IAAI,OAAOA,WAAW,UAAU,OAAO,GAAGC,OAAOC,SAASF,MAAM,IAAIG,KAAKC,IAAI,GAAGJ,MAAM,IAAI,EAAC;CAC3F,OAAOA,QAAQK,KAAK,KAAKT;AAC3B;AAkBA,SAAgBc,YAAYC,OAAyB;CACnD,MAAM,CAACC,OAAOC,QAAQvB,WAAWqB,OAAO;EAAC;EAAS;EAAU;EAAQ;EAAS;CAAU,CAAC;CACxF,MAAMX,SAASX,iBAAiBU,cAAca,MAAMZ,MAAM,CAAC;CAC3D,MAAMS,OAAOpB,iBAAiBuB,MAAMH,QAAQ,QAAQ;CAEpD,OAAAK,gBACGjB,mBAAmBkB,UAAQ;EAACC,OAAOhB;EAAM,IAAAiB,WAAA;GAAA,OAAAH,gBACvChB,iBAAiBiB,UAAQ;IAACC,OAAOP;IAAI,IAAAQ,WAAA;KAAA,IAAAC,OAAAC,OAAA;KAAAC,OAAAF,MAAAG,WAE9BR,MAAI;MAAA,aACE;MAAc,KAAA,WAAA;OAAA,OACjBpB,GAAGgB,KAAK,MAAM,SAAS,eAAe,sBAAsBG,MAAMU,KAAK;MAAC;KAAA,CAAA,GAAA,OAAA,IAAA;KAAAC,OAAAL,YAE9EN,MAAMK,QAAQ;KAAA,OAAAC;IAAA;GAAA,CAAA;EAAA;CAAA,CAAA;AAKzB;AAmBA,SAAgBS,UAAUhB,OAAuB;CAC/C,MAAM,CAACC,OAAOC,QAAQvB,WAAWqB,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;CAAU,CACX;CACD,MAAMiB,kBAAkBrC,WAAWM,kBAAkB;CACrD,MAAMgC,gBAAgBtC,WAAWO,gBAAgB;CACjD,MAAMW,aAAaoB,gBAAgB,KAAK;CACxC,MAAM7B,eACJY,MAAMZ,WAAW8B,KAAAA,IACb/B,cAAca,MAAMZ,MAAM,IACzB4B,kBAAkB,KAAKhC;CAC9B,MAAMmC,QAAQ1C,iBAAiB;EAC7B,MAAMqC,QAAQzB,OAAOC,SAASU,MAAMc,KAAK,IAAIvB,KAAKC,IAAI,GAAGD,KAAK6B,MAAMpB,MAAMc,KAAK,CAAC,IAAI;EAGpF,OAAO,KAFUzB,OAAOC,SAASU,MAAMa,KAAK,IAAItB,KAAK6B,MAAMpB,MAAMa,KAAK,IAAI,KAC/CC,QAASA,SAASA,QAC1BA,QAASvB,KAAK+B,KAAK,EAAC;CACzC,CAAC;CACD,MAAMC,sBACJ1B,KAAK,MAAM,SACPqB,KAAAA,IACA;EACEM,KAAK,kBAAkBL,MAAM,EAAC,MAAO/B,OAAO,EAAC;EAC7CqC,MAAM,kBAAkBN,MAAM,EAAC,MAAO/B,OAAO,EAAC;EAC9CsC,WAAW;CACb;CAEN,cAAA;EAAA,IAAAC,QAAApB,OAAA;EAAAC,OAAAmB,OAAAlB,WAEQR,MAAI;GAAA,aACE;GAAY,KAAA,WAAA;IAAA,OACfpB,GAAGgB,KAAK,MAAM,SAASqB,KAAAA,IAAY,YAAYlB,MAAMU,KAAK;GAAC;GAAA,IAClEd,QAAK;IAAA,OAAE2B,cAAc;GAAC;EAAA,CAAA,GAAA,OAAA,IAAA;EAAAZ,OAAAgB,aAErB3B,MAAMK,QAAQ;EAAA,OAAAsB;CAAA,EAAA,CAAA;AAGrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/virtual-window/index.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ComponentProps, JSX } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* VirtualWindow.
|
|
4
|
+
*
|
|
5
|
+
* Supplies the two geometry wrappers a virtualized viewport needs: a full-height
|
|
6
|
+
* scroll space and a translated window containing the mounted rows. The caller
|
|
7
|
+
* owns the scroll region, its semantics, keyboard model, and range calculation;
|
|
8
|
+
* this component only keeps those rows at their measured position.
|
|
9
|
+
*/
|
|
10
|
+
export type VirtualWindowProps = Omit<ComponentProps<'div'>, 'children' | 'style'> & {
|
|
11
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
12
|
+
style?: never;
|
|
13
|
+
/** The full scrollable height, in pixels. */
|
|
14
|
+
totalSize: number;
|
|
15
|
+
/** The mounted window's top offset from the start of the full list, in pixels. */
|
|
16
|
+
offset?: number;
|
|
17
|
+
/** Optional layout classes for the translated row container. */
|
|
18
|
+
contentClass?: string;
|
|
19
|
+
children?: JSX.Element;
|
|
20
|
+
};
|
|
21
|
+
export declare function VirtualWindow(props: VirtualWindowProps): JSX.Element;
|
|
22
|
+
//# sourceMappingURL=virtual-window.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-window.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/virtual-window/virtual-window.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAInD;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG;IACnF,4DAA4D;IAC5D,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAA;IACjB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB,CAAA;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,eA0BtD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { className, effect, insert, mergeProps, setStyleProperty, spread, template } from "solid-js/web";
|
|
3
|
+
import { splitProps } from "solid-js";
|
|
4
|
+
//#region src/components/layout/virtual-window/virtual-window.tsx
|
|
5
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div><div data-slot=virtual-window-content>`);
|
|
6
|
+
function finitePixels(value) {
|
|
7
|
+
return `${Number.isFinite(value) ? value : 0}px`;
|
|
8
|
+
}
|
|
9
|
+
function VirtualWindow(props) {
|
|
10
|
+
const [local, rest] = splitProps(props, [
|
|
11
|
+
"class",
|
|
12
|
+
"children",
|
|
13
|
+
"totalSize",
|
|
14
|
+
"offset",
|
|
15
|
+
"contentClass",
|
|
16
|
+
"style"
|
|
17
|
+
]);
|
|
18
|
+
return (() => {
|
|
19
|
+
var _el$ = _tmpl$(), _el$2 = _el$.firstChild;
|
|
20
|
+
spread(_el$, mergeProps(rest, {
|
|
21
|
+
"data-slot": "virtual-window-space",
|
|
22
|
+
get ["class"]() {
|
|
23
|
+
return cn("relative", local.class);
|
|
24
|
+
},
|
|
25
|
+
get style() {
|
|
26
|
+
return { height: finitePixels(Math.max(0, local.totalSize)) };
|
|
27
|
+
}
|
|
28
|
+
}), false, true);
|
|
29
|
+
insert(_el$2, () => local.children);
|
|
30
|
+
effect((_p$) => {
|
|
31
|
+
var _v$ = local.contentClass, _v$2 = `translateY(${finitePixels(local.offset ?? 0)})`;
|
|
32
|
+
_v$ !== _p$.e && className(_el$2, _p$.e = _v$);
|
|
33
|
+
_v$2 !== _p$.t && setStyleProperty(_el$2, "transform", _p$.t = _v$2);
|
|
34
|
+
return _p$;
|
|
35
|
+
}, {
|
|
36
|
+
e: void 0,
|
|
37
|
+
t: void 0
|
|
38
|
+
});
|
|
39
|
+
return _el$;
|
|
40
|
+
})();
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { VirtualWindow };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=virtual-window.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-window.js","names":["ComponentProps","JSX","splitProps","cn","VirtualWindowProps","Omit","style","totalSize","offset","contentClass","children","Element","finitePixels","value","Number","isFinite","VirtualWindow","props","local","rest","_el$","_tmpl$","_el$2","firstChild","_$spread","_$mergeProps","class","height","Math","max","_$insert","_$effect","_p$","_v$","_v$2","e","_$className","t","_$setStyleProperty","undefined","_$mergeProps","_$className","_$setStyleProperty"],"sources":["../../../../src/components/layout/virtual-window/virtual-window.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * VirtualWindow.\n *\n * Supplies the two geometry wrappers a virtualized viewport needs: a full-height\n * scroll space and a translated window containing the mounted rows. The caller\n * owns the scroll region, its semantics, keyboard model, and range calculation;\n * this component only keeps those rows at their measured position.\n */\nexport type VirtualWindowProps = Omit<ComponentProps<'div'>, 'children' | 'style'> & {\n /** JSX style props are owned by this geometry primitive. */\n style?: never\n /** The full scrollable height, in pixels. */\n totalSize: number\n /** The mounted window's top offset from the start of the full list, in pixels. */\n offset?: number\n /** Optional layout classes for the translated row container. */\n contentClass?: string\n children?: JSX.Element\n}\n\nfunction finitePixels(value: number): string {\n return `${Number.isFinite(value) ? value : 0}px`\n}\n\nexport function VirtualWindow(props: VirtualWindowProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'children',\n 'totalSize',\n 'offset',\n 'contentClass',\n 'style',\n ])\n\n return (\n <div\n {...rest}\n data-slot=\"virtual-window-space\"\n class={cn('relative', local.class)}\n style={{ height: finitePixels(Math.max(0, local.totalSize)) }}\n >\n <div\n data-slot=\"virtual-window-content\"\n class={local.contentClass}\n style={{ transform: `translateY(${finitePixels(local.offset ?? 0)})` }}\n >\n {local.children}\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;AAwBA,SAASY,aAAaC,OAAuB;CAC3C,OAAO,GAAGC,OAAOC,SAASF,KAAK,IAAIA,QAAQ,EAAC;AAC9C;AAEA,SAAgBG,cAAcC,OAA2B;CACvD,MAAM,CAACC,OAAOC,QAAQjB,WAAWe,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;CAAO,CACR;CAED,cAAA;EAAA,IAAAG,OAAAC,OAAA,GAAAC,QAAAF,KAAAG;EAAAC,OAAAJ,MAAAK,WAEQN,MAAI;GAAA,aACE;GAAsB,KAAA,WAAA;IAAA,OACzBhB,GAAG,YAAYe,MAAMQ,KAAK;GAAC;GAAA,IAClCpB,QAAK;IAAA,OAAE,EAAEqB,QAAQf,aAAagB,KAAKC,IAAI,GAAGX,MAAMX,SAAS,CAAC,EAAE;GAAC;EAAA,CAAA,GAAA,OAAA,IAAA;EAAAuB,OAAAR,aAO1DJ,MAAMR,QAAQ;EAAAqB,QAAAC,QAAA;GAAA,IAAAC,MAHRf,MAAMT,cAAYyB,OACL,cAActB,aAAaM,MAAMV,UAAU,CAAC,EAAC;GAAGyB,QAAAD,IAAAG,KAAAC,UAAAd,OAAAU,IAAAG,IAAAF,GAAA;GAAAC,SAAAF,IAAAK,KAAAC,iBAAAhB,OAAA,aAAAU,IAAAK,IAAAH,IAAA;GAAA,OAAAF;EAAA,GAAA;GAAAG,GAAAI,KAAAA;GAAAF,GAAAE,KAAAA;EAAA,CAAA;EAAA,OAAAnB;CAAA,EAAA,CAAA;AAM5E"}
|
package/dist/index.d.ts
CHANGED
|
@@ -73,6 +73,8 @@ export * from './components/ui/toggle-group';
|
|
|
73
73
|
export * from './components/ui/tooltip';
|
|
74
74
|
export * from './components/motion';
|
|
75
75
|
export * from './components/layout/split-layout';
|
|
76
|
+
export * from './components/layout/orbit-layout';
|
|
77
|
+
export * from './components/layout/virtual-window';
|
|
76
78
|
export * from './components/layout/app-shell';
|
|
77
79
|
export * from './components/layout/page';
|
|
78
80
|
export * from './components/layout/panel';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -63,6 +63,8 @@ import { Motion } from "./components/motion/index.js";
|
|
|
63
63
|
import { MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, closePane, countLeaves, createLayoutState, focusPane, layoutDepth, listLeaves, movePane, neighborLeaf, normalizeLayout, resizeSplit, splitPane, swapPanes, undoClosePane } from "./components/layout/split-layout/model.js";
|
|
64
64
|
import { computeLayoutFrames } from "./components/layout/split-layout/geometry.js";
|
|
65
65
|
import { SplitLayout } from "./components/layout/split-layout/split-layout.js";
|
|
66
|
+
import { OrbitItem, OrbitLayout } from "./components/layout/orbit-layout/orbit-layout.js";
|
|
67
|
+
import { VirtualWindow } from "./components/layout/virtual-window/virtual-window.js";
|
|
66
68
|
import { AppShell, AppShellBody, AppShellContent, AppShellMain } from "./components/layout/app-shell/app-shell.js";
|
|
67
69
|
import { Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection } from "./components/layout/page/page.js";
|
|
68
70
|
import { Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar } from "./components/layout/panel/panel.js";
|
|
@@ -97,4 +99,4 @@ import { formatBytes, formatReleaseDate, plainTextFromMarkdown } from "./lib/ver
|
|
|
97
99
|
import { UpdateDialog } from "./components/composites/update-dialog/update-dialog.js";
|
|
98
100
|
import { WorkspaceMark } from "./components/composites/workspace-mark/workspace-mark.js";
|
|
99
101
|
import { keyedRows } from "./lib/keyed-rows.js";
|
|
100
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EntityIcon, Field, FieldDescription, FieldError, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavSection, SidebarNavTitle, Skeleton, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, UpdateDialog, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeSplit, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, zIndexTokens };
|
|
102
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EntityIcon, Field, FieldDescription, FieldError, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, OrbitItem, OrbitLayout, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavSection, SidebarNavTitle, Skeleton, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, UpdateDialog, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeSplit, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, zIndexTokens };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "orbit-layout",
|
|
3
|
+
"type": "registry:ui",
|
|
4
|
+
"title": "Orbit Layout",
|
|
5
|
+
"description": "Geometry-only wrappers for arranging content around a circle.",
|
|
6
|
+
"dependencies": [],
|
|
7
|
+
"registryDependencies": [
|
|
8
|
+
"lib"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
{
|
|
12
|
+
"path": "src/components/layout/orbit-layout/index.ts",
|
|
13
|
+
"type": "registry:ui",
|
|
14
|
+
"target": "components/layout/orbit-layout/index.ts"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"path": "src/components/layout/orbit-layout/orbit-layout.tsx",
|
|
18
|
+
"type": "registry:ui",
|
|
19
|
+
"target": "components/layout/orbit-layout/orbit-layout.tsx"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
package/dist/r/registry.json
CHANGED
|
@@ -1457,6 +1457,28 @@
|
|
|
1457
1457
|
}
|
|
1458
1458
|
]
|
|
1459
1459
|
},
|
|
1460
|
+
{
|
|
1461
|
+
"name": "orbit-layout",
|
|
1462
|
+
"type": "registry:ui",
|
|
1463
|
+
"title": "Orbit Layout",
|
|
1464
|
+
"description": "Geometry-only wrappers for arranging content around a circle.",
|
|
1465
|
+
"dependencies": [],
|
|
1466
|
+
"registryDependencies": [
|
|
1467
|
+
"lib"
|
|
1468
|
+
],
|
|
1469
|
+
"files": [
|
|
1470
|
+
{
|
|
1471
|
+
"path": "src/components/layout/orbit-layout/index.ts",
|
|
1472
|
+
"type": "registry:ui",
|
|
1473
|
+
"target": "components/layout/orbit-layout/index.ts"
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
"path": "src/components/layout/orbit-layout/orbit-layout.tsx",
|
|
1477
|
+
"type": "registry:ui",
|
|
1478
|
+
"target": "components/layout/orbit-layout/orbit-layout.tsx"
|
|
1479
|
+
}
|
|
1480
|
+
]
|
|
1481
|
+
},
|
|
1460
1482
|
{
|
|
1461
1483
|
"name": "page",
|
|
1462
1484
|
"type": "registry:ui",
|
|
@@ -1640,6 +1662,28 @@
|
|
|
1640
1662
|
}
|
|
1641
1663
|
]
|
|
1642
1664
|
},
|
|
1665
|
+
{
|
|
1666
|
+
"name": "virtual-window",
|
|
1667
|
+
"type": "registry:ui",
|
|
1668
|
+
"title": "Virtual Window",
|
|
1669
|
+
"description": "Geometry wrappers for a virtual list; scrolling and range ownership stay with the caller.",
|
|
1670
|
+
"dependencies": [],
|
|
1671
|
+
"registryDependencies": [
|
|
1672
|
+
"lib"
|
|
1673
|
+
],
|
|
1674
|
+
"files": [
|
|
1675
|
+
{
|
|
1676
|
+
"path": "src/components/layout/virtual-window/index.ts",
|
|
1677
|
+
"type": "registry:ui",
|
|
1678
|
+
"target": "components/layout/virtual-window/index.ts"
|
|
1679
|
+
},
|
|
1680
|
+
{
|
|
1681
|
+
"path": "src/components/layout/virtual-window/virtual-window.tsx",
|
|
1682
|
+
"type": "registry:ui",
|
|
1683
|
+
"target": "components/layout/virtual-window/virtual-window.tsx"
|
|
1684
|
+
}
|
|
1685
|
+
]
|
|
1686
|
+
},
|
|
1643
1687
|
{
|
|
1644
1688
|
"name": "account-menu",
|
|
1645
1689
|
"type": "registry:ui",
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { ComponentProps } from 'solid-js'
|
|
2
|
+
import { createContext, createMemo, splitProps, useContext, type Accessor } from 'solid-js'
|
|
3
|
+
import { cn } from '../../../lib/utils'
|
|
4
|
+
|
|
5
|
+
/** A CSS length or expression used to place an item away from the orbit center. */
|
|
6
|
+
export type OrbitRadius = number | string
|
|
7
|
+
export type OrbitLayoutMode = 'radial' | 'flow'
|
|
8
|
+
|
|
9
|
+
const DEFAULT_ORBIT_RADIUS = 'calc(50% - 2rem)'
|
|
10
|
+
const OrbitRadiusContext = createContext<Accessor<string>>()
|
|
11
|
+
const OrbitModeContext = createContext<Accessor<OrbitLayoutMode>>()
|
|
12
|
+
|
|
13
|
+
function resolveRadius(radius: OrbitRadius | undefined): string {
|
|
14
|
+
if (typeof radius === 'number') return `${Number.isFinite(radius) ? Math.max(0, radius) : 0}px`
|
|
15
|
+
return radius?.trim() || DEFAULT_ORBIT_RADIUS
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* OrbitLayout.
|
|
20
|
+
*
|
|
21
|
+
* Provides a positioned canvas and a shared radius for its OrbitItems. It does
|
|
22
|
+
* not assign list semantics or alter DOM order: callers choose semantics, and
|
|
23
|
+
* keyboard and screen-reader order remain the source order of the children.
|
|
24
|
+
*/
|
|
25
|
+
export type OrbitLayoutProps = Omit<ComponentProps<'div'>, 'style'> & {
|
|
26
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
27
|
+
style?: never
|
|
28
|
+
/** Responsive radius used by every OrbitItem unless that item overrides it. */
|
|
29
|
+
radius?: OrbitRadius
|
|
30
|
+
/** `flow` places items in source order; `radial` positions them around the host. */
|
|
31
|
+
mode?: OrbitLayoutMode
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function OrbitLayout(props: OrbitLayoutProps) {
|
|
35
|
+
const [local, rest] = splitProps(props, ['class', 'radius', 'mode', 'style', 'children'])
|
|
36
|
+
const radius = createMemo(() => resolveRadius(local.radius))
|
|
37
|
+
const mode = createMemo(() => local.mode ?? 'radial')
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<OrbitRadiusContext.Provider value={radius}>
|
|
41
|
+
<OrbitModeContext.Provider value={mode}>
|
|
42
|
+
<div
|
|
43
|
+
{...rest}
|
|
44
|
+
data-slot="orbit-layout"
|
|
45
|
+
class={cn(mode() === 'flow' ? 'grid gap-3' : 'relative size-full', local.class)}
|
|
46
|
+
>
|
|
47
|
+
{local.children}
|
|
48
|
+
</div>
|
|
49
|
+
</OrbitModeContext.Provider>
|
|
50
|
+
</OrbitRadiusContext.Provider>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* OrbitItem.
|
|
56
|
+
*
|
|
57
|
+
* Positions one ordinary child around its OrbitLayout. This is geometry only:
|
|
58
|
+
* the wrapper has no role, tabindex, or interaction of its own.
|
|
59
|
+
*/
|
|
60
|
+
export type OrbitItemProps = Omit<ComponentProps<'div'>, 'style'> & {
|
|
61
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
62
|
+
style?: never
|
|
63
|
+
/** Zero-based position in the rendered sequence. */
|
|
64
|
+
index: number
|
|
65
|
+
/** Number of items sharing this orbit. */
|
|
66
|
+
count: number
|
|
67
|
+
/** Per-item override for OrbitLayout's responsive radius. */
|
|
68
|
+
radius?: OrbitRadius
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function OrbitItem(props: OrbitItemProps) {
|
|
72
|
+
const [local, rest] = splitProps(props, [
|
|
73
|
+
'class',
|
|
74
|
+
'index',
|
|
75
|
+
'count',
|
|
76
|
+
'radius',
|
|
77
|
+
'style',
|
|
78
|
+
'children',
|
|
79
|
+
])
|
|
80
|
+
const inheritedRadius = useContext(OrbitRadiusContext)
|
|
81
|
+
const inheritedMode = useContext(OrbitModeContext)
|
|
82
|
+
const mode = () => inheritedMode?.() ?? 'radial'
|
|
83
|
+
const radius = () =>
|
|
84
|
+
local.radius !== undefined
|
|
85
|
+
? resolveRadius(local.radius)
|
|
86
|
+
: (inheritedRadius?.() ?? DEFAULT_ORBIT_RADIUS)
|
|
87
|
+
const angle = createMemo(() => {
|
|
88
|
+
const count = Number.isFinite(local.count) ? Math.max(1, Math.trunc(local.count)) : 1
|
|
89
|
+
const rawIndex = Number.isFinite(local.index) ? Math.trunc(local.index) : 0
|
|
90
|
+
const index = ((rawIndex % count) + count) % count
|
|
91
|
+
return `${(index / count) * Math.PI * 2}rad`
|
|
92
|
+
})
|
|
93
|
+
const positionStyle = () =>
|
|
94
|
+
mode() === 'flow'
|
|
95
|
+
? undefined
|
|
96
|
+
: {
|
|
97
|
+
top: `calc(50% + sin(${angle()}) * ${radius()})`,
|
|
98
|
+
left: `calc(50% + cos(${angle()}) * ${radius()})`,
|
|
99
|
+
translate: '-50% -50%',
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<div
|
|
104
|
+
{...rest}
|
|
105
|
+
data-slot="orbit-item"
|
|
106
|
+
class={cn(mode() === 'flow' ? undefined : 'absolute', local.class)}
|
|
107
|
+
style={positionStyle()}
|
|
108
|
+
>
|
|
109
|
+
{local.children}
|
|
110
|
+
</div>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ComponentProps, JSX } from 'solid-js'
|
|
2
|
+
import { splitProps } from 'solid-js'
|
|
3
|
+
import { cn } from '../../../lib/utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* VirtualWindow.
|
|
7
|
+
*
|
|
8
|
+
* Supplies the two geometry wrappers a virtualized viewport needs: a full-height
|
|
9
|
+
* scroll space and a translated window containing the mounted rows. The caller
|
|
10
|
+
* owns the scroll region, its semantics, keyboard model, and range calculation;
|
|
11
|
+
* this component only keeps those rows at their measured position.
|
|
12
|
+
*/
|
|
13
|
+
export type VirtualWindowProps = Omit<ComponentProps<'div'>, 'children' | 'style'> & {
|
|
14
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
15
|
+
style?: never
|
|
16
|
+
/** The full scrollable height, in pixels. */
|
|
17
|
+
totalSize: number
|
|
18
|
+
/** The mounted window's top offset from the start of the full list, in pixels. */
|
|
19
|
+
offset?: number
|
|
20
|
+
/** Optional layout classes for the translated row container. */
|
|
21
|
+
contentClass?: string
|
|
22
|
+
children?: JSX.Element
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function finitePixels(value: number): string {
|
|
26
|
+
return `${Number.isFinite(value) ? value : 0}px`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function VirtualWindow(props: VirtualWindowProps) {
|
|
30
|
+
const [local, rest] = splitProps(props, [
|
|
31
|
+
'class',
|
|
32
|
+
'children',
|
|
33
|
+
'totalSize',
|
|
34
|
+
'offset',
|
|
35
|
+
'contentClass',
|
|
36
|
+
'style',
|
|
37
|
+
])
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
{...rest}
|
|
42
|
+
data-slot="virtual-window-space"
|
|
43
|
+
class={cn('relative', local.class)}
|
|
44
|
+
style={{ height: finitePixels(Math.max(0, local.totalSize)) }}
|
|
45
|
+
>
|
|
46
|
+
<div
|
|
47
|
+
data-slot="virtual-window-content"
|
|
48
|
+
class={local.contentClass}
|
|
49
|
+
style={{ transform: `translateY(${finitePixels(local.offset ?? 0)})` }}
|
|
50
|
+
>
|
|
51
|
+
{local.children}
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "virtual-window",
|
|
3
|
+
"type": "registry:ui",
|
|
4
|
+
"title": "Virtual Window",
|
|
5
|
+
"description": "Geometry wrappers for a virtual list; scrolling and range ownership stay with the caller.",
|
|
6
|
+
"dependencies": [],
|
|
7
|
+
"registryDependencies": [
|
|
8
|
+
"lib"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
{
|
|
12
|
+
"path": "src/components/layout/virtual-window/index.ts",
|
|
13
|
+
"type": "registry:ui",
|
|
14
|
+
"target": "components/layout/virtual-window/index.ts"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"path": "src/components/layout/virtual-window/virtual-window.tsx",
|
|
18
|
+
"type": "registry:ui",
|
|
19
|
+
"target": "components/layout/virtual-window/virtual-window.tsx"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
package/package.json
CHANGED
package/registry.json
CHANGED
|
@@ -1457,6 +1457,28 @@
|
|
|
1457
1457
|
}
|
|
1458
1458
|
]
|
|
1459
1459
|
},
|
|
1460
|
+
{
|
|
1461
|
+
"name": "orbit-layout",
|
|
1462
|
+
"type": "registry:ui",
|
|
1463
|
+
"title": "Orbit Layout",
|
|
1464
|
+
"description": "Geometry-only wrappers for arranging content around a circle.",
|
|
1465
|
+
"dependencies": [],
|
|
1466
|
+
"registryDependencies": [
|
|
1467
|
+
"lib"
|
|
1468
|
+
],
|
|
1469
|
+
"files": [
|
|
1470
|
+
{
|
|
1471
|
+
"path": "src/components/layout/orbit-layout/index.ts",
|
|
1472
|
+
"type": "registry:ui",
|
|
1473
|
+
"target": "components/layout/orbit-layout/index.ts"
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
"path": "src/components/layout/orbit-layout/orbit-layout.tsx",
|
|
1477
|
+
"type": "registry:ui",
|
|
1478
|
+
"target": "components/layout/orbit-layout/orbit-layout.tsx"
|
|
1479
|
+
}
|
|
1480
|
+
]
|
|
1481
|
+
},
|
|
1460
1482
|
{
|
|
1461
1483
|
"name": "page",
|
|
1462
1484
|
"type": "registry:ui",
|
|
@@ -1640,6 +1662,28 @@
|
|
|
1640
1662
|
}
|
|
1641
1663
|
]
|
|
1642
1664
|
},
|
|
1665
|
+
{
|
|
1666
|
+
"name": "virtual-window",
|
|
1667
|
+
"type": "registry:ui",
|
|
1668
|
+
"title": "Virtual Window",
|
|
1669
|
+
"description": "Geometry wrappers for a virtual list; scrolling and range ownership stay with the caller.",
|
|
1670
|
+
"dependencies": [],
|
|
1671
|
+
"registryDependencies": [
|
|
1672
|
+
"lib"
|
|
1673
|
+
],
|
|
1674
|
+
"files": [
|
|
1675
|
+
{
|
|
1676
|
+
"path": "src/components/layout/virtual-window/index.ts",
|
|
1677
|
+
"type": "registry:ui",
|
|
1678
|
+
"target": "components/layout/virtual-window/index.ts"
|
|
1679
|
+
},
|
|
1680
|
+
{
|
|
1681
|
+
"path": "src/components/layout/virtual-window/virtual-window.tsx",
|
|
1682
|
+
"type": "registry:ui",
|
|
1683
|
+
"target": "components/layout/virtual-window/virtual-window.tsx"
|
|
1684
|
+
}
|
|
1685
|
+
]
|
|
1686
|
+
},
|
|
1643
1687
|
{
|
|
1644
1688
|
"name": "account-menu",
|
|
1645
1689
|
"type": "registry:ui",
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { ComponentProps } from 'solid-js'
|
|
2
|
+
import { createContext, createMemo, splitProps, useContext, type Accessor } from 'solid-js'
|
|
3
|
+
import { cn } from '#lib/utils'
|
|
4
|
+
|
|
5
|
+
/** A CSS length or expression used to place an item away from the orbit center. */
|
|
6
|
+
export type OrbitRadius = number | string
|
|
7
|
+
export type OrbitLayoutMode = 'radial' | 'flow'
|
|
8
|
+
|
|
9
|
+
const DEFAULT_ORBIT_RADIUS = 'calc(50% - 2rem)'
|
|
10
|
+
const OrbitRadiusContext = createContext<Accessor<string>>()
|
|
11
|
+
const OrbitModeContext = createContext<Accessor<OrbitLayoutMode>>()
|
|
12
|
+
|
|
13
|
+
function resolveRadius(radius: OrbitRadius | undefined): string {
|
|
14
|
+
if (typeof radius === 'number') return `${Number.isFinite(radius) ? Math.max(0, radius) : 0}px`
|
|
15
|
+
return radius?.trim() || DEFAULT_ORBIT_RADIUS
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* OrbitLayout.
|
|
20
|
+
*
|
|
21
|
+
* Provides a positioned canvas and a shared radius for its OrbitItems. It does
|
|
22
|
+
* not assign list semantics or alter DOM order: callers choose semantics, and
|
|
23
|
+
* keyboard and screen-reader order remain the source order of the children.
|
|
24
|
+
*/
|
|
25
|
+
export type OrbitLayoutProps = Omit<ComponentProps<'div'>, 'style'> & {
|
|
26
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
27
|
+
style?: never
|
|
28
|
+
/** Responsive radius used by every OrbitItem unless that item overrides it. */
|
|
29
|
+
radius?: OrbitRadius
|
|
30
|
+
/** `flow` places items in source order; `radial` positions them around the host. */
|
|
31
|
+
mode?: OrbitLayoutMode
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function OrbitLayout(props: OrbitLayoutProps) {
|
|
35
|
+
const [local, rest] = splitProps(props, ['class', 'radius', 'mode', 'style', 'children'])
|
|
36
|
+
const radius = createMemo(() => resolveRadius(local.radius))
|
|
37
|
+
const mode = createMemo(() => local.mode ?? 'radial')
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<OrbitRadiusContext.Provider value={radius}>
|
|
41
|
+
<OrbitModeContext.Provider value={mode}>
|
|
42
|
+
<div
|
|
43
|
+
{...rest}
|
|
44
|
+
data-slot="orbit-layout"
|
|
45
|
+
class={cn(mode() === 'flow' ? 'grid gap-3' : 'relative size-full', local.class)}
|
|
46
|
+
>
|
|
47
|
+
{local.children}
|
|
48
|
+
</div>
|
|
49
|
+
</OrbitModeContext.Provider>
|
|
50
|
+
</OrbitRadiusContext.Provider>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* OrbitItem.
|
|
56
|
+
*
|
|
57
|
+
* Positions one ordinary child around its OrbitLayout. This is geometry only:
|
|
58
|
+
* the wrapper has no role, tabindex, or interaction of its own.
|
|
59
|
+
*/
|
|
60
|
+
export type OrbitItemProps = Omit<ComponentProps<'div'>, 'style'> & {
|
|
61
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
62
|
+
style?: never
|
|
63
|
+
/** Zero-based position in the rendered sequence. */
|
|
64
|
+
index: number
|
|
65
|
+
/** Number of items sharing this orbit. */
|
|
66
|
+
count: number
|
|
67
|
+
/** Per-item override for OrbitLayout's responsive radius. */
|
|
68
|
+
radius?: OrbitRadius
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function OrbitItem(props: OrbitItemProps) {
|
|
72
|
+
const [local, rest] = splitProps(props, [
|
|
73
|
+
'class',
|
|
74
|
+
'index',
|
|
75
|
+
'count',
|
|
76
|
+
'radius',
|
|
77
|
+
'style',
|
|
78
|
+
'children',
|
|
79
|
+
])
|
|
80
|
+
const inheritedRadius = useContext(OrbitRadiusContext)
|
|
81
|
+
const inheritedMode = useContext(OrbitModeContext)
|
|
82
|
+
const mode = () => inheritedMode?.() ?? 'radial'
|
|
83
|
+
const radius = () =>
|
|
84
|
+
local.radius !== undefined
|
|
85
|
+
? resolveRadius(local.radius)
|
|
86
|
+
: (inheritedRadius?.() ?? DEFAULT_ORBIT_RADIUS)
|
|
87
|
+
const angle = createMemo(() => {
|
|
88
|
+
const count = Number.isFinite(local.count) ? Math.max(1, Math.trunc(local.count)) : 1
|
|
89
|
+
const rawIndex = Number.isFinite(local.index) ? Math.trunc(local.index) : 0
|
|
90
|
+
const index = ((rawIndex % count) + count) % count
|
|
91
|
+
return `${(index / count) * Math.PI * 2}rad`
|
|
92
|
+
})
|
|
93
|
+
const positionStyle = () =>
|
|
94
|
+
mode() === 'flow'
|
|
95
|
+
? undefined
|
|
96
|
+
: {
|
|
97
|
+
top: `calc(50% + sin(${angle()}) * ${radius()})`,
|
|
98
|
+
left: `calc(50% + cos(${angle()}) * ${radius()})`,
|
|
99
|
+
translate: '-50% -50%',
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<div
|
|
104
|
+
{...rest}
|
|
105
|
+
data-slot="orbit-item"
|
|
106
|
+
class={cn(mode() === 'flow' ? undefined : 'absolute', local.class)}
|
|
107
|
+
style={positionStyle()}
|
|
108
|
+
>
|
|
109
|
+
{local.children}
|
|
110
|
+
</div>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ComponentProps, JSX } from 'solid-js'
|
|
2
|
+
import { splitProps } from 'solid-js'
|
|
3
|
+
import { cn } from '#lib/utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* VirtualWindow.
|
|
7
|
+
*
|
|
8
|
+
* Supplies the two geometry wrappers a virtualized viewport needs: a full-height
|
|
9
|
+
* scroll space and a translated window containing the mounted rows. The caller
|
|
10
|
+
* owns the scroll region, its semantics, keyboard model, and range calculation;
|
|
11
|
+
* this component only keeps those rows at their measured position.
|
|
12
|
+
*/
|
|
13
|
+
export type VirtualWindowProps = Omit<ComponentProps<'div'>, 'children' | 'style'> & {
|
|
14
|
+
/** JSX style props are owned by this geometry primitive. */
|
|
15
|
+
style?: never
|
|
16
|
+
/** The full scrollable height, in pixels. */
|
|
17
|
+
totalSize: number
|
|
18
|
+
/** The mounted window's top offset from the start of the full list, in pixels. */
|
|
19
|
+
offset?: number
|
|
20
|
+
/** Optional layout classes for the translated row container. */
|
|
21
|
+
contentClass?: string
|
|
22
|
+
children?: JSX.Element
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function finitePixels(value: number): string {
|
|
26
|
+
return `${Number.isFinite(value) ? value : 0}px`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function VirtualWindow(props: VirtualWindowProps) {
|
|
30
|
+
const [local, rest] = splitProps(props, [
|
|
31
|
+
'class',
|
|
32
|
+
'children',
|
|
33
|
+
'totalSize',
|
|
34
|
+
'offset',
|
|
35
|
+
'contentClass',
|
|
36
|
+
'style',
|
|
37
|
+
])
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
{...rest}
|
|
42
|
+
data-slot="virtual-window-space"
|
|
43
|
+
class={cn('relative', local.class)}
|
|
44
|
+
style={{ height: finitePixels(Math.max(0, local.totalSize)) }}
|
|
45
|
+
>
|
|
46
|
+
<div
|
|
47
|
+
data-slot="virtual-window-content"
|
|
48
|
+
class={local.contentClass}
|
|
49
|
+
style={{ transform: `translateY(${finitePixels(local.offset ?? 0)})` }}
|
|
50
|
+
>
|
|
51
|
+
{local.children}
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -79,6 +79,8 @@ export * from './components/motion'
|
|
|
79
79
|
|
|
80
80
|
/* --- Layout -------------------------------------------------------------- */
|
|
81
81
|
export * from './components/layout/split-layout'
|
|
82
|
+
export * from './components/layout/orbit-layout'
|
|
83
|
+
export * from './components/layout/virtual-window'
|
|
82
84
|
export * from './components/layout/app-shell'
|
|
83
85
|
export * from './components/layout/page'
|
|
84
86
|
export * from './components/layout/panel'
|