@embedpdf/plugin-scroll 1.5.0 → 2.0.0-next.1

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.
Files changed (39) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +522 -266
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +30 -27
  6. package/dist/lib/index.d.ts +1 -0
  7. package/dist/lib/reducer.d.ts +3 -4
  8. package/dist/lib/scroll-plugin.d.ts +40 -27
  9. package/dist/lib/selectors.d.ts +2 -2
  10. package/dist/lib/types.d.ts +65 -30
  11. package/dist/preact/adapter.d.ts +1 -1
  12. package/dist/preact/index.cjs +1 -1
  13. package/dist/preact/index.cjs.map +1 -1
  14. package/dist/preact/index.js +33 -114
  15. package/dist/preact/index.js.map +1 -1
  16. package/dist/react/adapter.d.ts +1 -1
  17. package/dist/react/index.cjs +1 -1
  18. package/dist/react/index.cjs.map +1 -1
  19. package/dist/react/index.js +33 -114
  20. package/dist/react/index.js.map +1 -1
  21. package/dist/shared/components/scroller.d.ts +4 -4
  22. package/dist/shared/hooks/use-scroll.d.ts +4 -15
  23. package/dist/shared-preact/components/scroller.d.ts +4 -4
  24. package/dist/shared-preact/hooks/use-scroll.d.ts +4 -15
  25. package/dist/shared-react/components/scroller.d.ts +4 -4
  26. package/dist/shared-react/hooks/use-scroll.d.ts +4 -15
  27. package/dist/svelte/components/Scroller.svelte.d.ts +4 -4
  28. package/dist/svelte/hooks/use-scroll.svelte.d.ts +11 -5
  29. package/dist/svelte/index.cjs +1 -1
  30. package/dist/svelte/index.cjs.map +1 -1
  31. package/dist/svelte/index.js +90 -102
  32. package/dist/svelte/index.js.map +1 -1
  33. package/dist/vue/components/scroller.vue.d.ts +6 -9
  34. package/dist/vue/hooks/use-scroll.d.ts +12 -8
  35. package/dist/vue/index.cjs +1 -1
  36. package/dist/vue/index.cjs.map +1 -1
  37. package/dist/vue/index.js +115 -115
  38. package/dist/vue/index.js.map +1 -1
  39. package/package.json +7 -6
package/dist/vue/index.js CHANGED
@@ -1,166 +1,166 @@
1
- import { ref, watchEffect, computed, defineComponent, useAttrs, onMounted, createElementBlock, createCommentVNode, unref, openBlock, mergeProps, createElementVNode, normalizeStyle, Fragment, renderList, renderSlot, createBlock, resolveDynamicComponent } from "vue";
2
- import { usePlugin, useCapability, useRegistry } from "@embedpdf/core/vue";
1
+ import { ref, watch, toValue, computed, defineComponent, createElementBlock, createCommentVNode, openBlock, mergeProps, unref, createElementVNode, normalizeStyle, Fragment, renderList, renderSlot } from "vue";
2
+ import { usePlugin, useCapability } from "@embedpdf/core/vue";
3
3
  import { ScrollPlugin, ScrollStrategy } from "@embedpdf/plugin-scroll";
4
4
  export * from "@embedpdf/plugin-scroll";
5
5
  const useScrollPlugin = () => usePlugin(ScrollPlugin.id);
6
6
  const useScrollCapability = () => useCapability(ScrollPlugin.id);
