@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 +84 -0
- package/lib/index.qwik.cjs +22 -0
- package/lib/index.qwik.mjs +10 -0
- package/lib/ssgoi-transition.qwik.cjs +12 -0
- package/lib/ssgoi-transition.qwik.mjs +12 -0
- package/lib/ssgoi.qwik.cjs +21 -0
- package/lib/ssgoi.qwik.mjs +21 -0
- package/lib/types.qwik.cjs +9 -0
- package/lib/types.qwik.mjs +1 -0
- package/lib/use-ssgoi.qwik.cjs +24 -0
- package/lib/use-ssgoi.qwik.mjs +24 -0
- package/lib/view-transitions.qwik.cjs +9 -0
- package/lib/view-transitions.qwik.mjs +1 -0
- package/lib-types/index.d.ts +5 -0
- package/lib-types/ssgoi-transition.d.ts +11 -0
- package/lib-types/ssgoi.d.ts +6 -0
- package/lib-types/types.d.ts +11 -0
- package/lib-types/use-ssgoi.d.ts +7 -0
- package/lib-types/view-transitions.d.ts +1 -0
- package/package.json +90 -0
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,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,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
|
+
}
|