@ssgoi/qwik 6.6.4

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/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # @ssgoi/qwik
2
+
3
+ Qwik bindings for SSGOI - native app-like page transitions for Qwik and Qwik City.
4
+
5
+ Full setup reference for AI agents:
6
+
7
+ https://ssgoi.dev/llms.txt
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @ssgoi/qwik
13
+ ```
14
+
15
+ ## Qwik City
16
+
17
+ Qwik serializes component state for resumability, while SSGOI transition configs contain functions. Pass the config as a QRL factory (`config$`) so the adapter can resolve it in the browser before starting the DOM observer.
18
+
19
+ Use `useSsgoi(ref, { config$ })` directly in the Qwik City layout that owns the route `<Slot />`:
20
+
21
+ ```tsx
22
+ import { $, Slot, component$, useSignal } from "@builder.io/qwik";
23
+ import { Link, useLocation } from "@builder.io/qwik-city";
24
+ import { useSsgoi } from "@ssgoi/qwik";
25
+ import { drill, zoom } from "@ssgoi/qwik/view-transitions";
26
+
27
+ const ssgoiConfig$ = $(() => ({
28
+ preserveScroll: { exclude: ["/posts/*"] },
29
+ transitions: [
30
+ zoom({ paths: ["/gallery", "/gallery/*"], type: "expand" }),
31
+ drill({ enter: "/posts/*", exit: "/posts" }),
32
+ ],
33
+ }));
34
+
35
+ export default component$(() => {
36
+ const location = useLocation();
37
+ const ssgoiRoot = useSignal<HTMLElement>();
38
+
39
+ useSsgoi(ssgoiRoot, { config$: ssgoiConfig$ });
40
+
41
+ return (
42
+ <main
43
+ ref={ssgoiRoot}
44
+ class="relative z-0 h-dvh overflow-y-auto overflow-x-clip"
45
+ >
46
+ <Slot />
47
+ <Link href="/posts/">Posts</Link>
48
+ <p>{location.url.pathname}</p>
49
+ </main>
50
+ );
51
+ });
52
+ ```
53
+
54
+ Set `data-ssgoi-transition` directly on each routed page boundary. The value only needs to match the `paths`, `from`, or `to` values in your config:
55
+
56
+ ```tsx
57
+ export default component$(() => {
58
+ return (
59
+ <section data-ssgoi-transition="/posts" class="min-h-full">
60
+ Posts
61
+ </section>
62
+ );
63
+ });
64
+ ```
65
+
66
+ Import view-level factories from `@ssgoi/qwik/view-transitions`.
67
+
68
+ ## Qwik City Notes
69
+
70
+ - Declare configs with Qwik `$`, for example `const config$ = $(() => ({ transitions: [...] }))`. Do not pass a plain config object through component props.
71
+ - Keep the route `<Slot />` inside the same layout element observed by `useSsgoi`.
72
+ - Mark pages directly with `data-ssgoi-transition`; do not put one generic boundary around the parent `<Slot />`.
73
+ - Put layout-shell classes such as `relative z-0 overflow-x-clip` on the SSGOI root/scroll container, not on every page marker.
74
+
75
+ `Ssgoi` is also exported for wrapping concrete children outside Qwik City routing. In Qwik City layouts, prefer `useSsgoi` because forwarding a route `<Slot />` through another component can prevent routed content from being projected into the live DOM during navigation.
76
+
77
+ ## Troubleshooting
78
+
79
+ If route navigation works but no transition runs:
80
+
81
+ 1. Confirm the layout calls `useSsgoi(ssgoiRoot, { config$ })`.
82
+ 2. Confirm `config$` is created with Qwik `$`.
83
+ 3. Confirm the SSGOI root contains the route `<Slot />` directly.
84
+ 4. Confirm every routed page has a `data-ssgoi-transition` value that matches your transition config.
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const types = require("@ssgoi/core/types");
4
+ const useSsgoi = require("./use-ssgoi.qwik.cjs");
5
+ const ssgoi = require("./ssgoi.qwik.cjs");
6
+ const ssgoiTransition = require("./ssgoi-transition.qwik.cjs");
7
+ const core = require("@ssgoi/core");
8
+ exports.useSsgoi = useSsgoi.useSsgoi;
9
+ exports.Ssgoi = ssgoi.Ssgoi;
10
+ exports.SsgoiTransition = ssgoiTransition.SsgoiTransition;
11
+ Object.keys(types).forEach((k) => {
12
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
13
+ enumerable: true,
14
+ get: () => types[k]
15
+ });
16
+ });
17
+ Object.keys(core).forEach((k) => {
18
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
19
+ enumerable: true,
20
+ get: () => core[k]
21
+ });
22
+ });
@@ -0,0 +1,10 @@
1
+ export * from "@ssgoi/core/types";
2
+ import { useSsgoi } from "./use-ssgoi.qwik.mjs";
3
+ import { Ssgoi } from "./ssgoi.qwik.mjs";
4
+ import { SsgoiTransition } from "./ssgoi-transition.qwik.mjs";
5
+ export * from "@ssgoi/core";
6
+ export {
7
+ Ssgoi,
8
+ SsgoiTransition,
9
+ useSsgoi
10
+ };
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("@builder.io/qwik/jsx-runtime");
4
+ const qwik = require("@builder.io/qwik");
5
+ const SsgoiTransition = qwik.component$(({ id, class: className }) => {
6
+ return /* @__PURE__ */ jsxRuntime.jsx("div", {
7
+ "data-ssgoi-transition": id,
8
+ class: className,
9
+ children: /* @__PURE__ */ jsxRuntime.jsx(qwik.Slot, {})
10
+ });
11
+ });
12
+ exports.SsgoiTransition = SsgoiTransition;
@@ -0,0 +1,12 @@
1
+ import { jsx } from "@builder.io/qwik/jsx-runtime";
2
+ import { component$, Slot } from "@builder.io/qwik";
3
+ const SsgoiTransition = component$(({ id, class: className }) => {
4
+ return /* @__PURE__ */ jsx("div", {
5
+ "data-ssgoi-transition": id,
6
+ class: className,
7
+ children: /* @__PURE__ */ jsx(Slot, {})
8
+ });
9
+ });
10
+ export {
11
+ SsgoiTransition
12
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("@builder.io/qwik/jsx-runtime");
4
+ const qwik = require("@builder.io/qwik");
5
+ const useSsgoi = require("./use-ssgoi.qwik.cjs");
6
+ const Ssgoi = qwik.component$(({ config$, host$ }) => {
7
+ const root = qwik.useSignal();
8
+ useSsgoi.useSsgoi(root, {
9
+ config$,
10
+ host$
11
+ });
12
+ return /* @__PURE__ */ jsxRuntime.jsx("div", {
13
+ ref: root,
14
+ "data-ssgoi-root": "",
15
+ style: {
16
+ display: "contents"
17
+ },
18
+ children: /* @__PURE__ */ jsxRuntime.jsx(qwik.Slot, {})
19
+ });
20
+ });
21
+ exports.Ssgoi = Ssgoi;
@@ -0,0 +1,21 @@
1
+ import { jsx } from "@builder.io/qwik/jsx-runtime";
2
+ import { component$, useSignal, Slot } from "@builder.io/qwik";
3
+ import { useSsgoi } from "./use-ssgoi.qwik.mjs";
4
+ const Ssgoi = component$(({ config$, host$ }) => {
5
+ const root = useSignal();
6
+ useSsgoi(root, {
7
+ config$,
8
+ host$
9
+ });
10
+ return /* @__PURE__ */ jsx("div", {
11
+ ref: root,
12
+ "data-ssgoi-root": "",
13
+ style: {
14
+ display: "contents"
15
+ },
16
+ children: /* @__PURE__ */ jsx(Slot, {})
17
+ });
18
+ });
19
+ export {
20
+ Ssgoi
21
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const types = require("@ssgoi/core/types");
4
+ Object.keys(types).forEach((k) => {
5
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
6
+ enumerable: true,
7
+ get: () => types[k]
8
+ });
9
+ });
@@ -0,0 +1 @@
1
+ export * from "@ssgoi/core/types";
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const qwik = require("@builder.io/qwik");
4
+ const internal = require("@ssgoi/core/internal");
5
+ const useSsgoi = (root, options = {}) => {
6
+ const configQrl = options.config$;
7
+ const hostQrl = options.host$;
8
+ qwik.useVisibleTask$(async ({ cleanup, track }) => {
9
+ const element = track(() => root.value);
10
+ if (!element) return;
11
+ const configFactory = configQrl ? await configQrl.resolve() : void 0;
12
+ const hostFactory = hostQrl ? await hostQrl.resolve() : void 0;
13
+ const config = configFactory ? await configFactory() : {};
14
+ const host = hostFactory ? await hostFactory() : void 0;
15
+ const ssgoi = internal.createSggoiTransitionContext(config, {
16
+ host
17
+ });
18
+ const stopObserving = internal.observeSsgoiTransitions(element, ssgoi);
19
+ cleanup(stopObserving);
20
+ }, {
21
+ strategy: "document-ready"
22
+ });
23
+ };
24
+ exports.useSsgoi = useSsgoi;
@@ -0,0 +1,24 @@
1
+ import { useVisibleTask$ } from "@builder.io/qwik";
2
+ import { createSggoiTransitionContext, observeSsgoiTransitions } from "@ssgoi/core/internal";
3
+ const useSsgoi = (root, options = {}) => {
4
+ const configQrl = options.config$;
5
+ const hostQrl = options.host$;
6
+ useVisibleTask$(async ({ cleanup, track }) => {
7
+ const element = track(() => root.value);
8
+ if (!element) return;
9
+ const configFactory = configQrl ? await configQrl.resolve() : void 0;
10
+ const hostFactory = hostQrl ? await hostQrl.resolve() : void 0;
11
+ const config = configFactory ? await configFactory() : {};
12
+ const host = hostFactory ? await hostFactory() : void 0;
13
+ const ssgoi = createSggoiTransitionContext(config, {
14
+ host
15
+ });
16
+ const stopObserving = observeSsgoiTransitions(element, ssgoi);
17
+ cleanup(stopObserving);
18
+ }, {
19
+ strategy: "document-ready"
20
+ });
21
+ };
22
+ export {
23
+ useSsgoi
24
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const core = require("@ssgoi/core");
4
+ Object.keys(core).forEach((k) => {
5
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
6
+ enumerable: true,
7
+ get: () => core[k]
8
+ });
9
+ });
@@ -0,0 +1 @@
1
+ export * from "@ssgoi/core";
@@ -0,0 +1,5 @@
1
+ export * from "./types";
2
+ export { useSsgoi, type UseSsgoiOptions } from "./use-ssgoi";
3
+ export { Ssgoi } from "./ssgoi";
4
+ export { SsgoiTransition } from "./ssgoi-transition";
5
+ export * from "@ssgoi/core";
@@ -0,0 +1,11 @@
1
+ export interface SsgoiTransitionProps {
2
+ id: string;
3
+ class?: string;
4
+ }
5
+ /**
6
+ * Marks a subtree as a Ssgoi page boundary.
7
+ *
8
+ * @deprecated Set `data-ssgoi-transition` directly on the page boundary
9
+ * element inside `<Ssgoi>` instead.
10
+ */
11
+ export declare const SsgoiTransition: import("@builder.io/qwik").Component<SsgoiTransitionProps>;
@@ -0,0 +1,6 @@
1
+ import type { SsgoiConfigQrl, SsgoiHostQrl } from "./types";
2
+ export interface SsgoiProps {
3
+ config$?: SsgoiConfigQrl;
4
+ host$?: SsgoiHostQrl;
5
+ }
6
+ export declare const Ssgoi: import("@builder.io/qwik").Component<SsgoiProps>;
@@ -0,0 +1,11 @@
1
+ import type { QRL } from "@builder.io/qwik";
2
+ import type { HostAnimation } from "@ssgoi/core/internal";
3
+ import type { SsgoiConfig } from "@ssgoi/core/types";
4
+ export * from "@ssgoi/core/types";
5
+ export type SsgoiConfigFactory = () => SsgoiConfig | Promise<SsgoiConfig>;
6
+ export type SsgoiHostFactory = () =>
7
+ | HostAnimation
8
+ | undefined
9
+ | Promise<HostAnimation | undefined>;
10
+ export type SsgoiConfigQrl = QRL<SsgoiConfigFactory>;
11
+ export type SsgoiHostQrl = QRL<SsgoiHostFactory>;
@@ -0,0 +1,7 @@
1
+ import { type Signal } from "@builder.io/qwik";
2
+ import type { SsgoiConfigQrl, SsgoiHostQrl } from "./types";
3
+ export interface UseSsgoiOptions {
4
+ config$?: SsgoiConfigQrl;
5
+ host$?: SsgoiHostQrl;
6
+ }
7
+ export declare const useSsgoi: (root: Signal<HTMLElement | undefined>, options?: UseSsgoiOptions) => void;
@@ -0,0 +1 @@
1
+ export * from "@ssgoi/core";
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@ssgoi/qwik",
3
+ "version": "6.6.4",
4
+ "description": "Qwik bindings for SSGOI - Native app-like page transitions for Qwik and Qwik City applications",
5
+ "private": false,
6
+ "sideEffects": false,
7
+ "type": "module",
8
+ "main": "./lib/index.qwik.mjs",
9
+ "qwik": "./lib/index.qwik.mjs",
10
+ "types": "./lib-types/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./lib-types/index.d.ts",
14
+ "import": "./lib/index.qwik.mjs",
15
+ "require": "./lib/index.qwik.cjs"
16
+ },
17
+ "./types": {
18
+ "types": "./lib-types/types.d.ts",
19
+ "import": "./lib/types.qwik.mjs",
20
+ "require": "./lib/types.qwik.cjs"
21
+ },
22
+ "./view-transitions": {
23
+ "types": "./lib-types/view-transitions.d.ts",
24
+ "import": "./lib/view-transitions.qwik.mjs",
25
+ "require": "./lib/view-transitions.qwik.cjs"
26
+ }
27
+ },
28
+ "files": [
29
+ "lib",
30
+ "lib-types"
31
+ ],
32
+ "dependencies": {
33
+ "@ssgoi/core": "^6.6.4"
34
+ },
35
+ "peerDependencies": {
36
+ "@builder.io/qwik": "^1.20.0"
37
+ },
38
+ "devDependencies": {
39
+ "@builder.io/qwik": "^1.20.0",
40
+ "@eslint/js": "^9.30.1",
41
+ "@types/node": "^22.10.6",
42
+ "eslint": "^9.30.1",
43
+ "eslint-plugin-qwik": "^1.20.0",
44
+ "globals": "^16.3.0",
45
+ "typescript": "~5.8.3",
46
+ "typescript-eslint": "^8.35.1",
47
+ "vite": "^7.0.4",
48
+ "vite-tsconfig-paths": "^5.1.4"
49
+ },
50
+ "keywords": [
51
+ "qwik",
52
+ "qwik-city",
53
+ "page-transition",
54
+ "page-transitions",
55
+ "view-transitions",
56
+ "view-transition-api-alternative",
57
+ "animation",
58
+ "ssgoi",
59
+ "spring-physics",
60
+ "cross-browser",
61
+ "navigation-animation",
62
+ "hero-transition",
63
+ "shared-element-transition"
64
+ ],
65
+ "author": "MeurSyphus <tmdeoans@snu.ac.kr>",
66
+ "license": "MIT",
67
+ "repository": {
68
+ "type": "git",
69
+ "url": "git+https://github.com/meursyphus/ssgoi.git",
70
+ "directory": "packages/qwik"
71
+ },
72
+ "homepage": "https://ssgoi.dev",
73
+ "bugs": {
74
+ "url": "https://github.com/meursyphus/ssgoi/issues"
75
+ },
76
+ "publishConfig": {
77
+ "access": "public"
78
+ },
79
+ "engines": {
80
+ "node": ">=18.0.0"
81
+ },
82
+ "scripts": {
83
+ "build": "pnpm run build.lib && pnpm run build.types",
84
+ "build.lib": "vite build --mode lib",
85
+ "build.types": "tsc --emitDeclarationOnly",
86
+ "dev": "vite build --watch --mode lib",
87
+ "watch": "vite build --watch --mode lib",
88
+ "lint": "eslint \"src/**/*.ts*\""
89
+ }
90
+ }