7
- function useScroll() {
7
+ function useScroll(documentId) {
8
8
  const { provides } = useScrollCapability();
9
9
  const currentPage = ref(1);
10
10
  const totalPages = ref(1);
11
- watchEffect((onCleanup) => {
12
- if (!provides.value) return;
13
- const unsubscribe = provides.value.onPageChange(({ pageNumber, totalPages: tp }) => {
14
- currentPage.value = pageNumber;
15
- totalPages.value = tp;
16
- });
17
- onCleanup(unsubscribe);
18
- });
11
+ watch(
12
+ [provides, () => toValue(documentId)],
13
+ ([providesValue, docId], _, onCleanup) => {
14
+ if (!providesValue || !docId) {
15
+ currentPage.value = 1;
16
+ totalPages.value = 1;
17
+ return;
18
+ }
19
+ const scope = providesValue.forDocument(docId);
20
+ currentPage.value = scope.getCurrentPage();
21
+ totalPages.value = scope.getTotalPages();
22
+ const unsubscribe = providesValue.onPageChange((event) => {
23
+ if (event.documentId === docId) {
24
+ currentPage.value = event.pageNumber;
25
+ totalPages.value = event.totalPages;
26
+ }
27
+ });
28
+ onCleanup(unsubscribe);
29
+ },
30
+ { immediate: true }
31
+ );
19
32
  const state = computed(() => ({
20
33
  currentPage: currentPage.value,
21
34
  totalPages: totalPages.value
22
35
  }));
23
- const deprecatedCurrentPage = computed({
24
- get() {
25
- console.warn(
26
- `Accessing 'currentPage' directly on useScroll() is deprecated. Use useScroll().state.currentPage instead.`
27
- );
28
- return currentPage.value;
29
- },
30
- set(value) {
31
- currentPage.value = value;
32
- }
33
- });
34
- const deprecatedTotalPages = computed({
35
- get() {
36
- console.warn(
37
- `Accessing 'totalPages' directly on useScroll() is deprecated. Use useScroll().state.totalPages instead.`
38
- );
39
- return totalPages.value;
40
- },
41
- set(value) {
42
- totalPages.value = value;
43
- }
44
- });
45
- const deprecatedScroll = computed(() => {
46
- if (provides.value) {
47
- console.warn(
48
- `Accessing 'scroll' directly on useScroll() is deprecated. Use useScroll().provides instead.`
49
- );
50
- }
51
- return provides.value;
36
+ const scopedProvides = computed(() => {
37
+ var _a;
38
+ const docId = toValue(documentId);
39
+ return ((_a = provides.value) == null ? void 0 : _a.forDocument(docId)) ?? null;
52
40
  });
53
41
  return {
54
- // New format (preferred)
55
- provides,
56
- state,
57
- // Deprecated properties (for backward compatibility)
58
- currentPage: deprecatedCurrentPage,
59
- totalPages: deprecatedTotalPages,
60
- scroll: deprecatedScroll
42
+ provides: scopedProvides,
43
+ state
61
44
  };
62
45
  }
63
46
  const _sfc_main = /* @__PURE__ */ defineComponent({
64
47
  __name: "scroller",
65
48
  props: {
66
- style: { type: [Boolean, null, String, Object, Array] },
67
- overlayElements: { default: () => [] }
49
+ documentId: {}
68
50
  },
69
51
  setup(__props) {
70
52
  const props = __props;
71
- const attrs = useAttrs();
72
53
  const { plugin: scrollPlugin } = useScrollPlugin();
73
- const { registry } = useRegistry();
74
- const layout = ref(null);
75
- watchEffect((onCleanup) => {
76
- if (!scrollPlugin.value) return;
77
- layout.value = scrollPlugin.value.getScrollerLayout();
78
- const off = scrollPlugin.value.onScrollerData((l) => layout.value = l);
79
- onCleanup(off);
80
- });
81
- onMounted(() => {
82
- var _a;
83
- (_a = scrollPlugin.value) == null ? void 0 : _a.setLayoutReady();
54
+ const layoutData = ref({ layout: null, docId: null });
55
+ watch(
56
+ [scrollPlugin, () => props.documentId],
57
+ ([plugin, docId], _, onCleanup) => {
58
+ if (!plugin || !docId) {
59
+ layoutData.value = { layout: null, docId: null };
60
+ return;
61
+ }
62
+ const unsubscribe = plugin.onScrollerData(docId, (newLayout) => {
63
+ layoutData.value = { layout: newLayout, docId };
64
+ });
65
+ onCleanup(() => {
66
+ unsubscribe();
67
+ layoutData.value = { layout: null, docId: null };
68
+ plugin.clearLayoutReady(docId);
69
+ });
70
+ },
71
+ {
72
+ immediate: true
73
+ }
74
+ );
75
+ const scrollerLayout = computed(() => {
76
+ return layoutData.value.docId === props.documentId ? layoutData.value.layout : null;
84
77
  });
85
- function pageSlotProps(pl) {
86
- const core = registry.value.getStore().getState().core;
87
- return {
88
- ...pl,
89
- rotation: core.rotation,
90
- scale: core.scale,
91
- document: core.document
92
- };
93
- }
94
- const rootStyle = computed(() => {
95
- if (!layout.value) return props.style;
96
- const base = typeof props.style === "object" && !Array.isArray(props.style) ? { ...props.style } : props.style ?? {};
97
- return [
98
- base,
99
- {
100
- width: `${layout.value.totalWidth}px`,
101
- height: `${layout.value.totalHeight}px`,
78
+ watch(
79
+ [scrollPlugin, () => props.documentId, scrollerLayout],
80
+ ([plugin, docId, layout]) => {
81
+ if (!plugin || !docId || !layout) return;
82
+ plugin.setLayoutReady(docId);
83
+ },
84
+ { immediate: true }
85
+ );
86
+ return (_ctx, _cache) => {
87
+ return scrollerLayout.value ? (openBlock(), createElementBlock("div", mergeProps({
88
+ key: 0,
89
+ style: {
90
+ width: `${scrollerLayout.value.totalWidth}px`,
91
+ height: `${scrollerLayout.value.totalHeight}px`,
102
92
  position: "relative",
103
93
  boxSizing: "border-box",
104
94
  margin: "0 auto",
105
- ...layout.value.strategy === ScrollStrategy.Horizontal && {
95
+ ...scrollerLayout.value.strategy === unref(ScrollStrategy).Horizontal && {
106
96
  display: "flex",
107
97
  flexDirection: "row"
108
98
  }
109
99
  }
110
- ];
111
- });
112
- return (_ctx, _cache) => {
113
- return layout.value && unref(registry) ? (openBlock(), createElementBlock("div", mergeProps({
114
- key: 0,
115
- style: rootStyle.value
116
- }, unref(attrs)), [
117
- layout.value.strategy === "horizontal" ? (openBlock(), createElementBlock("div", {
118
- key: 0,
119
- style: normalizeStyle({ width: layout.value.startSpacing + "px", height: "100%", flexShrink: 0 })
120
- }, null, 4)) : (openBlock(), createElementBlock("div", {
121
- key: 1,
122
- style: normalizeStyle({ height: layout.value.startSpacing + "px", width: "100%" })
123
- }, null, 4)),
100
+ }, _ctx.$attrs), [
101
+ createElementVNode("div", {
102
+ style: normalizeStyle(
103
+ scrollerLayout.value.strategy === unref(ScrollStrategy).Horizontal ? {
104
+ width: `${scrollerLayout.value.startSpacing}px`,
105
+ height: "100%",
106
+ flexShrink: 0
107
+ } : {
108
+ height: `${scrollerLayout.value.startSpacing}px`,
109
+ width: "100%"
110
+ }
111
+ )
112
+ }, null, 4),
124
113
  createElementVNode("div", {
125
114
  style: normalizeStyle({
126
- gap: layout.value.pageGap + "px",
115
+ gap: `${scrollerLayout.value.pageGap}px`,
127
116
  display: "flex",
128
117
  alignItems: "center",
129
118
  position: "relative",
130
119
  boxSizing: "border-box",
131
- flexDirection: layout.value.strategy === "horizontal" ? "row" : "column",
132
- minHeight: layout.value.strategy === "horizontal" ? "100%" : void 0,
133
- minWidth: layout.value.strategy === "vertical" ? "fit-content" : void 0
120
+ ...scrollerLayout.value.strategy === unref(ScrollStrategy).Horizontal ? {
121
+ flexDirection: "row",
122
+ minHeight: "100%"
123
+ } : {
124
+ flexDirection: "column",
125
+ minWidth: "fit-content"
126
+ }
134
127
  })
135
128
  }, [
136
- (openBlock(true), createElementBlock(Fragment, null, renderList(layout.value.items, (item) => {
129
+ (openBlock(true), createElementBlock(Fragment, null, renderList(scrollerLayout.value.items, (item) => {
137
130
  return openBlock(), createElementBlock("div", {
138
131
  key: item.pageNumbers[0],
139
- style: normalizeStyle({ display: "flex", justifyContent: "center", gap: layout.value.pageGap + "px" })
132
+ style: normalizeStyle({
133
+ display: "flex",
134
+ justifyContent: "center",
135
+ gap: `${scrollerLayout.value.pageGap}px`
136
+ })
140
137
  }, [
141
- (openBlock(true), createElementBlock(Fragment, null, renderList(item.pageLayouts, (pl) => {
138
+ (openBlock(true), createElementBlock(Fragment, null, renderList(item.pageLayouts, (layout) => {
142
139
  return openBlock(), createElementBlock("div", {
143
- key: pl.pageNumber,
144
- style: normalizeStyle({ width: pl.rotatedWidth + "px", height: pl.rotatedHeight + "px" })
145
- }, [
146
- renderSlot(_ctx.$slots, "default", {
147
- page: pageSlotProps(pl)
140
+ key: layout.pageNumber,
141
+ style: normalizeStyle({
142
+ width: `${layout.rotatedWidth}px`,
143
+ height: `${layout.rotatedHeight}px`
148
144
  })
145
+ }, [
146
+ renderSlot(_ctx.$slots, "default", { page: layout })
149
147
  ], 4);
150
148
  }), 128))
151
149
  ], 4);
152
150
  }), 128))
153
151
  ], 4),
154
- layout.value.strategy === "horizontal" ? (openBlock(), createElementBlock("div", {
155
- key: 2,
156
- style: normalizeStyle({ width: layout.value.endSpacing + "px", height: "100%", flexShrink: 0 })
157
- }, null, 4)) : (openBlock(), createElementBlock("div", {
158
- key: 3,
159
- style: normalizeStyle({ height: layout.value.endSpacing + "px", width: "100%" })
160
- }, null, 4)),
161
- (openBlock(true), createElementBlock(Fragment, null, renderList(props.overlayElements, (el, i) => {
162
- return openBlock(), createBlock(resolveDynamicComponent(el), { key: i });
163
- }), 128))
152
+ createElementVNode("div", {
153
+ style: normalizeStyle(
154
+ scrollerLayout.value.strategy === unref(ScrollStrategy).Horizontal ? {
155
+ width: `${scrollerLayout.value.endSpacing}px`,
156
+ height: "100%",
157
+ flexShrink: 0
158
+ } : {
159
+ height: `${scrollerLayout.value.endSpacing}px`,
160
+ width: "100%"
161
+ }
162
+ )
163
+ }, null, 4)
164
164
  ], 16)) : createCommentVNode("", true);
165
165
  };
166
166
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/vue/hooks/use-scroll.ts","../../src/vue/components/scroller.vue"],"sourcesContent":["import { ref, watchEffect, computed } from 'vue';\nimport { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { ScrollPlugin } from '@embedpdf/plugin-scroll';\n\nexport const useScrollPlugin = () => usePlugin<ScrollPlugin>(ScrollPlugin.id);\nexport const useScrollCapability = () => useCapability<ScrollPlugin>(ScrollPlugin.id);\n\nexport function useScroll() {\n const { provides } = useScrollCapability();\n\n const currentPage = ref(1);\n const totalPages = ref(1);\n\n watchEffect((onCleanup) => {\n if (!provides.value) return;\n\n const unsubscribe = provides.value.onPageChange(({ pageNumber, totalPages: tp }) => {\n currentPage.value = pageNumber;\n totalPages.value = tp;\n });\n onCleanup(unsubscribe);\n });\n\n // New format\n const state = computed(() => ({\n currentPage: currentPage.value,\n totalPages: totalPages.value,\n }));\n\n // Create deprecated properties with warnings\n const deprecatedCurrentPage = computed({\n get() {\n console.warn(\n `Accessing 'currentPage' directly on useScroll() is deprecated. Use useScroll().state.currentPage instead.`,\n );\n return currentPage.value;\n },\n set(value) {\n currentPage.value = value;\n },\n });\n\n const deprecatedTotalPages = computed({\n get() {\n console.warn(\n `Accessing 'totalPages' directly on useScroll() is deprecated. Use useScroll().state.totalPages instead.`,\n );\n return totalPages.value;\n },\n set(value) {\n totalPages.value = value;\n },\n });\n\n const deprecatedScroll = computed(() => {\n if (provides.value) {\n console.warn(\n `Accessing 'scroll' directly on useScroll() is deprecated. Use useScroll().provides instead.`,\n );\n }\n return provides.value;\n });\n\n return {\n // New format (preferred)\n provides,\n state,\n\n // Deprecated properties (for backward compatibility)\n currentPage: deprecatedCurrentPage,\n totalPages: deprecatedTotalPages,\n scroll: deprecatedScroll,\n };\n}\n","<script setup lang=\"ts\">\n/* ------------------------------------------------------------------ */\n/* imports */\n/* ------------------------------------------------------------------ */\nimport { computed, onMounted, ref, watchEffect, useAttrs } from 'vue';\nimport type { StyleValue } from 'vue';\n\nimport { useScrollPlugin } from '../hooks';\nimport { ScrollStrategy, type ScrollerLayout, type PageLayout } from '@embedpdf/plugin-scroll';\nimport { useRegistry } from '@embedpdf/core/vue';\nimport { RenderPageProps } from '../../shared/types';\n\n/* ------------------------------------------------------------------ */\n/* props – pure layout; page content comes from the *slot* */\n/* ------------------------------------------------------------------ */\nconst props = withDefaults(\n defineProps<{\n style?: StyleValue;\n overlayElements?: any[];\n }>(),\n { overlayElements: () => [] },\n);\n\nconst attrs = useAttrs();\n\n/* ------------------------------------------------------------------ */\n/* plugin + reactive state */\n/* ------------------------------------------------------------------ */\nconst { plugin: scrollPlugin } = useScrollPlugin();\nconst { registry } = useRegistry(); // shallowRef<PluginRegistry|null>\n\nconst layout = ref<ScrollerLayout | null>(null);\n\n/* subscribe to scroller‑layout updates */\nwatchEffect((onCleanup) => {\n if (!scrollPlugin.value) return;\n\n layout.value = scrollPlugin.value.getScrollerLayout();\n const off = scrollPlugin.value.onScrollerData((l) => (layout.value = l));\n onCleanup(off);\n});\n\n/* inform plugin once the DOM is ready */\nonMounted(() => {\n scrollPlugin.value?.setLayoutReady();\n});\n\n/** Build the prop object that we’ll forward into the default slot */\nfunction pageSlotProps(pl: PageLayout): RenderPageProps {\n const core = registry.value!.getStore().getState().core;\n return {\n ...pl,\n rotation: core.rotation,\n scale: core.scale,\n document: core.document,\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* computed root style */\n/* ------------------------------------------------------------------ */\nconst rootStyle = computed<StyleValue>(() => {\n if (!layout.value) return props.style;\n\n const base =\n typeof props.style === 'object' && !Array.isArray(props.style)\n ? { ...props.style }\n : (props.style ?? {});\n\n return [\n base,\n {\n width: `${layout.value.totalWidth}px`,\n height: `${layout.value.totalHeight}px`,\n position: 'relative',\n boxSizing: 'border-box',\n margin: '0 auto',\n ...(layout.value.strategy === ScrollStrategy.Horizontal && {\n display: 'flex',\n flexDirection: 'row',\n }),\n },\n ];\n});\n</script>\n\n<template>\n <!-- render nothing until both layout + registry exist -->\n <div v-if=\"layout && registry\" :style=\"rootStyle\" v-bind=\"attrs\">\n <!-- leading spacer -->\n <div\n v-if=\"layout.strategy === 'horizontal'\"\n :style=\"{ width: layout.startSpacing + 'px', height: '100%', flexShrink: 0 }\"\n />\n <div v-else :style=\"{ height: layout.startSpacing + 'px', width: '100%' }\" />\n\n <!-- actual page grid -->\n <div\n :style=\"{\n gap: layout.pageGap + 'px',\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n flexDirection: layout.strategy === 'horizontal' ? 'row' : 'column',\n minHeight: layout.strategy === 'horizontal' ? '100%' : undefined,\n minWidth: layout.strategy === 'vertical' ? 'fit-content' : undefined,\n }\"\n >\n <template v-for=\"item in layout.items\" :key=\"item.pageNumbers[0]\">\n <div :style=\"{ display: 'flex', justifyContent: 'center', gap: layout.pageGap + 'px' }\">\n <div\n v-for=\"pl in item.pageLayouts\"\n :key=\"pl.pageNumber\"\n :style=\"{ width: pl.rotatedWidth + 'px', height: pl.rotatedHeight + 'px' }\"\n >\n <!-- 🔑 give the host app full control over page content -->\n <slot :page=\"pageSlotProps(pl)\" />\n </div>\n </div>\n </template>\n </div>\n\n <!-- trailing spacer -->\n <div\n v-if=\"layout.strategy === 'horizontal'\"\n :style=\"{ width: layout.endSpacing + 'px', height: '100%', flexShrink: 0 }\"\n />\n <div v-else :style=\"{ height: layout.endSpacing + 'px', width: '100%' }\" />\n\n <!-- optional overlay components -->\n <component v-for=\"(el, i) in props.overlayElements\" :is=\"el\" :key=\"i\" />\n </div>\n</template>\n"],"names":["_unref","_openBlock","_createElementBlock","_mergeProps","_normalizeStyle","_createElementVNode","_Fragment","_renderList","_renderSlot","_createBlock","_resolveDynamicComponent"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/vue/hooks/use-scroll.ts","../../src/vue/components/scroller.vue"],"sourcesContent":["import { ref, watch, computed, toValue, type MaybeRefOrGetter, type ComputedRef } from 'vue';\nimport { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { ScrollPlugin, ScrollScope } from '@embedpdf/plugin-scroll';\n\nexport const useScrollPlugin = () => usePlugin<ScrollPlugin>(ScrollPlugin.id);\nexport const useScrollCapability = () => useCapability<ScrollPlugin>(ScrollPlugin.id);\n\n// Define the return type explicitly to maintain type safety\ninterface UseScrollReturn {\n provides: ComputedRef<ScrollScope | null>;\n state: ComputedRef<{\n currentPage: number;\n totalPages: number;\n }>;\n}\n\n/**\n * Hook for scroll state for a specific document\n * @param documentId Document ID (can be ref, computed, getter, or plain value)\n */\nexport function useScroll(documentId: MaybeRefOrGetter<string>): UseScrollReturn {\n const { provides } = useScrollCapability();\n\n const currentPage = ref(1);\n const totalPages = ref(1);\n\n watch(\n [provides, () => toValue(documentId)],\n ([providesValue, docId], _, onCleanup) => {\n if (!providesValue || !docId) {\n currentPage.value = 1;\n totalPages.value = 1;\n return;\n }\n\n const scope = providesValue.forDocument(docId);\n\n // Get initial state\n currentPage.value = scope.getCurrentPage();\n totalPages.value = scope.getTotalPages();\n\n const unsubscribe = providesValue.onPageChange((event) => {\n if (event.documentId === docId) {\n currentPage.value = event.pageNumber;\n totalPages.value = event.totalPages;\n }\n });\n\n onCleanup(unsubscribe);\n },\n { immediate: true },\n );\n\n const state = computed(() => ({\n currentPage: currentPage.value,\n totalPages: totalPages.value,\n }));\n\n // Return a computed ref for the scoped capability\n const scopedProvides = computed(() => {\n const docId = toValue(documentId);\n return provides.value?.forDocument(docId) ?? null;\n });\n\n return {\n provides: scopedProvides,\n state,\n };\n}\n","<script setup lang=\"ts\">\nimport { ref, watch, computed } from 'vue';\nimport { useScrollPlugin } from '../hooks';\nimport { ScrollStrategy, type ScrollerLayout } from '@embedpdf/plugin-scroll';\n\ninterface ScrollerProps {\n documentId: string;\n}\n\nconst props = defineProps<ScrollerProps>();\n\nconst { plugin: scrollPlugin } = useScrollPlugin();\n\nconst layoutData = ref<{\n layout: ScrollerLayout | null;\n docId: string | null;\n}>({ layout: null, docId: null });\n\nwatch(\n [scrollPlugin, () => props.documentId],\n ([plugin, docId], _, onCleanup) => {\n if (!plugin || !docId) {\n layoutData.value = { layout: null, docId: null };\n return;\n }\n\n // Subscribe to the new document\n const unsubscribe = plugin.onScrollerData(docId, (newLayout) => {\n layoutData.value = { layout: newLayout, docId };\n });\n\n onCleanup(() => {\n unsubscribe();\n layoutData.value = { layout: null, docId: null };\n plugin.clearLayoutReady(docId);\n });\n },\n {\n immediate: true,\n },\n);\n\n// Only use layout if it matches the current documentId (prevents stale data)\nconst scrollerLayout = computed(() => {\n return layoutData.value.docId === props.documentId ? layoutData.value.layout : null;\n});\n\n// Call setLayoutReady after layout is rendered (Vue's equivalent to useLayoutEffect)\nwatch(\n [scrollPlugin, () => props.documentId, scrollerLayout],\n ([plugin, docId, layout]) => {\n if (!plugin || !docId || !layout) return;\n\n plugin.setLayoutReady(docId);\n },\n { immediate: true },\n);\n</script>\n\n<template>\n <div\n v-if=\"scrollerLayout\"\n :style=\"{\n width: `${scrollerLayout.totalWidth}px`,\n height: `${scrollerLayout.totalHeight}px`,\n position: 'relative',\n boxSizing: 'border-box',\n margin: '0 auto',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal && {\n display: 'flex',\n flexDirection: 'row',\n }),\n }\"\n v-bind=\"$attrs\"\n >\n <!-- Leading spacer -->\n <div\n :style=\"\n scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: `${scrollerLayout.startSpacing}px`,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: `${scrollerLayout.startSpacing}px`,\n width: '100%',\n }\n \"\n />\n\n <!-- Page grid -->\n <div\n :style=\"{\n gap: `${scrollerLayout.pageGap}px`,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n flexDirection: 'row',\n minHeight: '100%',\n }\n : {\n flexDirection: 'column',\n minWidth: 'fit-content',\n }),\n }\"\n >\n <div\n v-for=\"item in scrollerLayout.items\"\n :key=\"item.pageNumbers[0]\"\n :style=\"{\n display: 'flex',\n justifyContent: 'center',\n gap: `${scrollerLayout.pageGap}px`,\n }\"\n >\n <div\n v-for=\"layout in item.pageLayouts\"\n :key=\"layout.pageNumber\"\n :style=\"{\n width: `${layout.rotatedWidth}px`,\n height: `${layout.rotatedHeight}px`,\n }\"\n >\n <slot :page=\"layout\" />\n </div>\n </div>\n </div>\n\n <!-- Trailing spacer -->\n <div\n :style=\"\n scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: `${scrollerLayout.endSpacing}px`,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: `${scrollerLayout.endSpacing}px`,\n width: '100%',\n }\n \"\n />\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_mergeProps","_unref","$attrs","_createElementVNode","_normalizeStyle","_Fragment","_renderList","_renderSlot"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embedpdf/plugin-scroll",
3
- "version": "1.5.0",
3
+ "version": "2.0.0-next.1",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.cjs",
@@ -35,14 +35,15 @@
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
- "@embedpdf/models": "1.5.0"
38
+ "@embedpdf/models": "2.0.0-next.1"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/react": "^18.2.0",
42
42
  "typescript": "^5.0.0",
43
43
  "@embedpdf/build": "1.1.0",
44
- "@embedpdf/core": "1.5.0",
45
- "@embedpdf/plugin-viewport": "1.5.0"
44
+ "@embedpdf/core": "2.0.0-next.1",
45
+ "@embedpdf/plugin-spread": "2.0.0-next.1",
46
+ "@embedpdf/plugin-viewport": "2.0.0-next.1"
46
47
  },
47
48
  "peerDependencies": {
48
49
  "preact": "^10.26.4",
@@ -50,8 +51,8 @@
50
51
  "react-dom": ">=16.8.0",
51
52
  "vue": ">=3.2.0",
52
53
  "svelte": ">=5 <6",
53
- "@embedpdf/plugin-viewport": "1.5.0",
54
- "@embedpdf/core": "1.5.0"
54
+ "@embedpdf/core": "2.0.0-next.1",
55
+ "@embedpdf/plugin-viewport": "2.0.0-next.1"
55
56
  },
56
57
  "files": [
57
58
  "dist",