fumadocs-ui 16.7.13 → 16.7.15
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/css/generated/shared.css +13 -3
- package/dist/components/toc/clerk.js +55 -46
- package/dist/components/toc/default.js +17 -7
- package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/Controlled.d.ts +36 -0
- package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/Controlled.js +435 -0
- package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/Uncontrolled.d.ts +7 -0
- package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/Uncontrolled.js +17 -0
- package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/icons.js +24 -0
- package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/index.d.ts +2 -0
- package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/utils.js +372 -0
- package/dist/provider/base.d.ts +13 -12
- package/dist/provider/base.js +2 -2
- package/dist/style.css +8 -2
- package/package.json +8 -12
package/css/generated/shared.css
CHANGED
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
@source inline("--color-fd-muted");
|
|
21
21
|
@source inline("--fd-animated-height");
|
|
22
22
|
@source inline("--fd-banner-height");
|
|
23
|
+
@source inline("--offset-distance");
|
|
24
|
+
@source inline("--opacity");
|
|
23
25
|
@source inline("--padding-right");
|
|
24
26
|
@source inline("--radix-navigation-menu-viewport-height");
|
|
25
27
|
@source inline("--radix-popover-content-available-height");
|
|
@@ -29,6 +31,8 @@
|
|
|
29
31
|
@source inline("--shiki-light-bg");
|
|
30
32
|
@source inline("--spacing");
|
|
31
33
|
@source inline("--t");
|
|
34
|
+
@source inline("--track-bottom");
|
|
35
|
+
@source inline("--track-top");
|
|
32
36
|
@source inline("-circle");
|
|
33
37
|
@source inline("-mb-px");
|
|
34
38
|
@source inline("-me-0.5");
|
|
@@ -69,6 +73,7 @@
|
|
|
69
73
|
@source inline("[&_svg]:size-5");
|
|
70
74
|
@source inline("[&_svg]:size-full");
|
|
71
75
|
@source inline("[&_svg]:text-fd-muted-foreground");
|
|
76
|
+
@source inline("[offset-distance:var(--offset-distance,0)]");
|
|
72
77
|
@source inline("[scrollbar-width:none]");
|
|
73
78
|
@source inline("a");
|
|
74
79
|
@source inline("about");
|
|
@@ -160,6 +165,8 @@
|
|
|
160
165
|
@source inline("bottom-0");
|
|
161
166
|
@source inline("bottom-1.5");
|
|
162
167
|
@source inline("boundary");
|
|
168
|
+
@source inline("box");
|
|
169
|
+
@source inline("boxRef");
|
|
163
170
|
@source inline("breaking");
|
|
164
171
|
@source inline("button");
|
|
165
172
|
@source inline("buttonVariants");
|
|
@@ -682,7 +689,6 @@
|
|
|
682
689
|
@source inline("of");
|
|
683
690
|
@source inline("official");
|
|
684
691
|
@source inline("offset");
|
|
685
|
-
@source inline("offsetDistance");
|
|
686
692
|
@source inline("offsetPath");
|
|
687
693
|
@source inline("offsetTop");
|
|
688
694
|
@source inline("on");
|
|
@@ -705,8 +711,10 @@
|
|
|
705
711
|
@source inline("onSelectCallback");
|
|
706
712
|
@source inline("onTagChange");
|
|
707
713
|
@source inline("onTagChangeCallback");
|
|
714
|
+
@source inline("onUpdate");
|
|
708
715
|
@source inline("onValueChange");
|
|
709
716
|
@source inline("only");
|
|
717
|
+
@source inline("opacity-(--opacity,0)");
|
|
710
718
|
@source inline("opacity-0");
|
|
711
719
|
@source inline("open");
|
|
712
720
|
@source inline("opening");
|
|
@@ -821,6 +829,7 @@
|
|
|
821
829
|
@source inline("rainbowColors");
|
|
822
830
|
@source inline("raw");
|
|
823
831
|
@source inline("rawTree");
|
|
832
|
+
@source inline("re-exported");
|
|
824
833
|
@source inline("react");
|
|
825
834
|
@source inline("react-hooks/exhaustive-deps");
|
|
826
835
|
@source inline("react-hooks/rules-of-hooks");
|
|
@@ -874,7 +883,6 @@
|
|
|
874
883
|
@source inline("rtl:rotate-180");
|
|
875
884
|
@source inline("rtl:rotate-90");
|
|
876
885
|
@source inline("s");
|
|
877
|
-
@source inline("scale");
|
|
878
886
|
@source inline("scope");
|
|
879
887
|
@source inline("scroll");
|
|
880
888
|
@source inline("scroll-into-view-if-needed");
|
|
@@ -978,6 +986,7 @@
|
|
|
978
986
|
@source inline("supposed");
|
|
979
987
|
@source inline("sure");
|
|
980
988
|
@source inline("svg");
|
|
989
|
+
@source inline("svgRef");
|
|
981
990
|
@source inline("switch");
|
|
982
991
|
@source inline("system");
|
|
983
992
|
@source inline("t");
|
|
@@ -1033,6 +1042,7 @@
|
|
|
1033
1042
|
@source inline("title");
|
|
1034
1043
|
@source inline("to");
|
|
1035
1044
|
@source inline("toc");
|
|
1045
|
+
@source inline("tocInfo");
|
|
1036
1046
|
@source inline("tocNoHeadings");
|
|
1037
1047
|
@source inline("toolbar");
|
|
1038
1048
|
@source inline("top");
|
|
@@ -1048,7 +1058,7 @@
|
|
|
1048
1058
|
@source inline("transform");
|
|
1049
1059
|
@source inline("transition-[clip-path]");
|
|
1050
1060
|
@source inline("transition-[height]");
|
|
1051
|
-
@source inline("transition-[offset-distance]");
|
|
1061
|
+
@source inline("transition-[opacity,offset-distance]");
|
|
1052
1062
|
@source inline("transition-[width,height]");
|
|
1053
1063
|
@source inline("transition-all");
|
|
1054
1064
|
@source inline("transition-colors");
|
|
@@ -105,13 +105,9 @@ function TOCItems({ ref, className, thumbBox = true, ...props }) {
|
|
|
105
105
|
observer.unobserve(container);
|
|
106
106
|
};
|
|
107
107
|
}, [onPrint]);
|
|
108
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [svg && /* @__PURE__ */
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
width: svg.width,
|
|
112
|
-
height: svg.height
|
|
113
|
-
},
|
|
114
|
-
children: [/* @__PURE__ */ jsx(ThumbTrack, { computed: svg }), thumbBox && /* @__PURE__ */ jsx(ThumbBox, { computed: svg })]
|
|
108
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [svg && /* @__PURE__ */ jsx(ThumbTrack, {
|
|
109
|
+
computed: svg,
|
|
110
|
+
thumbBox
|
|
115
111
|
}), /* @__PURE__ */ jsx("div", {
|
|
116
112
|
ref: mergeRefs(containerRef, ref),
|
|
117
113
|
className: cn("flex flex-col", className),
|
|
@@ -125,48 +121,61 @@ function TOCEmpty() {
|
|
|
125
121
|
children: text.tocNoHeadings
|
|
126
122
|
});
|
|
127
123
|
}
|
|
128
|
-
function ThumbTrack({ computed }) {
|
|
129
|
-
const
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
124
|
+
function ThumbTrack({ computed, thumbBox }) {
|
|
125
|
+
const svgRef = useRef(null);
|
|
126
|
+
const boxRef = useRef(null);
|
|
127
|
+
const previousRef = useRef(null);
|
|
128
|
+
const tocInfo = Primitive.useTOC();
|
|
129
|
+
const onUpdate = useCallback((items) => {
|
|
130
|
+
const svg = svgRef.current;
|
|
131
|
+
if (!svg) return;
|
|
132
|
+
const startIdx = items.findIndex((item) => item.active);
|
|
133
|
+
if (startIdx === -1) return;
|
|
134
|
+
const endIdx = items.findLastIndex((item) => item.active);
|
|
135
|
+
svg.style.setProperty("--track-top", `${computed.positions[startIdx][0]}px`);
|
|
136
|
+
svg.style.setProperty("--track-bottom", `${computed.positions[endIdx][1]}px`);
|
|
137
|
+
const box = boxRef.current;
|
|
138
|
+
if (box) {
|
|
139
|
+
let isUp = false;
|
|
140
|
+
if (previousRef.current) {
|
|
141
|
+
const prev = previousRef.current;
|
|
142
|
+
isUp = prev.startIdx > startIdx || prev.endIdx > endIdx || prev.startIdx === startIdx && prev.endIdx === endIdx && prev.isUp;
|
|
143
|
+
}
|
|
144
|
+
previousRef.current = {
|
|
145
|
+
startIdx,
|
|
146
|
+
endIdx,
|
|
147
|
+
isUp
|
|
148
|
+
};
|
|
149
|
+
box.style.setProperty("--offset-distance", isUp ? `${computed.itemLineLengths[startIdx][0]}px` : `${computed.itemLineLengths[endIdx][1]}px`);
|
|
150
|
+
box.style.setProperty("--opacity", items[isUp ? startIdx : endIdx].original._step !== void 0 ? "0" : "1");
|
|
151
|
+
}
|
|
152
|
+
}, [computed]);
|
|
153
|
+
Primitive.useTOCListener(onUpdate);
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
onUpdate(tocInfo.get());
|
|
156
|
+
}, [onUpdate, tocInfo]);
|
|
157
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
158
|
+
className: "absolute top-0 inset-s-0",
|
|
139
159
|
style: {
|
|
140
160
|
width: computed.width,
|
|
141
|
-
height: computed.height
|
|
142
|
-
clipPath: `polygon(0 ${top}, 100% ${top}, 100% ${bottom}, 0 ${bottom})`
|
|
161
|
+
height: computed.height
|
|
143
162
|
},
|
|
144
|
-
children:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
endIdx,
|
|
161
|
-
isUp
|
|
162
|
-
};
|
|
163
|
-
return /* @__PURE__ */ jsx("div", {
|
|
164
|
-
className: "absolute size-1 bg-fd-primary rounded-full transition-[offset-distance]",
|
|
165
|
-
style: {
|
|
166
|
-
offsetPath: `path("${computed.d}")`,
|
|
167
|
-
offsetDistance: isUp ? computed.itemLineLengths[startIdx][0] : computed.itemLineLengths[endIdx][1],
|
|
168
|
-
scale: items[isUp ? startIdx : endIdx].original._step !== void 0 ? "0" : "1"
|
|
169
|
-
}
|
|
163
|
+
children: [/* @__PURE__ */ jsx("svg", {
|
|
164
|
+
ref: svgRef,
|
|
165
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
166
|
+
viewBox: `0 0 ${computed.width} ${computed.height}`,
|
|
167
|
+
className: "absolute transition-[clip-path]",
|
|
168
|
+
style: {
|
|
169
|
+
width: computed.width,
|
|
170
|
+
height: computed.height,
|
|
171
|
+
clipPath: `polygon(0 var(--track-top,0), 100% var(--track-top,0), 100% var(--track-bottom,0), 0 var(--track-bottom,0))`
|
|
172
|
+
},
|
|
173
|
+
children: computed.content
|
|
174
|
+
}), thumbBox && /* @__PURE__ */ jsx("div", {
|
|
175
|
+
ref: boxRef,
|
|
176
|
+
className: "absolute size-1 bg-fd-primary rounded-full [offset-distance:var(--offset-distance,0)] opacity-(--opacity,0) transition-[opacity,offset-distance]",
|
|
177
|
+
style: { offsetPath: `path("${computed.d}")` }
|
|
178
|
+
})]
|
|
170
179
|
});
|
|
171
180
|
}
|
|
172
181
|
const a = 8;
|
|
@@ -53,15 +53,25 @@ function TOCItems({ ref, className, ...props }) {
|
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
function TocThumb({ computed }) {
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
const ref = useRef(null);
|
|
57
|
+
const tocInfo = Primitive.useTOC();
|
|
58
|
+
const onUpdate = useCallback((items) => {
|
|
59
|
+
const element = ref.current;
|
|
60
|
+
if (!element) return;
|
|
61
|
+
const startIdx = items.findIndex((item) => item.active);
|
|
62
|
+
if (startIdx === -1) return;
|
|
63
|
+
const endIdx = items.findLastIndex((item) => item.active);
|
|
64
|
+
element.style.setProperty("--track-top", `${computed.positions[startIdx][0]}px`);
|
|
65
|
+
element.style.setProperty("--track-bottom", `${computed.positions[endIdx][1]}px`);
|
|
66
|
+
}, [computed]);
|
|
67
|
+
Primitive.useTOCListener(onUpdate);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
onUpdate(tocInfo.get());
|
|
70
|
+
}, [onUpdate, tocInfo]);
|
|
62
71
|
return /* @__PURE__ */ jsx("div", {
|
|
72
|
+
ref,
|
|
63
73
|
className: "absolute inset-y-0 inset-s-0 bg-fd-primary w-px transition-[clip-path]",
|
|
64
|
-
style: { clipPath: `polygon(0
|
|
74
|
+
style: { clipPath: `polygon(0 var(--track-top,0), 100% var(--track-top,0), 100% var(--track-bottom,0), 0 var(--track-bottom,0))` }
|
|
65
75
|
});
|
|
66
76
|
}
|
|
67
77
|
function TOCEmpty() {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/Controlled.d.ts
|
|
4
|
+
declare const enum ModalState {
|
|
5
|
+
LOADED = "LOADED",
|
|
6
|
+
LOADING = "LOADING",
|
|
7
|
+
UNLOADED = "UNLOADED",
|
|
8
|
+
UNLOADING = "UNLOADING"
|
|
9
|
+
}
|
|
10
|
+
interface ControlledProps {
|
|
11
|
+
a11yNameButtonUnzoom?: string;
|
|
12
|
+
a11yNameButtonZoom?: string;
|
|
13
|
+
canSwipeToUnzoom?: boolean;
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
classDialog?: string;
|
|
16
|
+
IconUnzoom?: React.ElementType;
|
|
17
|
+
IconZoom?: React.ElementType;
|
|
18
|
+
isDisabled?: boolean;
|
|
19
|
+
isZoomed: boolean;
|
|
20
|
+
onZoomChange?: (value: boolean, data: {
|
|
21
|
+
event: React.SyntheticEvent | Event;
|
|
22
|
+
}) => void;
|
|
23
|
+
swipeToUnzoomThreshold?: number;
|
|
24
|
+
wrapElement?: 'div' | 'span';
|
|
25
|
+
ZoomContent?: (data: {
|
|
26
|
+
buttonUnzoom: React.ReactElement<HTMLButtonElement>;
|
|
27
|
+
img: React.ReactElement | null;
|
|
28
|
+
isZoomImgLoaded: boolean;
|
|
29
|
+
modalState: ModalState;
|
|
30
|
+
onUnzoom: (e: Event) => void;
|
|
31
|
+
}) => React.ReactElement;
|
|
32
|
+
zoomImg?: React.ImgHTMLAttributes<HTMLImageElement>;
|
|
33
|
+
zoomMargin?: number;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { ControlledProps };
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import { ICompress, IEnlarge } from "./icons.js";
|
|
2
|
+
import { adjustSvgIDs, getImgAlt, getImgSrc, getStyleGhost, getStyleModalImg, testDiv, testImg, testImgLoaded, testSvg } from "./utils.js";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import ReactDOM from "react-dom";
|
|
5
|
+
//#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/Controlled.js
|
|
6
|
+
const IMAGE_QUERY = [
|
|
7
|
+
"img",
|
|
8
|
+
"svg",
|
|
9
|
+
"[role=\"img\"]",
|
|
10
|
+
"[data-zoom]"
|
|
11
|
+
].map((x) => `${x}:not([aria-hidden="true"])`).join(",");
|
|
12
|
+
const defaultBodyAttrs = {
|
|
13
|
+
overflow: "",
|
|
14
|
+
width: ""
|
|
15
|
+
};
|
|
16
|
+
function getDialogContainer() {
|
|
17
|
+
const existing = document.querySelector("[data-rmiz-portal]");
|
|
18
|
+
if (existing != null) return existing;
|
|
19
|
+
const el = document.createElement("div");
|
|
20
|
+
el.setAttribute("data-rmiz-portal", "");
|
|
21
|
+
document.body.appendChild(el);
|
|
22
|
+
return el;
|
|
23
|
+
}
|
|
24
|
+
function handleDialogCancelStatic(e) {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
}
|
|
27
|
+
function Controlled(props) {
|
|
28
|
+
return React.createElement(ControlledBase, { ...props });
|
|
29
|
+
}
|
|
30
|
+
var ControlledBase = class extends React.Component {
|
|
31
|
+
constructor() {
|
|
32
|
+
super(...arguments);
|
|
33
|
+
this.state = {
|
|
34
|
+
id: "",
|
|
35
|
+
isZoomImgLoaded: false,
|
|
36
|
+
loadedImgEl: void 0,
|
|
37
|
+
modalState: "UNLOADED",
|
|
38
|
+
shouldRefresh: false,
|
|
39
|
+
styleGhost: {}
|
|
40
|
+
};
|
|
41
|
+
this.refContent = React.createRef();
|
|
42
|
+
this.refDialog = React.createRef();
|
|
43
|
+
this.refModalContent = React.createRef();
|
|
44
|
+
this.refModalImg = React.createRef();
|
|
45
|
+
this.refWrap = React.createRef();
|
|
46
|
+
this.imgEl = null;
|
|
47
|
+
this.isScaling = false;
|
|
48
|
+
this.prevBodyAttrs = defaultBodyAttrs;
|
|
49
|
+
this.styleModalImg = {};
|
|
50
|
+
this.handleModalStateChange = (prevModalState) => {
|
|
51
|
+
const { state: { modalState } } = this;
|
|
52
|
+
if (prevModalState !== "LOADING" && modalState === "LOADING") {
|
|
53
|
+
this.loadZoomImg();
|
|
54
|
+
window.addEventListener("resize", this.handleResize, { passive: true });
|
|
55
|
+
window.addEventListener("touchstart", this.handleTouchStart, { passive: true });
|
|
56
|
+
window.addEventListener("touchmove", this.handleTouchMove, { passive: true });
|
|
57
|
+
window.addEventListener("touchend", this.handleTouchEnd, { passive: true });
|
|
58
|
+
window.addEventListener("touchcancel", this.handleTouchCancel, { passive: true });
|
|
59
|
+
document.addEventListener("keydown", this.handleKeyDown, true);
|
|
60
|
+
} else if (prevModalState !== "LOADED" && modalState === "LOADED") window.addEventListener("wheel", this.handleWheel, { passive: true });
|
|
61
|
+
else if (prevModalState !== "UNLOADING" && modalState === "UNLOADING") {
|
|
62
|
+
this.ensureImgTransitionEnd();
|
|
63
|
+
window.removeEventListener("wheel", this.handleWheel);
|
|
64
|
+
window.removeEventListener("touchstart", this.handleTouchStart);
|
|
65
|
+
window.removeEventListener("touchmove", this.handleTouchMove);
|
|
66
|
+
window.removeEventListener("touchend", this.handleTouchEnd);
|
|
67
|
+
window.removeEventListener("touchcancel", this.handleTouchCancel);
|
|
68
|
+
document.removeEventListener("keydown", this.handleKeyDown, true);
|
|
69
|
+
} else if (prevModalState !== "UNLOADED" && modalState === "UNLOADED") {
|
|
70
|
+
this.bodyScrollEnable();
|
|
71
|
+
window.removeEventListener("resize", this.handleResize);
|
|
72
|
+
this.refModalImg.current?.removeEventListener("transitionend", this.handleImgTransitionEnd);
|
|
73
|
+
this.refDialog.current?.close();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
this.setId = () => {
|
|
77
|
+
const gen4 = () => Math.random().toString(16).slice(-4);
|
|
78
|
+
this.setState({ id: gen4() + gen4() + gen4() });
|
|
79
|
+
};
|
|
80
|
+
this.setAndTrackImg = () => {
|
|
81
|
+
const { refContent: { current: contentEl } } = this;
|
|
82
|
+
if (contentEl == null) return;
|
|
83
|
+
this.imgEl = contentEl.querySelector(IMAGE_QUERY);
|
|
84
|
+
if (this.imgEl !== null) {
|
|
85
|
+
this.contentNotFoundChangeObserver?.disconnect();
|
|
86
|
+
this.imgEl.addEventListener("load", this.handleImgLoad);
|
|
87
|
+
this.imgEl.addEventListener("click", this.handleZoom);
|
|
88
|
+
if (this.state.loadedImgEl == null) this.handleImgLoad();
|
|
89
|
+
this.imgElResizeObserver = new ResizeObserver((entries) => {
|
|
90
|
+
const [entry] = entries;
|
|
91
|
+
if (entry?.target !== void 0) {
|
|
92
|
+
this.imgEl = entry.target;
|
|
93
|
+
this.setState({ styleGhost: getStyleGhost(this.imgEl) });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
this.imgElResizeObserver.observe(this.imgEl);
|
|
97
|
+
if (this.contentChangeObserver == null) {
|
|
98
|
+
this.contentChangeObserver = new MutationObserver(() => {
|
|
99
|
+
this.setState({ styleGhost: getStyleGhost(this.imgEl) });
|
|
100
|
+
});
|
|
101
|
+
this.contentChangeObserver.observe(contentEl, {
|
|
102
|
+
attributes: true,
|
|
103
|
+
childList: true,
|
|
104
|
+
subtree: true
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
} else if (this.contentNotFoundChangeObserver == null) {
|
|
108
|
+
this.contentNotFoundChangeObserver = new MutationObserver(this.setAndTrackImg);
|
|
109
|
+
this.contentNotFoundChangeObserver.observe(contentEl, {
|
|
110
|
+
childList: true,
|
|
111
|
+
subtree: true
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
this.handleIfZoomChanged = (prevIsZoomed) => {
|
|
116
|
+
const { props: { isZoomed } } = this;
|
|
117
|
+
if (!prevIsZoomed && isZoomed) this.zoom();
|
|
118
|
+
else if (prevIsZoomed && !isZoomed) this.unzoom();
|
|
119
|
+
};
|
|
120
|
+
this.handleImgLoad = () => {
|
|
121
|
+
const imgSrc = getImgSrc(this.imgEl);
|
|
122
|
+
if (imgSrc == null || imgSrc === "") return;
|
|
123
|
+
const img = new Image();
|
|
124
|
+
const { imgEl } = this;
|
|
125
|
+
if (testImg(imgEl)) {
|
|
126
|
+
const { sizes, srcset, crossOrigin } = imgEl;
|
|
127
|
+
img.sizes = sizes;
|
|
128
|
+
img.srcset = srcset;
|
|
129
|
+
img.crossOrigin = crossOrigin;
|
|
130
|
+
}
|
|
131
|
+
img.src = imgSrc;
|
|
132
|
+
const setLoaded = () => {
|
|
133
|
+
this.setState({
|
|
134
|
+
loadedImgEl: img,
|
|
135
|
+
styleGhost: getStyleGhost(this.imgEl)
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
img.decode().then(setLoaded).catch(() => {
|
|
139
|
+
if (testImgLoaded(img)) {
|
|
140
|
+
setLoaded();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
img.onload = setLoaded;
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
this.handleZoom = (e) => {
|
|
147
|
+
if (this.props.isDisabled !== true && this.hasImage()) this.props.onZoomChange?.(true, { event: e });
|
|
148
|
+
};
|
|
149
|
+
this.handleUnzoom = (e) => {
|
|
150
|
+
if (this.props.isDisabled !== true) this.props.onZoomChange?.(false, { event: e });
|
|
151
|
+
};
|
|
152
|
+
this.handleBtnUnzoomClick = (e) => {
|
|
153
|
+
e.preventDefault();
|
|
154
|
+
e.stopPropagation();
|
|
155
|
+
this.handleUnzoom(e);
|
|
156
|
+
};
|
|
157
|
+
this.handleDialogClick = (e) => {
|
|
158
|
+
if (e.target === this.refModalContent.current || e.target === this.refModalImg.current) {
|
|
159
|
+
e.stopPropagation();
|
|
160
|
+
this.handleUnzoom(e);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
this.handleDialogClose = (e) => {
|
|
164
|
+
e.stopPropagation();
|
|
165
|
+
this.handleUnzoom(e);
|
|
166
|
+
};
|
|
167
|
+
this.handleKeyDown = (e) => {
|
|
168
|
+
if (e.key === "Escape") {
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
e.stopPropagation();
|
|
171
|
+
this.handleUnzoom(e);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
this.handleWheel = (e) => {
|
|
175
|
+
if (e.ctrlKey) return;
|
|
176
|
+
e.stopPropagation();
|
|
177
|
+
queueMicrotask(() => {
|
|
178
|
+
this.handleUnzoom(e);
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
this.handleTouchStart = (e) => {
|
|
182
|
+
if (e.touches.length > 1) {
|
|
183
|
+
this.isScaling = true;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const { changedTouches } = e;
|
|
187
|
+
const [changedTouch] = changedTouches;
|
|
188
|
+
if (changedTouches.length === 1 && changedTouch !== void 0) {
|
|
189
|
+
const { screenY } = changedTouch;
|
|
190
|
+
this.touchYStart = screenY;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
this.handleTouchMove = (e) => {
|
|
194
|
+
const browserScale = window.visualViewport?.scale ?? 1;
|
|
195
|
+
const { changedTouches: changedTouchesMove } = e;
|
|
196
|
+
const [changedTouchMove] = changedTouchesMove;
|
|
197
|
+
if (this.props.canSwipeToUnzoom && !this.isScaling && browserScale <= 1 && this.touchYStart != null && changedTouchMove !== void 0) {
|
|
198
|
+
const { screenY } = changedTouchMove;
|
|
199
|
+
this.touchYEnd = screenY;
|
|
200
|
+
const max = Math.max(this.touchYStart, this.touchYEnd);
|
|
201
|
+
const min = Math.min(this.touchYStart, this.touchYEnd);
|
|
202
|
+
if (Math.abs(max - min) > this.props.swipeToUnzoomThreshold) {
|
|
203
|
+
this.touchYStart = void 0;
|
|
204
|
+
this.touchYEnd = void 0;
|
|
205
|
+
this.handleUnzoom(e);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
this.handleTouchEnd = () => {
|
|
210
|
+
this.isScaling = false;
|
|
211
|
+
this.touchYStart = void 0;
|
|
212
|
+
this.touchYEnd = void 0;
|
|
213
|
+
};
|
|
214
|
+
this.handleTouchCancel = () => {
|
|
215
|
+
this.isScaling = false;
|
|
216
|
+
this.touchYStart = void 0;
|
|
217
|
+
this.touchYEnd = void 0;
|
|
218
|
+
};
|
|
219
|
+
this.handleResize = () => {
|
|
220
|
+
this.setState({ shouldRefresh: true });
|
|
221
|
+
};
|
|
222
|
+
this.hasImage = () => this.imgEl !== null && (this.state.loadedImgEl !== void 0 || testSvg(this.imgEl)) && window.getComputedStyle(this.imgEl).display !== "none";
|
|
223
|
+
this.zoom = () => {
|
|
224
|
+
this.bodyScrollDisable();
|
|
225
|
+
this.refDialog.current?.showModal();
|
|
226
|
+
this.refModalImg.current?.addEventListener("transitionend", this.handleImgTransitionEnd);
|
|
227
|
+
this.setState({ modalState: "LOADING" });
|
|
228
|
+
};
|
|
229
|
+
this.unzoom = () => {
|
|
230
|
+
this.setState({ modalState: "UNLOADING" });
|
|
231
|
+
};
|
|
232
|
+
this.handleImgTransitionEnd = () => {
|
|
233
|
+
clearTimeout(this.timeoutTransitionEnd);
|
|
234
|
+
if (this.state.modalState === "LOADING") this.setState({ modalState: "LOADED" });
|
|
235
|
+
else if (this.state.modalState === "UNLOADING") this.setState({
|
|
236
|
+
shouldRefresh: false,
|
|
237
|
+
modalState: "UNLOADED"
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
this.ensureImgTransitionEnd = () => {
|
|
241
|
+
if (this.refModalImg.current !== null) {
|
|
242
|
+
const { transitionDuration: td } = window.getComputedStyle(this.refModalImg.current);
|
|
243
|
+
const tdFloat = parseFloat(td);
|
|
244
|
+
if (tdFloat !== 0 && !Number.isNaN(tdFloat)) {
|
|
245
|
+
const tdMs = tdFloat * (td.endsWith("ms") ? 1 : 1e3) + 50;
|
|
246
|
+
this.timeoutTransitionEnd = setTimeout(this.handleImgTransitionEnd, tdMs);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
this.bodyScrollDisable = () => {
|
|
251
|
+
this.prevBodyAttrs = {
|
|
252
|
+
overflow: document.body.style.overflow,
|
|
253
|
+
width: document.body.style.width
|
|
254
|
+
};
|
|
255
|
+
const { body: { clientWidth } } = document;
|
|
256
|
+
document.body.style.overflow = "hidden";
|
|
257
|
+
document.body.style.width = `${clientWidth}px`;
|
|
258
|
+
};
|
|
259
|
+
this.bodyScrollEnable = () => {
|
|
260
|
+
const { prevBodyAttrs: { overflow, width } } = this;
|
|
261
|
+
document.body.style.width = width;
|
|
262
|
+
document.body.style.overflow = overflow;
|
|
263
|
+
this.prevBodyAttrs = defaultBodyAttrs;
|
|
264
|
+
};
|
|
265
|
+
this.loadZoomImg = () => {
|
|
266
|
+
const { props: { zoomImg } } = this;
|
|
267
|
+
if (zoomImg == null) return;
|
|
268
|
+
const { src: zoomImgSrc } = zoomImg;
|
|
269
|
+
if (zoomImgSrc !== void 0 && zoomImgSrc !== "") {
|
|
270
|
+
const img = new Image();
|
|
271
|
+
img.sizes = zoomImg.sizes ?? "";
|
|
272
|
+
img.srcset = zoomImg.srcSet ?? "";
|
|
273
|
+
img.crossOrigin = zoomImg.crossOrigin ?? void 0;
|
|
274
|
+
img.src = zoomImgSrc;
|
|
275
|
+
const setLoaded = () => {
|
|
276
|
+
this.setState({ isZoomImgLoaded: true });
|
|
277
|
+
};
|
|
278
|
+
img.decode().then(setLoaded).catch(() => {
|
|
279
|
+
if (testImgLoaded(img)) {
|
|
280
|
+
setLoaded();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
img.onload = setLoaded;
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
this.UNSAFE_handleSvg = () => {
|
|
288
|
+
const { imgEl, refModalImg, styleModalImg } = this;
|
|
289
|
+
if (testSvg(imgEl)) {
|
|
290
|
+
const svgEl = imgEl.cloneNode(true);
|
|
291
|
+
adjustSvgIDs(svgEl);
|
|
292
|
+
svgEl.style.width = `${styleModalImg.width ?? 0}px`;
|
|
293
|
+
svgEl.style.height = `${styleModalImg.height ?? 0}px`;
|
|
294
|
+
svgEl.addEventListener("click", this.handleUnzoom);
|
|
295
|
+
refModalImg.current?.firstChild?.remove();
|
|
296
|
+
refModalImg.current?.appendChild(svgEl);
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
render() {
|
|
301
|
+
const { handleBtnUnzoomClick, handleDialogClick, handleDialogClose, handleUnzoom, handleZoom, imgEl, props: { a11yNameButtonUnzoom, a11yNameButtonZoom, children, classDialog, IconUnzoom, IconZoom, isZoomed, wrapElement: WrapElement, ZoomContent, zoomImg, zoomMargin }, refContent, refDialog, refModalContent, refModalImg, refWrap, state: { id, isZoomImgLoaded, loadedImgEl, modalState, shouldRefresh, styleGhost } } = this;
|
|
302
|
+
const idModal = `rmiz-modal-${id}`;
|
|
303
|
+
const idModalImg = `rmiz-modal-img-${id}`;
|
|
304
|
+
const isDiv = testDiv(imgEl);
|
|
305
|
+
const isImg = testImg(imgEl);
|
|
306
|
+
const isSvg = testSvg(imgEl);
|
|
307
|
+
const imgAlt = getImgAlt(imgEl);
|
|
308
|
+
const imgSrc = getImgSrc(imgEl);
|
|
309
|
+
const imgSizes = isImg ? imgEl.sizes : void 0;
|
|
310
|
+
const imgSrcSet = isImg ? imgEl.srcset : void 0;
|
|
311
|
+
const imgCrossOrigin = isImg ? imgEl.crossOrigin : void 0;
|
|
312
|
+
const hasZoomImg = zoomImg?.src !== void 0 && zoomImg.src !== "";
|
|
313
|
+
const hasImage = this.hasImage();
|
|
314
|
+
const labelBtnZoom = imgAlt !== void 0 && imgAlt !== "" ? `${a11yNameButtonZoom}: ${imgAlt}` : a11yNameButtonZoom;
|
|
315
|
+
const isModalActive = modalState === "LOADING" || modalState === "LOADED";
|
|
316
|
+
const dataContentState = hasImage ? "found" : "not-found";
|
|
317
|
+
const dataOverlayState = modalState === "UNLOADED" || modalState === "UNLOADING" ? "hidden" : "visible";
|
|
318
|
+
const styleContent = { visibility: modalState === "UNLOADED" ? "visible" : "hidden" };
|
|
319
|
+
this.styleModalImg = hasImage && imgEl !== null ? getStyleModalImg({
|
|
320
|
+
hasZoomImg,
|
|
321
|
+
imgSrc,
|
|
322
|
+
isSvg,
|
|
323
|
+
isZoomed: isZoomed && isModalActive,
|
|
324
|
+
loadedImgEl,
|
|
325
|
+
offset: zoomMargin,
|
|
326
|
+
shouldRefresh,
|
|
327
|
+
targetEl: imgEl
|
|
328
|
+
}) : {};
|
|
329
|
+
let modalContent = null;
|
|
330
|
+
if (hasImage) {
|
|
331
|
+
const modalImg = isImg || isDiv ? React.createElement("img", {
|
|
332
|
+
alt: imgAlt,
|
|
333
|
+
crossOrigin: imgCrossOrigin,
|
|
334
|
+
sizes: imgSizes,
|
|
335
|
+
src: imgSrc,
|
|
336
|
+
srcSet: imgSrcSet,
|
|
337
|
+
...isZoomImgLoaded && modalState === "LOADED" ? zoomImg : {},
|
|
338
|
+
"data-rmiz-modal-img": "",
|
|
339
|
+
height: this.styleModalImg.height ?? void 0,
|
|
340
|
+
id: idModalImg,
|
|
341
|
+
ref: refModalImg,
|
|
342
|
+
style: this.styleModalImg,
|
|
343
|
+
width: this.styleModalImg.width ?? void 0
|
|
344
|
+
}) : isSvg ? React.createElement("div", {
|
|
345
|
+
"data-rmiz-modal-img": true,
|
|
346
|
+
ref: refModalImg,
|
|
347
|
+
style: this.styleModalImg
|
|
348
|
+
}) : null;
|
|
349
|
+
const modalBtnUnzoom = React.createElement("button", {
|
|
350
|
+
"aria-label": a11yNameButtonUnzoom,
|
|
351
|
+
"data-rmiz-btn-unzoom": "",
|
|
352
|
+
onClick: handleBtnUnzoomClick,
|
|
353
|
+
type: "button"
|
|
354
|
+
}, React.createElement(IconUnzoom, null));
|
|
355
|
+
modalContent = ZoomContent == null ? React.createElement(React.Fragment, null, modalImg, modalBtnUnzoom) : React.createElement(ZoomContent, {
|
|
356
|
+
buttonUnzoom: modalBtnUnzoom,
|
|
357
|
+
modalState,
|
|
358
|
+
img: modalImg,
|
|
359
|
+
isZoomImgLoaded,
|
|
360
|
+
onUnzoom: handleUnzoom
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
return React.createElement(WrapElement, {
|
|
364
|
+
"aria-owns": idModal,
|
|
365
|
+
"data-rmiz": "",
|
|
366
|
+
ref: refWrap
|
|
367
|
+
}, React.createElement(WrapElement, {
|
|
368
|
+
"data-rmiz-content": dataContentState,
|
|
369
|
+
ref: refContent,
|
|
370
|
+
style: styleContent
|
|
371
|
+
}, children), hasImage && React.createElement(WrapElement, {
|
|
372
|
+
"data-rmiz-ghost": "",
|
|
373
|
+
style: styleGhost
|
|
374
|
+
}, React.createElement("button", {
|
|
375
|
+
"aria-label": labelBtnZoom,
|
|
376
|
+
"data-rmiz-btn-zoom": "",
|
|
377
|
+
onClick: handleZoom,
|
|
378
|
+
type: "button"
|
|
379
|
+
}, React.createElement(IconZoom, null))), hasImage && ReactDOM.createPortal(React.createElement("dialog", {
|
|
380
|
+
"aria-labelledby": idModalImg,
|
|
381
|
+
"aria-modal": "true",
|
|
382
|
+
className: classDialog,
|
|
383
|
+
"data-rmiz-modal": "",
|
|
384
|
+
id: idModal,
|
|
385
|
+
onClick: handleDialogClick,
|
|
386
|
+
onClose: handleDialogClose,
|
|
387
|
+
onCancel: handleDialogCancelStatic,
|
|
388
|
+
ref: refDialog,
|
|
389
|
+
role: "dialog"
|
|
390
|
+
}, React.createElement("div", { "data-rmiz-modal-overlay": dataOverlayState }), React.createElement("div", {
|
|
391
|
+
"data-rmiz-modal-content": "",
|
|
392
|
+
ref: refModalContent
|
|
393
|
+
}, modalContent)), getDialogContainer()));
|
|
394
|
+
}
|
|
395
|
+
componentDidMount() {
|
|
396
|
+
this.setId();
|
|
397
|
+
this.setAndTrackImg();
|
|
398
|
+
this.handleImgLoad();
|
|
399
|
+
this.UNSAFE_handleSvg();
|
|
400
|
+
}
|
|
401
|
+
componentWillUnmount() {
|
|
402
|
+
if (this.state.modalState !== "UNLOADED") this.bodyScrollEnable();
|
|
403
|
+
this.contentChangeObserver?.disconnect();
|
|
404
|
+
this.contentNotFoundChangeObserver?.disconnect();
|
|
405
|
+
this.imgElResizeObserver?.disconnect();
|
|
406
|
+
this.imgEl?.removeEventListener("load", this.handleImgLoad);
|
|
407
|
+
this.imgEl?.removeEventListener("click", this.handleZoom);
|
|
408
|
+
this.refModalImg.current?.removeEventListener("transitionend", this.handleImgTransitionEnd);
|
|
409
|
+
window.removeEventListener("wheel", this.handleWheel);
|
|
410
|
+
window.removeEventListener("touchstart", this.handleTouchStart);
|
|
411
|
+
window.removeEventListener("touchmove", this.handleTouchMove);
|
|
412
|
+
window.removeEventListener("touchend", this.handleTouchEnd);
|
|
413
|
+
window.removeEventListener("touchcancel", this.handleTouchCancel);
|
|
414
|
+
window.removeEventListener("resize", this.handleResize);
|
|
415
|
+
document.removeEventListener("keydown", this.handleKeyDown, true);
|
|
416
|
+
}
|
|
417
|
+
componentDidUpdate(prevProps, prevState) {
|
|
418
|
+
this.handleModalStateChange(prevState.modalState);
|
|
419
|
+
this.UNSAFE_handleSvg();
|
|
420
|
+
this.handleIfZoomChanged(prevProps.isZoomed);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
ControlledBase.defaultProps = {
|
|
424
|
+
a11yNameButtonUnzoom: "Minimize image",
|
|
425
|
+
a11yNameButtonZoom: "Expand image",
|
|
426
|
+
canSwipeToUnzoom: true,
|
|
427
|
+
IconUnzoom: ICompress,
|
|
428
|
+
IconZoom: IEnlarge,
|
|
429
|
+
isDisabled: false,
|
|
430
|
+
swipeToUnzoomThreshold: 10,
|
|
431
|
+
wrapElement: "div",
|
|
432
|
+
zoomMargin: 0
|
|
433
|
+
};
|
|
434
|
+
//#endregion
|
|
435
|
+
export { Controlled };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ControlledProps } from "./Controlled.js";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
//#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/Uncontrolled.d.ts
|
|
5
|
+
type UncontrolledProps = Omit<ControlledProps, 'isZoomed'>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { UncontrolledProps };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Controlled } from "./Controlled.js";
|
|
2
|
+
import React from "react";
|
|
3
|
+
//#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/Uncontrolled.js
|
|
4
|
+
function Uncontrolled({ onZoomChange, ...props }) {
|
|
5
|
+
const [isZoomed, setIsZoomed] = React.useState(false);
|
|
6
|
+
const handleZoomChange = React.useCallback((value, { event }) => {
|
|
7
|
+
setIsZoomed(value);
|
|
8
|
+
onZoomChange?.(value, { event });
|
|
9
|
+
}, [onZoomChange]);
|
|
10
|
+
return React.createElement(Controlled, {
|
|
11
|
+
...props,
|
|
12
|
+
isZoomed,
|
|
13
|
+
onZoomChange: handleZoomChange
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { Uncontrolled };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
//#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/icons.js
|
|
3
|
+
function ICompress() {
|
|
4
|
+
return React.createElement("svg", {
|
|
5
|
+
"aria-hidden": "true",
|
|
6
|
+
"data-rmiz-btn-unzoom-icon": true,
|
|
7
|
+
fill: "currentColor",
|
|
8
|
+
focusable: "false",
|
|
9
|
+
viewBox: "0 0 16 16",
|
|
10
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
11
|
+
}, React.createElement("path", { d: "M 14.144531 1.148438 L 9 6.292969 L 9 3 L 8 3 L 8 8 L 13 8 L 13 7 L 9.707031 7 L 14.855469 1.851563 Z M 8 8 L 3 8 L 3 9 L 6.292969 9 L 1.148438 14.144531 L 1.851563 14.855469 L 7 9.707031 L 7 13 L 8 13 Z" }));
|
|
12
|
+
}
|
|
13
|
+
function IEnlarge() {
|
|
14
|
+
return React.createElement("svg", {
|
|
15
|
+
"aria-hidden": "true",
|
|
16
|
+
"data-rmiz-btn-zoom-icon": true,
|
|
17
|
+
fill: "currentColor",
|
|
18
|
+
focusable: "false",
|
|
19
|
+
viewBox: "0 0 16 16",
|
|
20
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
21
|
+
}, React.createElement("path", { d: "M 9 1 L 9 2 L 12.292969 2 L 2 12.292969 L 2 9 L 1 9 L 1 14 L 6 14 L 6 13 L 2.707031 13 L 13 2.707031 L 13 6 L 14 6 L 14 1 Z" }));
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ICompress, IEnlarge };
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
//#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.3_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/react-medium-image-zoom/dist/utils.js
|
|
2
|
+
function isElement(el) {
|
|
3
|
+
if (typeof Element === "undefined") return false;
|
|
4
|
+
return el instanceof Element;
|
|
5
|
+
}
|
|
6
|
+
const testElType = (type, el) => isElement(el) && el.tagName.toUpperCase() === type;
|
|
7
|
+
const testDiv = (el) => testElType("DIV", el) || testElType("SPAN", el);
|
|
8
|
+
const testImg = (el) => testElType("IMG", el);
|
|
9
|
+
const testImgLoaded = (el) => el.complete && el.naturalHeight !== 0;
|
|
10
|
+
const testSvg = (el) => testElType("SVG", el);
|
|
11
|
+
const getScaleToWindow = ({ height, offset, width }) => Math.min((window.innerWidth - offset * 2) / width, (window.innerHeight - offset * 2) / height);
|
|
12
|
+
const getScaleToWindowMax = ({ containerHeight, containerWidth, offset, targetHeight, targetWidth }) => {
|
|
13
|
+
const scale = getScaleToWindow({
|
|
14
|
+
height: targetHeight,
|
|
15
|
+
offset,
|
|
16
|
+
width: targetWidth
|
|
17
|
+
});
|
|
18
|
+
const ratio = targetWidth > targetHeight ? targetWidth / containerWidth : targetHeight / containerHeight;
|
|
19
|
+
return scale > 1 ? ratio : scale * ratio;
|
|
20
|
+
};
|
|
21
|
+
const getScale = ({ containerHeight, containerWidth, hasScalableSrc, offset, targetHeight, targetWidth }) => {
|
|
22
|
+
if (containerHeight === 0 || containerWidth === 0) return 1;
|
|
23
|
+
return !hasScalableSrc && targetHeight !== 0 && targetWidth !== 0 ? getScaleToWindowMax({
|
|
24
|
+
containerHeight,
|
|
25
|
+
containerWidth,
|
|
26
|
+
offset,
|
|
27
|
+
targetHeight,
|
|
28
|
+
targetWidth
|
|
29
|
+
}) : getScaleToWindow({
|
|
30
|
+
height: containerHeight,
|
|
31
|
+
offset,
|
|
32
|
+
width: containerWidth
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
const URL_REGEX = /url(?:\(['"]?)(?<url>.*?)(?:['"]?\))/;
|
|
36
|
+
const getImgSrc = (imgEl) => {
|
|
37
|
+
if (imgEl !== null) {
|
|
38
|
+
if (testImg(imgEl)) return imgEl.currentSrc === "" ? void 0 : imgEl.currentSrc;
|
|
39
|
+
else if (testDiv(imgEl)) {
|
|
40
|
+
const { backgroundImage: bgImg } = window.getComputedStyle(imgEl);
|
|
41
|
+
if (bgImg !== "") return URL_REGEX.exec(bgImg)?.[1];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const getImgAlt = (imgEl) => {
|
|
46
|
+
if (imgEl !== null) if (testImg(imgEl)) return imgEl.alt;
|
|
47
|
+
else return imgEl.getAttribute("aria-label") ?? void 0;
|
|
48
|
+
};
|
|
49
|
+
const getImgRegularStyle = ({ containerHeight, containerLeft, containerTop, containerWidth, hasScalableSrc, offset, targetHeight, targetWidth }) => {
|
|
50
|
+
const scale = getScale({
|
|
51
|
+
containerHeight,
|
|
52
|
+
containerWidth,
|
|
53
|
+
hasScalableSrc,
|
|
54
|
+
offset,
|
|
55
|
+
targetHeight,
|
|
56
|
+
targetWidth
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
top: containerTop,
|
|
60
|
+
left: containerLeft,
|
|
61
|
+
width: containerWidth * scale,
|
|
62
|
+
height: containerHeight * scale,
|
|
63
|
+
transform: `translate(0,0) scale(${1 / scale})`
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
const parsePosition = ({ position, relativeNum }) => {
|
|
67
|
+
const positionNum = parseFloat(position);
|
|
68
|
+
return position.endsWith("%") ? relativeNum * positionNum / 100 : positionNum;
|
|
69
|
+
};
|
|
70
|
+
const getImgObjectFitStyle = ({ containerHeight, containerLeft, containerTop, containerWidth, hasScalableSrc, objectFit: objectFitParam, objectPosition, offset, targetHeight, targetWidth }) => {
|
|
71
|
+
let resolvedObjectFit = objectFitParam;
|
|
72
|
+
if (resolvedObjectFit === "scale-down") if (targetWidth <= containerWidth && targetHeight <= containerHeight) resolvedObjectFit = "none";
|
|
73
|
+
else resolvedObjectFit = "contain";
|
|
74
|
+
if (resolvedObjectFit === "cover" || resolvedObjectFit === "contain") {
|
|
75
|
+
const widthRatio = containerWidth / targetWidth;
|
|
76
|
+
const heightRatio = containerHeight / targetHeight;
|
|
77
|
+
const ratio = resolvedObjectFit === "cover" ? Math.max(widthRatio, heightRatio) : Math.min(widthRatio, heightRatio);
|
|
78
|
+
const [posLeft = "50%", posTop = "50%"] = objectPosition.split(" ");
|
|
79
|
+
const posX = parsePosition({
|
|
80
|
+
position: posLeft,
|
|
81
|
+
relativeNum: containerWidth - targetWidth * ratio
|
|
82
|
+
});
|
|
83
|
+
const posY = parsePosition({
|
|
84
|
+
position: posTop,
|
|
85
|
+
relativeNum: containerHeight - targetHeight * ratio
|
|
86
|
+
});
|
|
87
|
+
const scale = getScale({
|
|
88
|
+
containerHeight: targetHeight * ratio,
|
|
89
|
+
containerWidth: targetWidth * ratio,
|
|
90
|
+
hasScalableSrc,
|
|
91
|
+
offset,
|
|
92
|
+
targetHeight,
|
|
93
|
+
targetWidth
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
top: containerTop + posY,
|
|
97
|
+
left: containerLeft + posX,
|
|
98
|
+
width: targetWidth * ratio * scale,
|
|
99
|
+
height: targetHeight * ratio * scale,
|
|
100
|
+
transform: `translate(0,0) scale(${1 / scale})`
|
|
101
|
+
};
|
|
102
|
+
} else if (resolvedObjectFit === "none") {
|
|
103
|
+
const [posLeft = "50%", posTop = "50%"] = objectPosition.split(" ");
|
|
104
|
+
const posX = parsePosition({
|
|
105
|
+
position: posLeft,
|
|
106
|
+
relativeNum: containerWidth - targetWidth
|
|
107
|
+
});
|
|
108
|
+
const posY = parsePosition({
|
|
109
|
+
position: posTop,
|
|
110
|
+
relativeNum: containerHeight - targetHeight
|
|
111
|
+
});
|
|
112
|
+
const scale = getScale({
|
|
113
|
+
containerHeight: targetHeight,
|
|
114
|
+
containerWidth: targetWidth,
|
|
115
|
+
hasScalableSrc,
|
|
116
|
+
offset,
|
|
117
|
+
targetHeight,
|
|
118
|
+
targetWidth
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
top: containerTop + posY,
|
|
122
|
+
left: containerLeft + posX,
|
|
123
|
+
width: targetWidth * scale,
|
|
124
|
+
height: targetHeight * scale,
|
|
125
|
+
transform: `translate(0,0) scale(${1 / scale})`
|
|
126
|
+
};
|
|
127
|
+
} else if (resolvedObjectFit === "fill") {
|
|
128
|
+
const widthRatio = containerWidth / targetWidth;
|
|
129
|
+
const heightRatio = containerHeight / targetHeight;
|
|
130
|
+
const ratio = Math.max(widthRatio, heightRatio);
|
|
131
|
+
const scale = getScale({
|
|
132
|
+
containerHeight: targetHeight * ratio,
|
|
133
|
+
containerWidth: targetWidth * ratio,
|
|
134
|
+
hasScalableSrc,
|
|
135
|
+
offset,
|
|
136
|
+
targetHeight,
|
|
137
|
+
targetWidth
|
|
138
|
+
});
|
|
139
|
+
return {
|
|
140
|
+
width: containerWidth * scale,
|
|
141
|
+
height: containerHeight * scale,
|
|
142
|
+
transform: `translate(0,0) scale(${1 / scale})`
|
|
143
|
+
};
|
|
144
|
+
} else return {};
|
|
145
|
+
};
|
|
146
|
+
const getDivImgStyle = ({ backgroundPosition, backgroundSize, containerHeight, containerLeft, containerTop, containerWidth, hasScalableSrc, offset, targetHeight, targetWidth }) => {
|
|
147
|
+
if (backgroundSize === "cover" || backgroundSize === "contain") {
|
|
148
|
+
const widthRatio = containerWidth / targetWidth;
|
|
149
|
+
const heightRatio = containerHeight / targetHeight;
|
|
150
|
+
const ratio = backgroundSize === "cover" ? Math.max(widthRatio, heightRatio) : Math.min(widthRatio, heightRatio);
|
|
151
|
+
const [posLeft = "50%", posTop = "50%"] = backgroundPosition.split(" ");
|
|
152
|
+
const posX = parsePosition({
|
|
153
|
+
position: posLeft,
|
|
154
|
+
relativeNum: containerWidth - targetWidth * ratio
|
|
155
|
+
});
|
|
156
|
+
const posY = parsePosition({
|
|
157
|
+
position: posTop,
|
|
158
|
+
relativeNum: containerHeight - targetHeight * ratio
|
|
159
|
+
});
|
|
160
|
+
const scale = getScale({
|
|
161
|
+
containerHeight: targetHeight * ratio,
|
|
162
|
+
containerWidth: targetWidth * ratio,
|
|
163
|
+
hasScalableSrc,
|
|
164
|
+
offset,
|
|
165
|
+
targetHeight,
|
|
166
|
+
targetWidth
|
|
167
|
+
});
|
|
168
|
+
return {
|
|
169
|
+
top: containerTop + posY,
|
|
170
|
+
left: containerLeft + posX,
|
|
171
|
+
width: targetWidth * ratio * scale,
|
|
172
|
+
height: targetHeight * ratio * scale,
|
|
173
|
+
transform: `translate(0,0) scale(${1 / scale})`
|
|
174
|
+
};
|
|
175
|
+
} else if (backgroundSize === "auto") {
|
|
176
|
+
const [posLeft = "50%", posTop = "50%"] = backgroundPosition.split(" ");
|
|
177
|
+
const posX = parsePosition({
|
|
178
|
+
position: posLeft,
|
|
179
|
+
relativeNum: containerWidth - targetWidth
|
|
180
|
+
});
|
|
181
|
+
const posY = parsePosition({
|
|
182
|
+
position: posTop,
|
|
183
|
+
relativeNum: containerHeight - targetHeight
|
|
184
|
+
});
|
|
185
|
+
const scale = getScale({
|
|
186
|
+
containerHeight: targetHeight,
|
|
187
|
+
containerWidth: targetWidth,
|
|
188
|
+
hasScalableSrc,
|
|
189
|
+
offset,
|
|
190
|
+
targetHeight,
|
|
191
|
+
targetWidth
|
|
192
|
+
});
|
|
193
|
+
return {
|
|
194
|
+
top: containerTop + posY,
|
|
195
|
+
left: containerLeft + posX,
|
|
196
|
+
width: targetWidth * scale,
|
|
197
|
+
height: targetHeight * scale,
|
|
198
|
+
transform: `translate(0,0) scale(${1 / scale})`
|
|
199
|
+
};
|
|
200
|
+
} else {
|
|
201
|
+
const [sizeW = "50%", sizeH = "50%"] = backgroundSize.split(" ");
|
|
202
|
+
const sizeWidth = parsePosition({
|
|
203
|
+
position: sizeW,
|
|
204
|
+
relativeNum: containerWidth
|
|
205
|
+
});
|
|
206
|
+
const sizeHeight = parsePosition({
|
|
207
|
+
position: sizeH,
|
|
208
|
+
relativeNum: containerHeight
|
|
209
|
+
});
|
|
210
|
+
const widthRatio = sizeWidth / targetWidth;
|
|
211
|
+
const heightRatio = sizeHeight / targetHeight;
|
|
212
|
+
const ratio = Math.min(widthRatio, heightRatio);
|
|
213
|
+
const [posLeft = "50%", posTop = "50%"] = backgroundPosition.split(" ");
|
|
214
|
+
const posX = parsePosition({
|
|
215
|
+
position: posLeft,
|
|
216
|
+
relativeNum: containerWidth - targetWidth * ratio
|
|
217
|
+
});
|
|
218
|
+
const posY = parsePosition({
|
|
219
|
+
position: posTop,
|
|
220
|
+
relativeNum: containerHeight - targetHeight * ratio
|
|
221
|
+
});
|
|
222
|
+
const scale = getScale({
|
|
223
|
+
containerHeight: targetHeight * ratio,
|
|
224
|
+
containerWidth: targetWidth * ratio,
|
|
225
|
+
hasScalableSrc,
|
|
226
|
+
offset,
|
|
227
|
+
targetHeight,
|
|
228
|
+
targetWidth
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
top: containerTop + posY,
|
|
232
|
+
left: containerLeft + posX,
|
|
233
|
+
width: targetWidth * ratio * scale,
|
|
234
|
+
height: targetHeight * ratio * scale,
|
|
235
|
+
transform: `translate(0,0) scale(${1 / scale})`
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
const SRC_SVG_REGEX = /\.svg$/i;
|
|
240
|
+
const getStyleModalImg = ({ hasZoomImg, imgSrc, isSvg, isZoomed, loadedImgEl, offset, shouldRefresh, targetEl }) => {
|
|
241
|
+
const hasScalableSrc = isSvg || imgSrc?.slice(0, 18) === "data:image/svg+xml" || hasZoomImg || imgSrc !== void 0 && SRC_SVG_REGEX.test(imgSrc);
|
|
242
|
+
const imgRect = targetEl.getBoundingClientRect();
|
|
243
|
+
const targetElComputedStyle = window.getComputedStyle(targetEl);
|
|
244
|
+
const isDivImg = loadedImgEl != null && testDiv(targetEl);
|
|
245
|
+
const isImgObjectFit = loadedImgEl != null && !isDivImg;
|
|
246
|
+
const targetHeight = loadedImgEl != null && loadedImgEl.naturalHeight !== 0 ? loadedImgEl.naturalHeight : imgRect.height;
|
|
247
|
+
const targetWidth = loadedImgEl != null && loadedImgEl.naturalWidth !== 0 ? loadedImgEl.naturalWidth : imgRect.width;
|
|
248
|
+
const styleImgRegular = getImgRegularStyle({
|
|
249
|
+
containerHeight: imgRect.height,
|
|
250
|
+
containerLeft: imgRect.left,
|
|
251
|
+
containerTop: imgRect.top,
|
|
252
|
+
containerWidth: imgRect.width,
|
|
253
|
+
hasScalableSrc,
|
|
254
|
+
offset,
|
|
255
|
+
targetHeight,
|
|
256
|
+
targetWidth
|
|
257
|
+
});
|
|
258
|
+
const styleImgObjectFit = isImgObjectFit ? getImgObjectFitStyle({
|
|
259
|
+
containerHeight: imgRect.height,
|
|
260
|
+
containerLeft: imgRect.left,
|
|
261
|
+
containerTop: imgRect.top,
|
|
262
|
+
containerWidth: imgRect.width,
|
|
263
|
+
hasScalableSrc,
|
|
264
|
+
objectFit: targetElComputedStyle.objectFit,
|
|
265
|
+
objectPosition: targetElComputedStyle.objectPosition,
|
|
266
|
+
offset,
|
|
267
|
+
targetHeight,
|
|
268
|
+
targetWidth
|
|
269
|
+
}) : void 0;
|
|
270
|
+
const styleDivImg = isDivImg ? getDivImgStyle({
|
|
271
|
+
backgroundPosition: targetElComputedStyle.backgroundPosition,
|
|
272
|
+
backgroundSize: targetElComputedStyle.backgroundSize,
|
|
273
|
+
containerHeight: imgRect.height,
|
|
274
|
+
containerLeft: imgRect.left,
|
|
275
|
+
containerTop: imgRect.top,
|
|
276
|
+
containerWidth: imgRect.width,
|
|
277
|
+
hasScalableSrc,
|
|
278
|
+
offset,
|
|
279
|
+
targetHeight,
|
|
280
|
+
targetWidth
|
|
281
|
+
}) : void 0;
|
|
282
|
+
const style = {
|
|
283
|
+
...styleImgRegular,
|
|
284
|
+
...styleImgObjectFit,
|
|
285
|
+
...styleDivImg
|
|
286
|
+
};
|
|
287
|
+
if (isZoomed) {
|
|
288
|
+
const viewportX = window.innerWidth / 2;
|
|
289
|
+
const viewportY = window.innerHeight / 2;
|
|
290
|
+
const childCenterX = parseFloat(String(style.left ?? 0)) + parseFloat(String(style.width ?? 0)) / 2;
|
|
291
|
+
const childCenterY = parseFloat(String(style.top ?? 0)) + parseFloat(String(style.height ?? 0)) / 2;
|
|
292
|
+
const translateX = viewportX - childCenterX;
|
|
293
|
+
const translateY = viewportY - childCenterY;
|
|
294
|
+
if (shouldRefresh) style.transitionDuration = "0.01ms";
|
|
295
|
+
style.transform = `translate(${translateX}px,${translateY}px) scale(1)`;
|
|
296
|
+
}
|
|
297
|
+
return style;
|
|
298
|
+
};
|
|
299
|
+
const getStyleGhost = (imgEl) => {
|
|
300
|
+
if (imgEl == null) return {};
|
|
301
|
+
if (testSvg(imgEl)) {
|
|
302
|
+
const { parentElement: parentEl } = imgEl;
|
|
303
|
+
const rect = imgEl.getBoundingClientRect();
|
|
304
|
+
if (parentEl == null) return {
|
|
305
|
+
height: rect.height,
|
|
306
|
+
left: rect.left,
|
|
307
|
+
width: rect.width,
|
|
308
|
+
top: rect.top
|
|
309
|
+
};
|
|
310
|
+
else {
|
|
311
|
+
const parentRect = parentEl.getBoundingClientRect();
|
|
312
|
+
return {
|
|
313
|
+
height: rect.height,
|
|
314
|
+
left: parentRect.left - rect.left,
|
|
315
|
+
top: parentRect.top - rect.top,
|
|
316
|
+
width: rect.width
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
} else return {
|
|
320
|
+
height: imgEl.offsetHeight,
|
|
321
|
+
left: imgEl.offsetLeft,
|
|
322
|
+
width: imgEl.offsetWidth,
|
|
323
|
+
top: imgEl.offsetTop
|
|
324
|
+
};
|
|
325
|
+
};
|
|
326
|
+
const adjustSvgIDs = (svgEl) => {
|
|
327
|
+
const newIdSuffix = "-zoom";
|
|
328
|
+
const attrs = [
|
|
329
|
+
"clip-path",
|
|
330
|
+
"fill",
|
|
331
|
+
"mask",
|
|
332
|
+
"marker-start",
|
|
333
|
+
"marker-mid",
|
|
334
|
+
"marker-end"
|
|
335
|
+
];
|
|
336
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
337
|
+
if (svgEl.hasAttribute("id")) {
|
|
338
|
+
const { id: oldId } = svgEl;
|
|
339
|
+
const newId = oldId + newIdSuffix;
|
|
340
|
+
idMap.set(oldId, newId);
|
|
341
|
+
const svgNode = svgEl;
|
|
342
|
+
svgNode.id = newId;
|
|
343
|
+
}
|
|
344
|
+
svgEl.querySelectorAll("[id]").forEach((el) => {
|
|
345
|
+
const { id: oldId } = el;
|
|
346
|
+
const newId = oldId + newIdSuffix;
|
|
347
|
+
idMap.set(oldId, newId);
|
|
348
|
+
const node = el;
|
|
349
|
+
node.id = newId;
|
|
350
|
+
});
|
|
351
|
+
idMap.forEach((newId, oldId) => {
|
|
352
|
+
const urlOldID = `url(#${oldId})`;
|
|
353
|
+
const urlNewID = `url(#${newId})`;
|
|
354
|
+
const attrsQuery = attrs.map((attr) => `[${attr}="${urlOldID}"]`).join(", ");
|
|
355
|
+
svgEl.querySelectorAll(attrsQuery).forEach((usedEl) => {
|
|
356
|
+
attrs.forEach((attr) => {
|
|
357
|
+
if (usedEl.getAttribute(attr) === urlOldID) usedEl.setAttribute(attr, urlNewID);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
svgEl.querySelectorAll("style").forEach((styleEl) => {
|
|
362
|
+
idMap.forEach((newId, oldId) => {
|
|
363
|
+
const { textContent } = styleEl;
|
|
364
|
+
if (textContent !== "") {
|
|
365
|
+
const styleNode = styleEl;
|
|
366
|
+
styleNode.textContent = textContent.replaceAll(`#${oldId}`, `#${newId}`);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
//#endregion
|
|
372
|
+
export { adjustSvgIDs, getImgAlt, getImgSrc, getStyleGhost, getStyleModalImg, testDiv, testImg, testImgLoaded, testSvg };
|
package/dist/provider/base.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { SearchProviderProps } from "../contexts/search.js";
|
|
2
2
|
import { DefaultSearchDialogProps } from "../components/dialog/search-default.js";
|
|
3
3
|
import { I18nProviderProps } from "../contexts/i18n.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
5
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
6
|
-
import {
|
|
6
|
+
import { ThemeProviderProps, UseThemeProps, useTheme } from "next-themes";
|
|
7
7
|
|
|
8
8
|
//#region src/provider/base.d.ts
|
|
9
9
|
interface SearchOptions extends Omit<SearchProviderProps, 'options' | 'children'> {
|
|
@@ -15,6 +15,14 @@ interface SearchOptions extends Omit<SearchProviderProps, 'options' | 'children'
|
|
|
15
15
|
*/
|
|
16
16
|
enabled?: boolean;
|
|
17
17
|
}
|
|
18
|
+
interface ThemeOptions extends ThemeProviderProps {
|
|
19
|
+
/**
|
|
20
|
+
* Enable `next-themes`
|
|
21
|
+
*
|
|
22
|
+
* @defaultValue true
|
|
23
|
+
*/
|
|
24
|
+
enabled?: boolean;
|
|
25
|
+
}
|
|
18
26
|
interface RootProviderProps {
|
|
19
27
|
/**
|
|
20
28
|
* `dir` option for Radix UI
|
|
@@ -25,16 +33,9 @@ interface RootProviderProps {
|
|
|
25
33
|
*/
|
|
26
34
|
search?: Partial<SearchOptions>;
|
|
27
35
|
/**
|
|
28
|
-
* Customise options
|
|
36
|
+
* Customise options for `next-themes`
|
|
29
37
|
*/
|
|
30
|
-
theme?:
|
|
31
|
-
/**
|
|
32
|
-
* Enable `next-themes`
|
|
33
|
-
*
|
|
34
|
-
* @defaultValue true
|
|
35
|
-
*/
|
|
36
|
-
enabled?: boolean;
|
|
37
|
-
};
|
|
38
|
+
theme?: ThemeOptions;
|
|
38
39
|
i18n?: Omit<I18nProviderProps, 'children'>;
|
|
39
40
|
children?: ReactNode;
|
|
40
41
|
}
|
|
@@ -46,4 +47,4 @@ declare function RootProvider({
|
|
|
46
47
|
i18n
|
|
47
48
|
}: RootProviderProps): _$react_jsx_runtime0.JSX.Element;
|
|
48
49
|
//#endregion
|
|
49
|
-
export { RootProvider, RootProviderProps };
|
|
50
|
+
export { RootProvider, RootProviderProps, type UseThemeProps, useTheme };
|
package/dist/provider/base.js
CHANGED
|
@@ -3,7 +3,7 @@ import { I18nProvider } from "../contexts/i18n.js";
|
|
|
3
3
|
import { SearchProvider } from "../contexts/search.js";
|
|
4
4
|
import { lazy } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
|
-
import { ThemeProvider } from "next-themes";
|
|
6
|
+
import { ThemeProvider, useTheme } from "next-themes";
|
|
7
7
|
import { DirectionProvider } from "@radix-ui/react-direction";
|
|
8
8
|
//#region src/provider/base.tsx
|
|
9
9
|
const DefaultSearchDialog = lazy(() => import("../components/dialog/search-default.js"));
|
|
@@ -32,4 +32,4 @@ function RootProvider({ children, dir = "ltr", theme = {}, search, i18n }) {
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
//#endregion
|
|
35
|
-
export { RootProvider };
|
|
35
|
+
export { RootProvider, useTheme };
|
package/dist/style.css
CHANGED
|
@@ -1827,6 +1827,9 @@
|
|
|
1827
1827
|
.underline {
|
|
1828
1828
|
text-decoration-line: underline;
|
|
1829
1829
|
}
|
|
1830
|
+
.opacity-\(--opacity\,0\) {
|
|
1831
|
+
opacity: var(--opacity,0);
|
|
1832
|
+
}
|
|
1830
1833
|
.opacity-0 {
|
|
1831
1834
|
opacity: 0%;
|
|
1832
1835
|
}
|
|
@@ -1894,8 +1897,8 @@
|
|
|
1894
1897
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1895
1898
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1896
1899
|
}
|
|
1897
|
-
.transition-\[offset-distance\] {
|
|
1898
|
-
transition-property: offset-distance;
|
|
1900
|
+
.transition-\[opacity\,offset-distance\] {
|
|
1901
|
+
transition-property: opacity,offset-distance;
|
|
1899
1902
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
1900
1903
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
1901
1904
|
}
|
|
@@ -2000,6 +2003,9 @@
|
|
|
2000
2003
|
.\[grid-area\:toc\] {
|
|
2001
2004
|
grid-area: toc;
|
|
2002
2005
|
}
|
|
2006
|
+
.\[offset-distance\:var\(--offset-distance\,0\)\] {
|
|
2007
|
+
offset-distance: var(--offset-distance,0);
|
|
2008
|
+
}
|
|
2003
2009
|
.\[scrollbar-width\:none\] {
|
|
2004
2010
|
scrollbar-width: none;
|
|
2005
2011
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-ui",
|
|
3
|
-
"version": "16.7.
|
|
3
|
+
"version": "16.7.15",
|
|
4
4
|
"description": "The Radix UI version of Fumadocs UI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Docs",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"author": "Fuma Nama",
|
|
12
12
|
"repository": "github:fuma-nama/fumadocs",
|
|
13
13
|
"files": [
|
|
14
|
-
"css
|
|
15
|
-
"dist
|
|
14
|
+
"css",
|
|
15
|
+
"dist"
|
|
16
16
|
],
|
|
17
17
|
"type": "module",
|
|
18
18
|
"exports": {
|
|
@@ -141,9 +141,10 @@
|
|
|
141
141
|
"react-remove-scroll": "^2.7.2",
|
|
142
142
|
"rehype-raw": "^7.0.0",
|
|
143
143
|
"scroll-into-view-if-needed": "^3.1.0",
|
|
144
|
+
"shiki": "^4.0.2",
|
|
144
145
|
"tailwind-merge": "^3.5.0",
|
|
145
146
|
"unist-util-visit": "^5.1.0",
|
|
146
|
-
"@fumadocs/tailwind": "0.0.
|
|
147
|
+
"@fumadocs/tailwind": "0.0.5"
|
|
147
148
|
},
|
|
148
149
|
"devDependencies": {
|
|
149
150
|
"@tailwindcss/cli": "^4.2.2",
|
|
@@ -155,12 +156,11 @@
|
|
|
155
156
|
"@types/react-dom": "^19.2.3",
|
|
156
157
|
"fuma-cli": "^0.0.5",
|
|
157
158
|
"react-medium-image-zoom": "^5.4.3",
|
|
158
|
-
"shiki": "^4.0.2",
|
|
159
159
|
"tailwindcss": "^4.2.2",
|
|
160
160
|
"tsdown": "0.21.7",
|
|
161
161
|
"unified": "^11.0.5",
|
|
162
|
-
"@fumadocs/cli": "1.3.
|
|
163
|
-
"fumadocs-core": "16.7.
|
|
162
|
+
"@fumadocs/cli": "1.3.7",
|
|
163
|
+
"fumadocs-core": "16.7.15",
|
|
164
164
|
"tsconfig": "0.0.0"
|
|
165
165
|
},
|
|
166
166
|
"peerDependencies": {
|
|
@@ -170,16 +170,12 @@
|
|
|
170
170
|
"next": "16.x.x",
|
|
171
171
|
"react": "^19.2.0",
|
|
172
172
|
"react-dom": "^19.2.0",
|
|
173
|
-
"
|
|
174
|
-
"fumadocs-core": "16.7.13"
|
|
173
|
+
"fumadocs-core": "16.7.15"
|
|
175
174
|
},
|
|
176
175
|
"peerDependenciesMeta": {
|
|
177
176
|
"next": {
|
|
178
177
|
"optional": true
|
|
179
178
|
},
|
|
180
|
-
"shiki": {
|
|
181
|
-
"optional": true
|
|
182
|
-
},
|
|
183
179
|
"@takumi-rs/image-response": {
|
|
184
180
|
"optional": true
|
|
185
181
|
},
|