@pie-players/pie-section-player-tools-shared 0.3.3

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.
@@ -0,0 +1,19 @@
1
+ export type SectionControllerKeyLike = {
2
+ sectionId?: string;
3
+ attemptId?: string;
4
+ };
5
+ export type SectionControllerLifecycleEventLike = {
6
+ type?: "ready" | "disposed" | string;
7
+ key?: SectionControllerKeyLike;
8
+ };
9
+ export type ToolkitCoordinatorWithSectionController<TController> = {
10
+ getSectionController?: (args: {
11
+ sectionId: string;
12
+ attemptId?: string;
13
+ }) => TController | undefined;
14
+ onSectionControllerLifecycle?: (listener: (event: SectionControllerLifecycleEventLike) => void) => () => void;
15
+ };
16
+ export declare function optionalIdsEqual(left?: string, right?: string): boolean;
17
+ export declare function isMatchingSectionControllerLifecycleEvent(event: SectionControllerLifecycleEventLike, sectionId: string, attemptId?: string): boolean;
18
+ export declare function getSectionControllerFromCoordinator<TController>(coordinator: ToolkitCoordinatorWithSectionController<TController> | null | undefined, sectionId: string, attemptId?: string): TController | null;
19
+ //# sourceMappingURL=section-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section-controller.d.ts","sourceRoot":"","sources":["../section-controller.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,wBAAwB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IACjD,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;IACrC,GAAG,CAAC,EAAE,wBAAwB,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,uCAAuC,CAAC,WAAW,IAAI;IAClE,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC7B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,KAAK,WAAW,GAAG,SAAS,CAAC;IAC9B,4BAA4B,CAAC,EAAE,CAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,mCAAmC,KAAK,IAAI,KAC1D,MAAM,IAAI,CAAC;CAChB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,wBAAgB,yCAAyC,CACxD,KAAK,EAAE,mCAAmC,EAC1C,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GAChB,OAAO,CAKT;AAED,wBAAgB,mCAAmC,CAAC,WAAW,EAC9D,WAAW,EACR,uCAAuC,CAAC,WAAW,CAAC,GACpD,IAAI,GACJ,SAAS,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GAChB,WAAW,GAAG,IAAI,CAQpB"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import('vite').UserConfig;
2
+ export default _default;
3
+ //# sourceMappingURL=vite.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../vite.config.ts"],"names":[],"mappings":";AAKA,wBA8BG"}
@@ -0,0 +1,165 @@
1
+ export type FloatingPanelState = {
2
+ x: number;
3
+ y: number;
4
+ width: number;
5
+ height: number;
6
+ };
7
+
8
+ export type FloatingPanelViewportSizing = {
9
+ widthRatio: number;
10
+ heightRatio: number;
11
+ minWidth: number;
12
+ maxWidth: number;
13
+ minHeight: number;
14
+ maxHeight: number;
15
+ alignX: "left" | "center" | "right";
16
+ alignY: "top" | "center" | "bottom";
17
+ paddingX?: number;
18
+ paddingY?: number;
19
+ };
20
+
21
+ export function computePanelSizeFromViewport(
22
+ viewport: { width: number; height: number },
23
+ sizing: FloatingPanelViewportSizing,
24
+ ): FloatingPanelState {
25
+ const clamp = (value: number, min: number, max: number) =>
26
+ Math.max(min, Math.min(value, max));
27
+ const width = clamp(
28
+ Math.round(viewport.width * sizing.widthRatio),
29
+ sizing.minWidth,
30
+ sizing.maxWidth,
31
+ );
32
+ const height = clamp(
33
+ Math.round(viewport.height * sizing.heightRatio),
34
+ sizing.minHeight,
35
+ sizing.maxHeight,
36
+ );
37
+ const paddingX = sizing.paddingX ?? 16;
38
+ const paddingY = sizing.paddingY ?? 16;
39
+ const maxX = Math.max(paddingX, viewport.width - width - paddingX);
40
+ const maxY = Math.max(paddingY, viewport.height - height - paddingY);
41
+ const x =
42
+ sizing.alignX === "left"
43
+ ? paddingX
44
+ : sizing.alignX === "right"
45
+ ? maxX
46
+ : Math.max(paddingX, Math.round((viewport.width - width) / 2));
47
+ const y =
48
+ sizing.alignY === "top"
49
+ ? paddingY
50
+ : sizing.alignY === "bottom"
51
+ ? maxY
52
+ : Math.max(paddingY, Math.round((viewport.height - height) / 2));
53
+ return { x, y, width, height };
54
+ }
55
+
56
+ type PointerControllerArgs = {
57
+ getState: () => FloatingPanelState;
58
+ setState: (next: FloatingPanelState) => void;
59
+ minWidth: number;
60
+ minHeight: number;
61
+ padding?: number;
62
+ };
63
+
64
+ export type FloatingPanelPointerController = {
65
+ startDrag: (event: MouseEvent) => void;
66
+ startResize: (event: MouseEvent) => void;
67
+ stop: () => void;
68
+ };
69
+
70
+ export function createFloatingPanelPointerController(
71
+ args: PointerControllerArgs,
72
+ ): FloatingPanelPointerController {
73
+ const padding = args.padding ?? 0;
74
+ let isDragging = false;
75
+ let isResizing = false;
76
+ let dragStartX = 0;
77
+ let dragStartY = 0;
78
+ let dragStartPanelX = 0;
79
+ let dragStartPanelY = 0;
80
+ let resizeStartX = 0;
81
+ let resizeStartY = 0;
82
+ let resizeStartWidth = 0;
83
+ let resizeStartHeight = 0;
84
+
85
+ const onDrag = (event: MouseEvent) => {
86
+ if (!isDragging) return;
87
+ const state = args.getState();
88
+ const deltaX = event.clientX - dragStartX;
89
+ const deltaY = event.clientY - dragStartY;
90
+ const maxX = Math.max(padding, window.innerWidth - state.width - padding);
91
+ const maxY = Math.max(padding, window.innerHeight - 100 - padding);
92
+ args.setState({
93
+ ...state,
94
+ x: Math.max(padding, Math.min(dragStartPanelX + deltaX, maxX)),
95
+ y: Math.max(padding, Math.min(dragStartPanelY + deltaY, maxY)),
96
+ });
97
+ };
98
+
99
+ const onResize = (event: MouseEvent) => {
100
+ if (!isResizing) return;
101
+ const state = args.getState();
102
+ const deltaX = event.clientX - resizeStartX;
103
+ const deltaY = event.clientY - resizeStartY;
104
+ const maxWidth = Math.max(
105
+ args.minWidth,
106
+ window.innerWidth - state.x - padding,
107
+ );
108
+ const maxHeight = Math.max(
109
+ args.minHeight,
110
+ window.innerHeight - state.y - padding,
111
+ );
112
+ args.setState({
113
+ ...state,
114
+ width: Math.max(
115
+ args.minWidth,
116
+ Math.min(resizeStartWidth + deltaX, maxWidth),
117
+ ),
118
+ height: Math.max(
119
+ args.minHeight,
120
+ Math.min(resizeStartHeight + deltaY, maxHeight),
121
+ ),
122
+ });
123
+ };
124
+
125
+ const stopDrag = () => {
126
+ isDragging = false;
127
+ document.removeEventListener("mousemove", onDrag);
128
+ document.removeEventListener("mouseup", stopDrag);
129
+ };
130
+
131
+ const stopResize = () => {
132
+ isResizing = false;
133
+ document.removeEventListener("mousemove", onResize);
134
+ document.removeEventListener("mouseup", stopResize);
135
+ };
136
+
137
+ return {
138
+ startDrag(event: MouseEvent) {
139
+ isDragging = true;
140
+ dragStartX = event.clientX;
141
+ dragStartY = event.clientY;
142
+ const state = args.getState();
143
+ dragStartPanelX = state.x;
144
+ dragStartPanelY = state.y;
145
+ document.addEventListener("mousemove", onDrag);
146
+ document.addEventListener("mouseup", stopDrag);
147
+ },
148
+ startResize(event: MouseEvent) {
149
+ isResizing = true;
150
+ resizeStartX = event.clientX;
151
+ resizeStartY = event.clientY;
152
+ const state = args.getState();
153
+ resizeStartWidth = state.width;
154
+ resizeStartHeight = state.height;
155
+ document.addEventListener("mousemove", onResize);
156
+ document.addEventListener("mouseup", stopResize);
157
+ event.preventDefault();
158
+ event.stopPropagation();
159
+ },
160
+ stop() {
161
+ stopDrag();
162
+ stopResize();
163
+ },
164
+ };
165
+ }
package/index.ts ADDED
@@ -0,0 +1,17 @@
1
+ export { default as PanelWindowControls } from "./PanelWindowControls.svelte";
2
+ export { default as PanelResizeHandle } from "./PanelResizeHandle.svelte";
3
+ export {
4
+ createFloatingPanelPointerController,
5
+ computePanelSizeFromViewport,
6
+ type FloatingPanelPointerController,
7
+ type FloatingPanelState,
8
+ type FloatingPanelViewportSizing,
9
+ } from "./floating-panel.js";
10
+ export {
11
+ getSectionControllerFromCoordinator,
12
+ isMatchingSectionControllerLifecycleEvent,
13
+ optionalIdsEqual,
14
+ type SectionControllerLifecycleEventLike,
15
+ type SectionControllerKeyLike,
16
+ type ToolkitCoordinatorWithSectionController,
17
+ } from "./section-controller.js";
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@pie-players/pie-section-player-tools-shared",
3
+ "version": "0.3.3",
4
+ "type": "module",
5
+ "description": "Shared UI and helpers for PIE section-player debug tools",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/pie-framework/pie-players.git",
9
+ "directory": "packages/section-player-tools-shared"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "keywords": [
15
+ "pie",
16
+ "section-player",
17
+ "debugger",
18
+ "shared",
19
+ "web-component"
20
+ ],
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.js",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "svelte": "./index.ts"
28
+ },
29
+ "./PanelWindowControls.svelte": {
30
+ "types": "./dist/PanelWindowControls.svelte.d.ts",
31
+ "svelte": "./PanelWindowControls.svelte"
32
+ },
33
+ "./PanelResizeHandle.svelte": {
34
+ "types": "./dist/PanelResizeHandle.svelte.d.ts",
35
+ "svelte": "./PanelResizeHandle.svelte"
36
+ }
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "*.svelte",
41
+ "*.ts",
42
+ "package.json"
43
+ ],
44
+ "license": "MIT",
45
+ "dependencies": {
46
+ "@pie-players/pie-theme": "0.3.3"
47
+ },
48
+ "types": "./dist/index.d.ts",
49
+ "scripts": {
50
+ "build": "vite build",
51
+ "dev": "vite build --watch",
52
+ "typecheck": "tsc --noEmit",
53
+ "lint": "biome check PanelWindowControls.svelte floating-panel.ts section-controller.ts index.ts vite.config.ts package.json"
54
+ },
55
+ "devDependencies": {
56
+ "@biomejs/biome": "^2.3.10",
57
+ "@sveltejs/vite-plugin-svelte": "^6.2.4",
58
+ "svelte": "^5.53.7",
59
+ "typescript": "^5.9.3",
60
+ "vite": "^7.3.1",
61
+ "vite-plugin-dts": "^4.5.4"
62
+ },
63
+ "homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/section-player-tools-shared#readme",
64
+ "bugs": {
65
+ "url": "https://github.com/pie-framework/pie-players/issues"
66
+ },
67
+ "engines": {
68
+ "node": ">=20.0.0"
69
+ },
70
+ "sideEffects": false
71
+ }
@@ -0,0 +1,51 @@
1
+ export type SectionControllerKeyLike = {
2
+ sectionId?: string;
3
+ attemptId?: string;
4
+ };
5
+
6
+ export type SectionControllerLifecycleEventLike = {
7
+ type?: "ready" | "disposed" | string;
8
+ key?: SectionControllerKeyLike;
9
+ };
10
+
11
+ export type ToolkitCoordinatorWithSectionController<TController> = {
12
+ getSectionController?: (args: {
13
+ sectionId: string;
14
+ attemptId?: string;
15
+ }) => TController | undefined;
16
+ onSectionControllerLifecycle?: (
17
+ listener: (event: SectionControllerLifecycleEventLike) => void,
18
+ ) => () => void;
19
+ };
20
+
21
+ export function optionalIdsEqual(left?: string, right?: string): boolean {
22
+ return (left || undefined) === (right || undefined);
23
+ }
24
+
25
+ export function isMatchingSectionControllerLifecycleEvent(
26
+ event: SectionControllerLifecycleEventLike,
27
+ sectionId: string,
28
+ attemptId?: string,
29
+ ): boolean {
30
+ const eventSectionId = event?.key?.sectionId || "";
31
+ const eventAttemptId = event?.key?.attemptId || undefined;
32
+ if (eventSectionId !== sectionId) return false;
33
+ return optionalIdsEqual(eventAttemptId, attemptId);
34
+ }
35
+
36
+ export function getSectionControllerFromCoordinator<TController>(
37
+ coordinator:
38
+ | ToolkitCoordinatorWithSectionController<TController>
39
+ | null
40
+ | undefined,
41
+ sectionId: string,
42
+ attemptId?: string,
43
+ ): TController | null {
44
+ if (!coordinator?.getSectionController || !sectionId) return null;
45
+ return (
46
+ coordinator.getSectionController({
47
+ sectionId,
48
+ attemptId,
49
+ }) || null
50
+ );
51
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,36 @@
1
+ import { svelte } from "@sveltejs/vite-plugin-svelte";
2
+ import { resolve } from "path";
3
+ import { defineConfig } from "vite";
4
+ import dts from "vite-plugin-dts";
5
+
6
+ export default defineConfig({
7
+ plugins: [
8
+ svelte({
9
+ emitCss: false,
10
+ }),
11
+ dts({
12
+ tsconfigPath: resolve(__dirname, "tsconfig.json"),
13
+ outDir: "dist",
14
+ insertTypesEntry: true,
15
+ include: ["**/*.ts", "**/*.svelte"],
16
+ }),
17
+ ],
18
+ build: {
19
+ lib: {
20
+ entry: resolve(__dirname, "index.ts"),
21
+ name: "PieSectionPlayerToolsShared",
22
+ fileName: () => "index.js",
23
+ formats: ["es"],
24
+ },
25
+ outDir: "dist",
26
+ emptyOutDir: true,
27
+ target: "es2020",
28
+ minify: "esbuild",
29
+ sourcemap: false,
30
+ rollupOptions: {
31
+ output: {
32
+ format: "es",
33
+ },
34
+ },
35
+ },
36
+ });