wimui 0.55.0 → 0.56.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.
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../Loader/Loader.cjs"),n=require("../Spinner/Spinner.cjs"),r=require("./loadingoverlay.module.cjs");let i=require("react");i=e.__toESM(i,1);let a=require("classnames");a=e.__toESM(a,1);let o=require("react/jsx-runtime");var s=({visible:e=!1,loaderType:i=`spinner`,loaderSize:s=`lg`,loaderColor:c=`primary`,backdropVariant:l=`dark`,blur:u=`sm`,message:d,fixed:f=!1,zIndex:p,children:m,className:h,style:g,..._})=>{if(!e)return null;let v=()=>m||(i===`spinner`?(0,o.jsx)(n.Spinner,{size:s,color:c}):(0,o.jsx)(t.Loader,{variant:i,size:s,color:c}));return(0,o.jsxs)(`div`,{className:(0,a.default)(`wim-loading-overlay`,r.default.root,f&&r.default.fixed,h),style:{...g,...p!==void 0&&{zIndex:p}},role:`status`,"data-testid":`loading-overlay`,"aria-live":`polite`,"aria-busy":`true`,..._,children:[(0,o.jsx)(`div`,{className:(0,a.default)(r.default.backdrop,r.default[l],r.default[`blur-${u}`])}),(0,o.jsxs)(`div`,{className:r.default.content,children:[v(),d&&(0,o.jsx)(`div`,{className:r.default.message,children:d})]})]})};exports.LoadingOverlay=s,exports.default=s;
2
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../i18n/useWimTranslation.cjs"),n=require("../../../i18n/generated/common.cjs"),r=require("../../layout/VisuallyHidden/VisuallyHidden.cjs"),i=require("../Loader/Loader.cjs"),a=require("../Spinner/Spinner.cjs"),o=require("./loadingoverlay.module.cjs");let s=require("react");s=e.__toESM(s,1);let c=require("classnames");c=e.__toESM(c,1);let l=require("react/jsx-runtime");var u=({visible:e=!1,loaderType:s=`spinner`,loaderSize:u=`lg`,loaderColor:d=`primary`,backdropVariant:f=`dark`,blur:p=`sm`,message:m,fixed:h=!1,zIndex:g,children:_,className:v,style:y,...b})=>{let{t:x}=t.useWimTranslation(n.commonNs);if(!e)return null;let S=()=>_||(s===`spinner`?(0,l.jsx)(a.Spinner,{size:u,color:d}):(0,l.jsx)(i.Loader,{variant:s,size:u,color:d}));return(0,l.jsxs)(`div`,{className:(0,c.default)(`wim-loading-overlay`,o.default.root,h&&o.default.fixed,v),style:{...y,...g!==void 0&&{zIndex:g}},role:`status`,"data-testid":`loading-overlay`,"aria-live":`polite`,"aria-busy":`true`,...b,children:[(0,l.jsx)(`div`,{className:(0,c.default)(o.default.backdrop,o.default[f],o.default[`blur-${p}`])}),(0,l.jsxs)(`div`,{className:o.default.content,children:[S(),m&&(0,l.jsx)(`div`,{className:o.default.message,children:m}),!m&&!_&&(0,l.jsx)(r.VisuallyHidden,{children:x(`a11y.loading`)})]})]})};exports.LoadingOverlay=u,exports.default=u;
@@ -37,7 +37,8 @@ export type LoadingOverlayProps = React.ComponentPropsWithoutRef<"div"> & {
37
37
  */
38
38
  blur?: "none" | "sm" | "md" | "lg";
39
39
  /**
40
- * Loading message displayed below the indicator.
40
+ * Loading message displayed below the indicator. Without a message (and without children),
41
+ * a built-in "Loading" text is read to assistive technology in its place.
41
42
  */
42
43
  message?: string;
43
44
  /**
@@ -1,40 +1,48 @@
1
1
  "use client";
2
- import { Loader as e } from "../Loader/Loader.js";
3
- import { Spinner as t } from "../Spinner/Spinner.js";
4
- import n from "./loadingoverlay.module.js";
2
+ import { useWimTranslation as e } from "../../../i18n/useWimTranslation.js";
3
+ import { commonNs as t } from "../../../i18n/generated/common.js";
4
+ import { VisuallyHidden as n } from "../../layout/VisuallyHidden/VisuallyHidden.js";
5
+ import { Loader as r } from "../Loader/Loader.js";
6
+ import { Spinner as i } from "../Spinner/Spinner.js";
7
+ import a from "./loadingoverlay.module.js";
5
8
  import "react";
6
- import r from "classnames";
7
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
9
+ import o from "classnames";
10
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
8
11
  //#region src/components/feedback/LoadingOverlay/LoadingOverlay.tsx
9
- var o = ({ visible: o = !1, loaderType: s = "spinner", loaderSize: c = "lg", loaderColor: l = "primary", backdropVariant: u = "dark", blur: d = "sm", message: f, fixed: p = !1, zIndex: m, children: h, className: g, style: _, ...v }) => {
10
- if (!o) return null;
11
- let y = () => h || (s === "spinner" ? /* @__PURE__ */ i(t, {
12
- size: c,
13
- color: l
14
- }) : /* @__PURE__ */ i(e, {
15
- variant: s,
16
- size: c,
17
- color: l
12
+ var l = ({ visible: l = !1, loaderType: u = "spinner", loaderSize: d = "lg", loaderColor: f = "primary", backdropVariant: p = "dark", blur: m = "sm", message: h, fixed: g = !1, zIndex: _, children: v, className: y, style: b, ...x }) => {
13
+ let { t: S } = e(t);
14
+ if (!l) return null;
15
+ let C = () => v || (u === "spinner" ? /* @__PURE__ */ s(i, {
16
+ size: d,
17
+ color: f
18
+ }) : /* @__PURE__ */ s(r, {
19
+ variant: u,
20
+ size: d,
21
+ color: f
18
22
  }));
19
- return /* @__PURE__ */ a("div", {
20
- className: r("wim-loading-overlay", n.root, p && n.fixed, g),
23
+ return /* @__PURE__ */ c("div", {
24
+ className: o("wim-loading-overlay", a.root, g && a.fixed, y),
21
25
  style: {
22
- ..._,
23
- ...m !== void 0 && { zIndex: m }
26
+ ...b,
27
+ ..._ !== void 0 && { zIndex: _ }
24
28
  },
25
29
  role: "status",
26
30
  "data-testid": "loading-overlay",
27
31
  "aria-live": "polite",
28
32
  "aria-busy": "true",
29
- ...v,
30
- children: [/* @__PURE__ */ i("div", { className: r(n.backdrop, n[u], n[`blur-${d}`]) }), /* @__PURE__ */ a("div", {
31
- className: n.content,
32
- children: [y(), f && /* @__PURE__ */ i("div", {
33
- className: n.message,
34
- children: f
35
- })]
33
+ ...x,
34
+ children: [/* @__PURE__ */ s("div", { className: o(a.backdrop, a[p], a[`blur-${m}`]) }), /* @__PURE__ */ c("div", {
35
+ className: a.content,
36
+ children: [
37
+ C(),
38
+ h && /* @__PURE__ */ s("div", {
39
+ className: a.message,
40
+ children: h
41
+ }),
42
+ !h && !v && /* @__PURE__ */ s(n, { children: S("a11y.loading") })
43
+ ]
36
44
  })]
37
45
  });
38
46
  };
39
47
  //#endregion
40
- export { o as LoadingOverlay, o as default };
48
+ export { l as LoadingOverlay, l as default };
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../i18n/useWimTranslation.cjs"),n=require("../../../i18n/generated/common.cjs"),r=require("../../layout/VisuallyHidden/VisuallyHidden.cjs"),i=require("../Button/Button.cjs"),a=require("../../../i18n/generated/form.cjs"),o=require("../Slider/Slider.cjs"),s=require("../IconButton/IconButton.cjs"),c=require("../../overlay/Dialog/Dialog.cjs"),l=require("./image-cropper.module.cjs");let u=require("react");u=e.__toESM(u,1);let d=require("classnames");d=e.__toESM(d,1);let f=require("react/jsx-runtime");var p=10,m=50,h=u.default.forwardRef(({src:e,aspectRatio:h=1,circular:g=!1,onCrop:_,showRotation:v=!0,showZoom:y=!0,showApplyButton:b=!0,applyLabel:x,onApply:S,className:C,...w},T)=>{let{t:E}=t.useWimTranslation([a.formNs,n.commonNs]),[D,O]=(0,u.useState)(1),[k,A]=(0,u.useState)(0),[j,M]=(0,u.useState)({x:0,y:0}),[N,P]=(0,u.useState)(!1),[F,I]=(0,u.useState)({x:0,y:0}),[L,R]=(0,u.useState)(!1),z=(0,u.useRef)(null),B=(0,u.useRef)(null),V=(0,u.useId)();(0,u.useEffect)(()=>{M({x:0,y:0}),O(1),A(0)},[e]);let H=e=>{P(!0),I({x:e.clientX-j.x,y:e.clientY-j.y})},U=(0,u.useCallback)(e=>{N&&M({x:e.clientX-F.x,y:e.clientY-F.y})},[N,F]),W=(0,u.useCallback)(()=>{P(!1)},[]);(0,u.useEffect)(()=>(N?(window.addEventListener(`mousemove`,U),window.addEventListener(`mouseup`,W)):(window.removeEventListener(`mousemove`,U),window.removeEventListener(`mouseup`,W)),()=>{window.removeEventListener(`mousemove`,U),window.removeEventListener(`mouseup`,W)}),[N,U,W]);let G=e=>{let t=e.shiftKey?m:p,n={ArrowLeft:[-t,0],ArrowRight:[t,0],ArrowUp:[0,-t],ArrowDown:[0,t]}[e.key];n?(e.preventDefault(),M(e=>({x:e.x+n[0],y:e.y+n[1]}))):e.key===`Home`&&(e.preventDefault(),M({x:0,y:0}))},K=()=>{A(e=>(e+90)%360)},q=()=>{R(!0)},J=()=>{let t=e||``;_?.(t),S?.(t),R(!1)};return e?(0,f.jsxs)(`div`,{ref:T,className:(0,d.default)(`wim-image-cropper`,l.default.root,C),...w,children:[(0,f.jsxs)(`div`,{ref:B,className:l.default.viewer,onMouseDown:H,onKeyDown:G,role:`application`,tabIndex:0,"aria-label":E(`image_cropper.position_label`),"aria-describedby":V,children:[(0,f.jsx)(r.VisuallyHidden,{id:V,children:E(`image_cropper.position_hint`)}),(0,f.jsx)(`div`,{className:l.default.imageContainer,children:(0,f.jsx)(`img`,{ref:z,src:e,alt:E(`a11y.crop_target`),className:l.default.image,style:{transform:`translate(${j.x}px, ${j.y}px) rotate(${k}deg) scale(${D})`},draggable:!1})}),(0,f.jsx)(`div`,{className:l.default.overlay,children:(0,f.jsx)(`div`,{className:(0,d.default)(l.default.cropArea,{[l.default.circular]:g}),style:{aspectRatio:h}})})]}),(0,f.jsxs)(`div`,{className:l.default.controls,children:[y&&(0,f.jsx)(`div`,{className:l.default.zoomControl,children:(0,f.jsx)(o.Slider,{min:1,max:3,step:.1,value:D,onChange:e=>O(e),label:E(`image_cropper.zoom`),styles:{root:l.default.zoomSlider}})}),v&&(0,f.jsx)(`div`,{className:l.default.rotationControl,children:(0,f.jsx)(s.IconButton,{iconName:`RefreshIcon`,onClick:K,"aria-label":E(`image_cropper.rotate`),variant:`outline`,size:`sm`})}),b&&(0,f.jsx)(`div`,{className:l.default.applyControl,children:(0,f.jsx)(i.Button,{onClick:q,size:`sm`,variant:`solid`,children:x||E(`image_cropper.apply`)})})]}),(0,f.jsx)(c.Dialog,{open:L,onOpenChange:R,children:(0,f.jsxs)(c.DialogContent,{children:[(0,f.jsx)(c.DialogHeader,{children:(0,f.jsx)(c.DialogTitle,{children:E(`image_cropper.confirm_title`)})}),(0,f.jsx)(c.DialogDescription,{children:E(`image_cropper.confirm_message`)}),(0,f.jsxs)(c.DialogFooter,{children:[(0,f.jsx)(c.DialogClose,{asChild:!0,children:(0,f.jsx)(i.Button,{variant:`ghost`,children:E(`image_cropper.cancel`)})}),(0,f.jsx)(i.Button,{onClick:J,variant:`solid`,children:E(`image_cropper.confirm`)})]})]})})]}):(0,f.jsx)(`div`,{ref:T,className:(0,d.default)(`wim-image-cropper`,l.default.root,l.default.empty,C),...w,children:(0,f.jsx)(`div`,{className:l.default.emptyContent,children:E(`image_cropper.no_image`)})})});h.displayName=`ImageCropper`,exports.ImageCropper=h;
2
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../i18n/useWimTranslation.cjs"),n=require("../../../i18n/generated/common.cjs"),r=require("../../layout/VisuallyHidden/VisuallyHidden.cjs"),i=require("../Button/Button.cjs"),a=require("../../../i18n/generated/form.cjs"),o=require("../Slider/Slider.cjs"),s=require("../IconButton/IconButton.cjs"),c=require("../../overlay/Dialog/Dialog.cjs"),l=require("./cropImage.cjs"),u=require("./image-cropper.module.cjs");let d=require("react");d=e.__toESM(d,1);let f=require("classnames");f=e.__toESM(f,1);let p=require("react/jsx-runtime");var m=10,h=50,g=d.default.forwardRef(({src:e,aspectRatio:g=1,circular:_=!1,onCrop:v,showRotation:y=!0,showZoom:b=!0,showApplyButton:x=!0,applyLabel:S,onApply:C,onCropError:w,maxOutputSize:T,outputType:E=`image/png`,outputQuality:D=.92,crossOrigin:O,className:k,...A},j)=>{let{t:M}=t.useWimTranslation([a.formNs,n.commonNs]),[N,P]=(0,d.useState)(1),[F,I]=(0,d.useState)(0),[L,R]=(0,d.useState)({x:0,y:0}),[z,B]=(0,d.useState)(!1),[V,H]=(0,d.useState)({x:0,y:0}),[U,W]=(0,d.useState)(!1),G=(0,d.useRef)(null),K=(0,d.useRef)(null),q=(0,d.useRef)(null),J=(0,d.useId)();(0,d.useEffect)(()=>{R({x:0,y:0}),P(1),I(0)},[e]);let Y=e=>{(e.pointerType!==`mouse`||e.button===0)&&(B(!0),H({x:e.clientX-L.x,y:e.clientY-L.y}))},X=(0,d.useCallback)(e=>{z&&R({x:e.clientX-V.x,y:e.clientY-V.y})},[z,V]),Z=(0,d.useCallback)(()=>{B(!1)},[]);(0,d.useEffect)(()=>{if(z)return window.addEventListener(`pointermove`,X),window.addEventListener(`pointerup`,Z),window.addEventListener(`pointercancel`,Z),()=>{window.removeEventListener(`pointermove`,X),window.removeEventListener(`pointerup`,Z),window.removeEventListener(`pointercancel`,Z)}},[z,X,Z]);let Q=e=>{let t=e.shiftKey?h:m,n={ArrowLeft:[-t,0],ArrowRight:[t,0],ArrowUp:[0,-t],ArrowDown:[0,t]}[e.key];n?(e.preventDefault(),R(e=>({x:e.x+n[0],y:e.y+n[1]}))):e.key===`Home`&&(e.preventDefault(),R({x:0,y:0}))},$=()=>{I(e=>(e+90)%360)},ee=()=>{W(!0)},te=()=>{let e=G.current,t=q.current;if(W(!1),!e||!t)return;let n={x:L.x,y:L.y,zoom:N,rotation:F,frameWidth:t.clientWidth,frameHeight:t.clientHeight,layoutWidth:e.offsetWidth,layoutHeight:e.offsetHeight,naturalWidth:e.naturalWidth,naturalHeight:e.naturalHeight,maxOutputSize:T};try{let{dataUrl:t,detail:r}=l.cropImage(e,n,E,D);v?.(t,r),C?.(t,r)}catch(e){w?.(e instanceof Error?e:Error(String(e)),l.resolveCropDetail(n).detail)}};return e?(0,p.jsxs)(`div`,{ref:j,className:(0,f.default)(`wim-image-cropper`,u.default.root,k),...A,children:[(0,p.jsxs)(`div`,{ref:K,className:u.default.viewer,onPointerDown:Y,onKeyDown:Q,role:`application`,tabIndex:0,"aria-label":M(`image_cropper.position_label`),"aria-describedby":J,children:[(0,p.jsx)(r.VisuallyHidden,{id:J,children:M(`image_cropper.position_hint`)}),(0,p.jsx)(`div`,{className:u.default.imageContainer,children:(0,p.jsx)(`img`,{ref:G,src:e,alt:M(`a11y.crop_target`),crossOrigin:O,className:u.default.image,style:{transform:`translate(${L.x}px, ${L.y}px) rotate(${F}deg) scale(${N})`},draggable:!1})}),(0,p.jsx)(`div`,{className:u.default.overlay,children:(0,p.jsx)(`div`,{ref:q,className:(0,f.default)(u.default.cropArea,{[u.default.circular]:_}),style:{aspectRatio:g}})})]}),(0,p.jsxs)(`div`,{className:u.default.controls,children:[b&&(0,p.jsx)(`div`,{className:u.default.zoomControl,children:(0,p.jsx)(o.Slider,{min:1,max:3,step:.1,value:N,onChange:e=>P(e),label:M(`image_cropper.zoom`),styles:{root:u.default.zoomSlider}})}),y&&(0,p.jsx)(`div`,{className:u.default.rotationControl,children:(0,p.jsx)(s.IconButton,{iconName:`RefreshIcon`,onClick:$,"aria-label":M(`image_cropper.rotate`),variant:`outline`,size:`sm`})}),x&&(0,p.jsx)(`div`,{className:u.default.applyControl,children:(0,p.jsx)(i.Button,{onClick:ee,size:`sm`,variant:`solid`,children:S||M(`image_cropper.apply`)})})]}),(0,p.jsx)(c.Dialog,{open:U,onOpenChange:W,children:(0,p.jsxs)(c.DialogContent,{children:[(0,p.jsx)(c.DialogHeader,{children:(0,p.jsx)(c.DialogTitle,{children:M(`image_cropper.confirm_title`)})}),(0,p.jsx)(c.DialogDescription,{children:M(`image_cropper.confirm_message`)}),(0,p.jsxs)(c.DialogFooter,{children:[(0,p.jsx)(c.DialogClose,{asChild:!0,children:(0,p.jsx)(i.Button,{variant:`ghost`,children:M(`image_cropper.cancel`)})}),(0,p.jsx)(i.Button,{onClick:te,variant:`solid`,children:M(`image_cropper.confirm`)})]})]})})]}):(0,p.jsx)(`div`,{ref:j,className:(0,f.default)(`wim-image-cropper`,u.default.root,u.default.empty,k),...A,children:(0,p.jsx)(`div`,{className:u.default.emptyContent,children:M(`image_cropper.no_image`)})})});g.displayName=`ImageCropper`,exports.ImageCropper=g;
@@ -1,4 +1,6 @@
1
1
  import { default as React } from 'react';
2
+ import { ImageCropDetail, ImageCropOutputType } from './cropImage';
3
+ export type { ImageCropDetail, ImageCropOutputType };
2
4
  export interface ImageCropperProps extends React.ComponentPropsWithoutRef<"div"> {
3
5
  /** URL or data URL of the image to crop */
4
6
  src?: string;
@@ -6,8 +8,11 @@ export interface ImageCropperProps extends React.ComponentPropsWithoutRef<"div">
6
8
  aspectRatio?: number;
7
9
  /** Whether to display a circular crop area (for profile images) */
8
10
  circular?: boolean;
9
- /** Callback when the crop result is finalized */
10
- onCrop?: (dataUrl: string) => void;
11
+ /**
12
+ * Called with the cropped image as a data URL once the crop is confirmed. The second argument
13
+ * describes the crop (offset, zoom, rotation, frame and output size) so it can be redone elsewhere.
14
+ */
15
+ onCrop?: (dataUrl: string, detail: ImageCropDetail) => void;
11
16
  /** Whether to show the rotation button */
12
17
  showRotation?: boolean;
13
18
  /** Whether to show the zoom slider */
@@ -16,8 +21,35 @@ export interface ImageCropperProps extends React.ComponentPropsWithoutRef<"div">
16
21
  showApplyButton?: boolean;
17
22
  /** Label of the apply button */
18
23
  applyLabel?: string;
19
- /** Callback when the crop is applied (after confirming in the dialog) */
20
- onApply?: (dataUrl: string) => void;
24
+ /** Called with the cropped image and the crop detail when the crop is applied (after confirming in the dialog) */
25
+ onApply?: (dataUrl: string, detail: ImageCropDetail) => void;
26
+ /**
27
+ * Called instead of onCrop and onApply when the image cannot be produced, with the crop detail.
28
+ * The usual cause is an image from another origin drawn without CORS approval: the browser then
29
+ * refuses to read the canvas. Set crossOrigin and serve the image with CORS headers, or crop on
30
+ * the server from the detail.
31
+ */
32
+ onCropError?: (error: Error, detail: ImageCropDetail) => void;
33
+ /**
34
+ * Upper bound, in px, for the longer side of the output image. The crop is taken at the
35
+ * resolution of the source image; without a bound a large photo produces a large data URL.
36
+ */
37
+ maxOutputSize?: number;
38
+ /**
39
+ * Image format of the output. "image/png" keeps transparency where the image does not cover the frame.
40
+ * @default "image/png"
41
+ */
42
+ outputType?: ImageCropOutputType;
43
+ /**
44
+ * Quality from 0 to 1 for "image/jpeg" and "image/webp". Ignored for "image/png".
45
+ * @default 0.92
46
+ */
47
+ outputQuality?: number;
48
+ /**
49
+ * CORS mode used to load the image. Needed to crop an image served from another origin;
50
+ * the server must send matching CORS headers or the image will not load at all.
51
+ */
52
+ crossOrigin?: "anonymous" | "use-credentials";
21
53
  }
22
54
  /**
23
55
  * Component for cropping and rotating an image.
@@ -6,173 +6,197 @@ import { Button as r } from "../Button/Button.js";
6
6
  import { formNs as i } from "../../../i18n/generated/form.js";
7
7
  import { Slider as a } from "../Slider/Slider.js";
8
8
  import { IconButton as o } from "../IconButton/IconButton.js";
9
- import { Dialog as s, DialogClose as c, DialogContent as l, DialogDescription as u, DialogFooter as d, DialogHeader as f, DialogTitle as ee } from "../../overlay/Dialog/Dialog.js";
10
- import p from "./image-cropper.module.js";
11
- import m, { useCallback as h, useEffect as g, useId as _, useRef as v, useState as y } from "react";
12
- import b from "classnames";
13
- import { jsx as x, jsxs as S } from "react/jsx-runtime";
9
+ import { Dialog as s, DialogClose as c, DialogContent as l, DialogDescription as u, DialogFooter as ee, DialogHeader as d, DialogTitle as te } from "../../overlay/Dialog/Dialog.js";
10
+ import { cropImage as f, resolveCropDetail as p } from "./cropImage.js";
11
+ import m from "./image-cropper.module.js";
12
+ import h, { useCallback as g, useEffect as _, useId as v, useRef as y, useState as b } from "react";
13
+ import x from "classnames";
14
+ import { jsx as S, jsxs as C } from "react/jsx-runtime";
14
15
  //#region src/components/form/ImageCropper/ImageCropper.tsx
15
- var C = 10, w = 50, T = m.forwardRef(({ src: m, aspectRatio: T = 1, circular: E = !1, onCrop: D, showRotation: O = !0, showZoom: te = !0, showApplyButton: k = !0, applyLabel: A, onApply: j, className: M, ...N }, P) => {
16
- let { t: F } = e([i, t]), [I, L] = y(1), [R, z] = y(0), [B, V] = y({
16
+ var w = 10, T = 50, E = h.forwardRef(({ src: h, aspectRatio: E = 1, circular: ne = !1, onCrop: re, showRotation: ie = !0, showZoom: ae = !0, showApplyButton: oe = !0, applyLabel: D, onApply: O, onCropError: k, maxOutputSize: A, outputType: j = "image/png", outputQuality: M = .92, crossOrigin: N, className: P, ...F }, I) => {
17
+ let { t: L } = e([i, t]), [R, z] = b(1), [B, V] = b(0), [H, U] = b({
17
18
  x: 0,
18
19
  y: 0
19
- }), [H, U] = y(!1), [W, G] = y({
20
+ }), [W, G] = b(!1), [K, q] = b({
20
21
  x: 0,
21
22
  y: 0
22
- }), [K, q] = y(!1), J = v(null), Y = v(null), X = _();
23
- g(() => {
24
- V({
23
+ }), [se, J] = b(!1), Y = y(null), ce = y(null), X = y(null), Z = v();
24
+ _(() => {
25
+ U({
25
26
  x: 0,
26
27
  y: 0
27
- }), L(1), z(0);
28
- }, [m]);
29
- let Z = (e) => {
30
- U(!0), G({
31
- x: e.clientX - B.x,
32
- y: e.clientY - B.y
33
- });
34
- }, Q = h((e) => {
35
- H && V({
36
- x: e.clientX - W.x,
37
- y: e.clientY - W.y
28
+ }), z(1), V(0);
29
+ }, [h]);
30
+ let le = (e) => {
31
+ (e.pointerType !== "mouse" || e.button === 0) && (G(!0), q({
32
+ x: e.clientX - H.x,
33
+ y: e.clientY - H.y
34
+ }));
35
+ }, Q = g((e) => {
36
+ W && U({
37
+ x: e.clientX - K.x,
38
+ y: e.clientY - K.y
38
39
  });
39
- }, [H, W]), $ = h(() => {
40
- U(!1);
40
+ }, [W, K]), $ = g(() => {
41
+ G(!1);
41
42
  }, []);
42
- g(() => (H ? (window.addEventListener("mousemove", Q), window.addEventListener("mouseup", $)) : (window.removeEventListener("mousemove", Q), window.removeEventListener("mouseup", $)), () => {
43
- window.removeEventListener("mousemove", Q), window.removeEventListener("mouseup", $);
44
- }), [
45
- H,
43
+ _(() => {
44
+ if (W) return window.addEventListener("pointermove", Q), window.addEventListener("pointerup", $), window.addEventListener("pointercancel", $), () => {
45
+ window.removeEventListener("pointermove", Q), window.removeEventListener("pointerup", $), window.removeEventListener("pointercancel", $);
46
+ };
47
+ }, [
48
+ W,
46
49
  Q,
47
50
  $
48
51
  ]);
49
- let ne = (e) => {
50
- let t = e.shiftKey ? w : C, n = {
52
+ let ue = (e) => {
53
+ let t = e.shiftKey ? T : w, n = {
51
54
  ArrowLeft: [-t, 0],
52
55
  ArrowRight: [t, 0],
53
56
  ArrowUp: [0, -t],
54
57
  ArrowDown: [0, t]
55
58
  }[e.key];
56
- n ? (e.preventDefault(), V((e) => ({
59
+ n ? (e.preventDefault(), U((e) => ({
57
60
  x: e.x + n[0],
58
61
  y: e.y + n[1]
59
- }))) : e.key === "Home" && (e.preventDefault(), V({
62
+ }))) : e.key === "Home" && (e.preventDefault(), U({
60
63
  x: 0,
61
64
  y: 0
62
65
  }));
63
- }, re = () => {
64
- z((e) => (e + 90) % 360);
65
- }, ie = () => {
66
- q(!0);
67
- }, ae = () => {
68
- let e = m || "";
69
- D?.(e), j?.(e), q(!1);
66
+ }, de = () => {
67
+ V((e) => (e + 90) % 360);
68
+ }, fe = () => {
69
+ J(!0);
70
+ }, pe = () => {
71
+ let e = Y.current, t = X.current;
72
+ if (J(!1), !e || !t) return;
73
+ let n = {
74
+ x: H.x,
75
+ y: H.y,
76
+ zoom: R,
77
+ rotation: B,
78
+ frameWidth: t.clientWidth,
79
+ frameHeight: t.clientHeight,
80
+ layoutWidth: e.offsetWidth,
81
+ layoutHeight: e.offsetHeight,
82
+ naturalWidth: e.naturalWidth,
83
+ naturalHeight: e.naturalHeight,
84
+ maxOutputSize: A
85
+ };
86
+ try {
87
+ let { dataUrl: t, detail: r } = f(e, n, j, M);
88
+ re?.(t, r), O?.(t, r);
89
+ } catch (e) {
90
+ k?.(e instanceof Error ? e : Error(String(e)), p(n).detail);
91
+ }
70
92
  };
71
- return m ? /* @__PURE__ */ S("div", {
72
- ref: P,
73
- className: b("wim-image-cropper", p.root, M),
74
- ...N,
93
+ return h ? /* @__PURE__ */ C("div", {
94
+ ref: I,
95
+ className: x("wim-image-cropper", m.root, P),
96
+ ...F,
75
97
  children: [
76
- /* @__PURE__ */ S("div", {
77
- ref: Y,
78
- className: p.viewer,
79
- onMouseDown: Z,
80
- onKeyDown: ne,
98
+ /* @__PURE__ */ C("div", {
99
+ ref: ce,
100
+ className: m.viewer,
101
+ onPointerDown: le,
102
+ onKeyDown: ue,
81
103
  role: "application",
82
104
  tabIndex: 0,
83
- "aria-label": F("image_cropper.position_label"),
84
- "aria-describedby": X,
105
+ "aria-label": L("image_cropper.position_label"),
106
+ "aria-describedby": Z,
85
107
  children: [
86
- /* @__PURE__ */ x(n, {
87
- id: X,
88
- children: F("image_cropper.position_hint")
108
+ /* @__PURE__ */ S(n, {
109
+ id: Z,
110
+ children: L("image_cropper.position_hint")
89
111
  }),
90
- /* @__PURE__ */ x("div", {
91
- className: p.imageContainer,
92
- children: /* @__PURE__ */ x("img", {
93
- ref: J,
94
- src: m,
95
- alt: F("a11y.crop_target"),
96
- className: p.image,
97
- style: { transform: `translate(${B.x}px, ${B.y}px) rotate(${R}deg) scale(${I})` },
112
+ /* @__PURE__ */ S("div", {
113
+ className: m.imageContainer,
114
+ children: /* @__PURE__ */ S("img", {
115
+ ref: Y,
116
+ src: h,
117
+ alt: L("a11y.crop_target"),
118
+ crossOrigin: N,
119
+ className: m.image,
120
+ style: { transform: `translate(${H.x}px, ${H.y}px) rotate(${B}deg) scale(${R})` },
98
121
  draggable: !1
99
122
  })
100
123
  }),
101
- /* @__PURE__ */ x("div", {
102
- className: p.overlay,
103
- children: /* @__PURE__ */ x("div", {
104
- className: b(p.cropArea, { [p.circular]: E }),
105
- style: { aspectRatio: T }
124
+ /* @__PURE__ */ S("div", {
125
+ className: m.overlay,
126
+ children: /* @__PURE__ */ S("div", {
127
+ ref: X,
128
+ className: x(m.cropArea, { [m.circular]: ne }),
129
+ style: { aspectRatio: E }
106
130
  })
107
131
  })
108
132
  ]
109
133
  }),
110
- /* @__PURE__ */ S("div", {
111
- className: p.controls,
134
+ /* @__PURE__ */ C("div", {
135
+ className: m.controls,
112
136
  children: [
113
- te && /* @__PURE__ */ x("div", {
114
- className: p.zoomControl,
115
- children: /* @__PURE__ */ x(a, {
137
+ ae && /* @__PURE__ */ S("div", {
138
+ className: m.zoomControl,
139
+ children: /* @__PURE__ */ S(a, {
116
140
  min: 1,
117
141
  max: 3,
118
142
  step: .1,
119
- value: I,
120
- onChange: (e) => L(e),
121
- label: F("image_cropper.zoom"),
122
- styles: { root: p.zoomSlider }
143
+ value: R,
144
+ onChange: (e) => z(e),
145
+ label: L("image_cropper.zoom"),
146
+ styles: { root: m.zoomSlider }
123
147
  })
124
148
  }),
125
- O && /* @__PURE__ */ x("div", {
126
- className: p.rotationControl,
127
- children: /* @__PURE__ */ x(o, {
149
+ ie && /* @__PURE__ */ S("div", {
150
+ className: m.rotationControl,
151
+ children: /* @__PURE__ */ S(o, {
128
152
  iconName: "RefreshIcon",
129
- onClick: re,
130
- "aria-label": F("image_cropper.rotate"),
153
+ onClick: de,
154
+ "aria-label": L("image_cropper.rotate"),
131
155
  variant: "outline",
132
156
  size: "sm"
133
157
  })
134
158
  }),
135
- k && /* @__PURE__ */ x("div", {
136
- className: p.applyControl,
137
- children: /* @__PURE__ */ x(r, {
138
- onClick: ie,
159
+ oe && /* @__PURE__ */ S("div", {
160
+ className: m.applyControl,
161
+ children: /* @__PURE__ */ S(r, {
162
+ onClick: fe,
139
163
  size: "sm",
140
164
  variant: "solid",
141
- children: A || F("image_cropper.apply")
165
+ children: D || L("image_cropper.apply")
142
166
  })
143
167
  })
144
168
  ]
145
169
  }),
146
- /* @__PURE__ */ x(s, {
147
- open: K,
148
- onOpenChange: q,
149
- children: /* @__PURE__ */ S(l, { children: [
150
- /* @__PURE__ */ x(f, { children: /* @__PURE__ */ x(ee, { children: F("image_cropper.confirm_title") }) }),
151
- /* @__PURE__ */ x(u, { children: F("image_cropper.confirm_message") }),
152
- /* @__PURE__ */ S(d, { children: [/* @__PURE__ */ x(c, {
170
+ /* @__PURE__ */ S(s, {
171
+ open: se,
172
+ onOpenChange: J,
173
+ children: /* @__PURE__ */ C(l, { children: [
174
+ /* @__PURE__ */ S(d, { children: /* @__PURE__ */ S(te, { children: L("image_cropper.confirm_title") }) }),
175
+ /* @__PURE__ */ S(u, { children: L("image_cropper.confirm_message") }),
176
+ /* @__PURE__ */ C(ee, { children: [/* @__PURE__ */ S(c, {
153
177
  asChild: !0,
154
- children: /* @__PURE__ */ x(r, {
178
+ children: /* @__PURE__ */ S(r, {
155
179
  variant: "ghost",
156
- children: F("image_cropper.cancel")
180
+ children: L("image_cropper.cancel")
157
181
  })
158
- }), /* @__PURE__ */ x(r, {
159
- onClick: ae,
182
+ }), /* @__PURE__ */ S(r, {
183
+ onClick: pe,
160
184
  variant: "solid",
161
- children: F("image_cropper.confirm")
185
+ children: L("image_cropper.confirm")
162
186
  })] })
163
187
  ] })
164
188
  })
165
189
  ]
166
- }) : /* @__PURE__ */ x("div", {
167
- ref: P,
168
- className: b("wim-image-cropper", p.root, p.empty, M),
169
- ...N,
170
- children: /* @__PURE__ */ x("div", {
171
- className: p.emptyContent,
172
- children: F("image_cropper.no_image")
190
+ }) : /* @__PURE__ */ S("div", {
191
+ ref: I,
192
+ className: x("wim-image-cropper", m.root, m.empty, P),
193
+ ...F,
194
+ children: /* @__PURE__ */ S("div", {
195
+ className: m.emptyContent,
196
+ children: L("image_cropper.no_image")
173
197
  })
174
198
  });
175
199
  });
176
- T.displayName = "ImageCropper";
200
+ E.displayName = "ImageCropper";
177
201
  //#endregion
178
- export { T as ImageCropper };
202
+ export { E as ImageCropper };
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ function e(e){let t=(e.layoutWidth>0?e.naturalWidth/e.layoutWidth:1)/e.zoom,n=Math.max(e.frameWidth,e.frameHeight)*t;e.maxOutputSize!==void 0&&e.maxOutputSize>0&&n>e.maxOutputSize&&(t*=e.maxOutputSize/n);let r=Math.max(1,Math.round(e.frameWidth*t)),i=Math.max(1,Math.round(e.frameHeight*t));return{detail:{x:e.x,y:e.y,zoom:e.zoom,rotation:e.rotation,frameWidth:e.frameWidth,frameHeight:e.frameHeight,width:r,height:i,naturalWidth:e.naturalWidth,naturalHeight:e.naturalHeight},scale:r/e.frameWidth}}function t(t,n,r,i){let{detail:a,scale:o}=e(n);if(!t.complete||n.naturalWidth===0||n.naturalHeight===0)throw Error(`ImageCropper: the image has not loaded, so there is nothing to crop.`);let s=document.createElement(`canvas`);s.width=a.width,s.height=a.height;let c=s.getContext(`2d`);if(!c)throw Error(`ImageCropper: a 2D canvas context is not available.`);return r===`image/jpeg`&&(c.fillStyle=`#fff`,c.fillRect(0,0,a.width,a.height)),c.translate(a.width/2,a.height/2),c.scale(o,o),c.translate(n.x,n.y),c.rotate(n.rotation*Math.PI/180),c.scale(n.zoom,n.zoom),c.drawImage(t,-n.layoutWidth/2,-n.layoutHeight/2,n.layoutWidth,n.layoutHeight),{dataUrl:s.toDataURL(r,i),detail:a}}exports.cropImage=t,exports.resolveCropDetail=e;
@@ -0,0 +1,58 @@
1
+ /** What the crop was made from. Enough to redo the crop elsewhere (for example on a server). */
2
+ export type ImageCropDetail = {
3
+ /** Horizontal offset of the image center from the center of the crop frame, in CSS px. */
4
+ x: number;
5
+ /** Vertical offset of the image center from the center of the crop frame, in CSS px. */
6
+ y: number;
7
+ /** Zoom factor applied to the image (1 = the size it is laid out at). */
8
+ zoom: number;
9
+ /** Clockwise rotation in degrees. */
10
+ rotation: number;
11
+ /** Width of the crop frame on screen, in CSS px. */
12
+ frameWidth: number;
13
+ /** Height of the crop frame on screen, in CSS px. */
14
+ frameHeight: number;
15
+ /** Width of the output image in px, after `maxOutputSize` is applied. */
16
+ width: number;
17
+ /** Height of the output image in px, after `maxOutputSize` is applied. */
18
+ height: number;
19
+ /** Natural width of the source image in px. */
20
+ naturalWidth: number;
21
+ /** Natural height of the source image in px. */
22
+ naturalHeight: number;
23
+ };
24
+ export type ImageCropOutputType = "image/png" | "image/jpeg" | "image/webp";
25
+ export type CropGeometry = {
26
+ x: number;
27
+ y: number;
28
+ zoom: number;
29
+ rotation: number;
30
+ frameWidth: number;
31
+ frameHeight: number;
32
+ /** 画像が、拡大の前に画面で占めている大きさ(CSS px)。 */
33
+ layoutWidth: number;
34
+ layoutHeight: number;
35
+ naturalWidth: number;
36
+ naturalHeight: number;
37
+ maxOutputSize?: number;
38
+ };
39
+ /**
40
+ * 出力の大きさと、枠の 1 CSS px が出力の何 px になるかを決める。
41
+ *
42
+ * 画面の枠の大きさで切ると、拡大して見ている写真は粗くなる。元の画像の解像度で切る ──
43
+ * 枠が元の画像の何 px ぶんを覆っているかを、出力の大きさにする。`maxOutputSize` は長いほうの辺の上限。
44
+ */
45
+ export declare function resolveCropDetail(g: CropGeometry): {
46
+ detail: ImageCropDetail;
47
+ scale: number;
48
+ };
49
+ /**
50
+ * 画面に見えている枠の中を、Canvas に描いて data URL にする。
51
+ *
52
+ * 画面の `transform`(`translate → rotate → scale`。原点は画像の中心)を、枠の中心を原点にして
53
+ * そのまま Canvas に写す。失敗(画像が読めていない・別オリジンの画像で Canvas が汚染された)は投げる。
54
+ */
55
+ export declare function cropImage(image: HTMLImageElement, g: CropGeometry, type: ImageCropOutputType, quality: number): {
56
+ dataUrl: string;
57
+ detail: ImageCropDetail;
58
+ };
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ //#region src/components/form/ImageCropper/cropImage.ts
3
+ function e(e) {
4
+ let t = (e.layoutWidth > 0 ? e.naturalWidth / e.layoutWidth : 1) / e.zoom, n = Math.max(e.frameWidth, e.frameHeight) * t;
5
+ e.maxOutputSize !== void 0 && e.maxOutputSize > 0 && n > e.maxOutputSize && (t *= e.maxOutputSize / n);
6
+ let r = Math.max(1, Math.round(e.frameWidth * t)), i = Math.max(1, Math.round(e.frameHeight * t));
7
+ return {
8
+ detail: {
9
+ x: e.x,
10
+ y: e.y,
11
+ zoom: e.zoom,
12
+ rotation: e.rotation,
13
+ frameWidth: e.frameWidth,
14
+ frameHeight: e.frameHeight,
15
+ width: r,
16
+ height: i,
17
+ naturalWidth: e.naturalWidth,
18
+ naturalHeight: e.naturalHeight
19
+ },
20
+ scale: r / e.frameWidth
21
+ };
22
+ }
23
+ function t(t, n, r, i) {
24
+ let { detail: a, scale: o } = e(n);
25
+ if (!t.complete || n.naturalWidth === 0 || n.naturalHeight === 0) throw Error("ImageCropper: the image has not loaded, so there is nothing to crop.");
26
+ let s = document.createElement("canvas");
27
+ s.width = a.width, s.height = a.height;
28
+ let c = s.getContext("2d");
29
+ if (!c) throw Error("ImageCropper: a 2D canvas context is not available.");
30
+ return r === "image/jpeg" && (c.fillStyle = "#fff", c.fillRect(0, 0, a.width, a.height)), c.translate(a.width / 2, a.height / 2), c.scale(o, o), c.translate(n.x, n.y), c.rotate(n.rotation * Math.PI / 180), c.scale(n.zoom, n.zoom), c.drawImage(t, -n.layoutWidth / 2, -n.layoutHeight / 2, n.layoutWidth, n.layoutHeight), {
31
+ dataUrl: s.toDataURL(r, i),
32
+ detail: a
33
+ };
34
+ }
35
+ //#endregion
36
+ export { t as cropImage, e as resolveCropDetail };
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- var e=`_root_jol5m_3`,t=`_viewer_jol5m_13`,n=`_imageContainer_jol5m_31`,r=`_image_jol5m_31`,i=`_overlay_jol5m_43`,a=`_cropArea_jol5m_52`,o=`_circular_jol5m_58`,s=`_controls_jol5m_61`,c=`_zoomControl_jol5m_69`,l=`_zoomSlider_jol5m_72`,u=`_rotationControl_jol5m_75`,d=`_applyControl_jol5m_78`,f=`_empty_jol5m_82`,p=`_emptyContent_jol5m_91`,m={root:e,viewer:t,imageContainer:n,image:r,overlay:i,cropArea:a,circular:o,controls:s,zoomControl:c,zoomSlider:l,rotationControl:u,applyControl:d,empty:f,emptyContent:p};exports.applyControl=d,exports.circular=o,exports.controls=s,exports.cropArea=a,exports.default=m,exports.empty=f,exports.emptyContent=p,exports.image=r,exports.imageContainer=n,exports.overlay=i,exports.root=e,exports.rotationControl=u,exports.viewer=t,exports.zoomControl=c,exports.zoomSlider=l;
2
+ var e=`_root_1xzzx_3`,t=`_viewer_1xzzx_13`,n=`_imageContainer_1xzzx_33`,r=`_image_1xzzx_33`,i=`_overlay_1xzzx_45`,a=`_cropArea_1xzzx_54`,o=`_circular_1xzzx_60`,s=`_controls_1xzzx_63`,c=`_zoomControl_1xzzx_71`,l=`_zoomSlider_1xzzx_74`,u=`_rotationControl_1xzzx_77`,d=`_applyControl_1xzzx_80`,f=`_empty_1xzzx_84`,p=`_emptyContent_1xzzx_93`,m={root:e,viewer:t,imageContainer:n,image:r,overlay:i,cropArea:a,circular:o,controls:s,zoomControl:c,zoomSlider:l,rotationControl:u,applyControl:d,empty:f,emptyContent:p};exports.applyControl=d,exports.circular=o,exports.controls=s,exports.cropArea=a,exports.default=m,exports.empty=f,exports.emptyContent=p,exports.image=r,exports.imageContainer=n,exports.overlay=i,exports.root=e,exports.rotationControl=u,exports.viewer=t,exports.zoomControl=c,exports.zoomSlider=l;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  //#region src/components/form/ImageCropper/image-cropper.module.scss
3
- var e = "_root_jol5m_3", t = "_viewer_jol5m_13", n = "_imageContainer_jol5m_31", r = "_image_jol5m_31", i = "_overlay_jol5m_43", a = "_cropArea_jol5m_52", o = "_circular_jol5m_58", s = "_controls_jol5m_61", c = "_zoomControl_jol5m_69", l = "_zoomSlider_jol5m_72", u = "_rotationControl_jol5m_75", d = "_applyControl_jol5m_78", f = "_empty_jol5m_82", p = "_emptyContent_jol5m_91", m = {
3
+ var e = "_root_1xzzx_3", t = "_viewer_1xzzx_13", n = "_imageContainer_1xzzx_33", r = "_image_1xzzx_33", i = "_overlay_1xzzx_45", a = "_cropArea_1xzzx_54", o = "_circular_1xzzx_60", s = "_controls_1xzzx_63", c = "_zoomControl_1xzzx_71", l = "_zoomSlider_1xzzx_74", u = "_rotationControl_1xzzx_77", d = "_applyControl_1xzzx_80", f = "_empty_1xzzx_84", p = "_emptyContent_1xzzx_93", m = {
4
4
  root: e,
5
5
  viewer: t,
6
6
  imageContainer: n,
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("./anchor.module.cjs");let n=require("react");n=e.__toESM(n,1);let r=require("classnames");r=e.__toESM(r,1);let i=require("react/jsx-runtime");var a=({items:e=[],bounds:a=5,offset:o=0,direction:s=`vertical`,className:c,style:l})=>{let[u,d]=(0,n.useState)(``),[f,p]=(0,n.useState)({}),m=(0,n.useRef)(null),h=(e,t)=>{e.preventDefault();let n=t.replace(`#`,``),r=document.getElementById(n);r&&(window.scrollTo({top:r.offsetTop-o,behavior:`smooth`}),d(t))};(0,n.useLayoutEffect)(()=>{let t=()=>{let t=(e,n)=>{let r=[];return e.forEach(e=>{r.push({href:e.href,parentHref:n}),e.children&&(r=r.concat(t(e.children,n||e.href)))}),r},n=t(e),r=``,i=window.scrollY||document.documentElement.scrollTop,c=document.documentElement.scrollHeight,l=document.documentElement.clientHeight;if(i>0&&Math.ceil(i+l)>=c&&n.length>0){let e=n[n.length-1];r=s===`horizontal`&&e.parentHref?e.parentHref:e.href}else for(let e of n){let t=e.href.replace(`#`,``),n=document.getElementById(t);if(n){if(n.getBoundingClientRect().top<=o+a)r=s===`horizontal`&&e.parentHref?e.parentHref:e.href;else break}}r&&r!==u&&d(r)};return window.addEventListener(`scroll`,t),t(),()=>window.removeEventListener(`scroll`,t)},[e,o,a,u,s]),(0,n.useLayoutEffect)(()=>{if(!u||!m.current)return;let e=m.current.querySelector(`a[href="${u}"]`);if(e){let n=m.current.getBoundingClientRect();if(s===`vertical`){let t=e.getBoundingClientRect();p({top:t.top-n.top,height:t.height,opacity:1})}else{let r=m.current.querySelector(`.${t.default.list}`);if(r){let t=e.getBoundingClientRect(),i=r.getBoundingClientRect(),a=t.left-i.left+r.scrollLeft,o=a-i.width/2+t.width/2,s=r.scrollWidth-i.width,c=Math.max(0,Math.min(o,s)),l=a-c+(i.left-n.left);p({left:l,width:t.width,opacity:1}),r.scrollTo({left:c,behavior:`smooth`})}else{let t=e.getBoundingClientRect();p({left:t.left-m.current.getBoundingClientRect().left,width:t.width,opacity:1})}}}else p({opacity:0})},[u,s]);let g=e=>(0,i.jsx)(`ul`,{className:(0,r.default)(t.default.list,t.default[s]),children:e.map(e=>(0,i.jsxs)(`li`,{className:(0,r.default)(t.default.item,u===e.href&&t.default.active),children:[(0,i.jsx)(`a`,{href:e.href,className:t.default.link,"aria-current":u===e.href?`location`:void 0,onClick:t=>h(t,e.href),title:typeof e.title==`string`?e.title:void 0,children:e.title}),e.children&&s===`vertical`&&g(e.children)]},e.key))});return(0,i.jsxs)(`div`,{className:(0,r.default)(`wim-anchor`,t.default.root,t.default[s],c),style:l,ref:m,children:[(0,i.jsx)(`div`,{className:t.default.ink,children:(0,i.jsx)(`span`,{className:t.default.inkBall,style:f})}),g(e)]})};exports.Anchor=a,exports.default=a;
2
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("./anchor.module.cjs");let n=require("react");n=e.__toESM(n,1);let r=require("classnames");r=e.__toESM(r,1);let i=require("react/jsx-runtime");var a=({items:e=[],bounds:a=5,offset:o=0,direction:s=`vertical`,className:c,style:l})=>{let[u,d]=(0,n.useState)(``),[f,p]=(0,n.useState)({}),m=(0,n.useRef)(null),h=(e,t)=>{e.preventDefault();let n=t.replace(`#`,``),r=document.getElementById(n);r&&(window.scrollTo({top:r.offsetTop-o,behavior:`smooth`}),d(t))};(0,n.useLayoutEffect)(()=>{let t=()=>{let t=(e,n)=>{let r=[];return e.forEach(e=>{r.push({href:e.href,parentHref:n}),e.children&&(r=r.concat(t(e.children,n||e.href)))}),r},n=t(e),r=``,i=window.scrollY||document.documentElement.scrollTop,c=document.documentElement.scrollHeight,l=document.documentElement.clientHeight;if(i>0&&Math.ceil(i+l)>=c&&n.length>0){let e=n[n.length-1];r=s===`horizontal`&&e.parentHref?e.parentHref:e.href}else for(let e of n){let t=e.href.replace(`#`,``),n=document.getElementById(t);if(n){if(n.getBoundingClientRect().top<=o+a)r=s===`horizontal`&&e.parentHref?e.parentHref:e.href;else break}}r&&r!==u&&d(r)};return window.addEventListener(`scroll`,t),t(),()=>window.removeEventListener(`scroll`,t)},[e,o,a,u,s]);let g=(0,n.useCallback)(()=>{if(!u||!m.current)return;let e=m.current.querySelector(`a[href="${u}"]`);if(e){let n=m.current.getBoundingClientRect();if(s===`vertical`){let t=e.getBoundingClientRect();p({top:t.top-n.top,height:t.height,opacity:1})}else{let r=m.current.querySelector(`.${t.default.list}`);if(r){let t=e.getBoundingClientRect(),i=r.getBoundingClientRect(),a=t.left-i.left+r.scrollLeft,o=a-i.width/2+t.width/2,s=r.scrollWidth-i.width,c=Math.max(0,Math.min(o,s)),l=a-c+(i.left-n.left);p({left:l,width:t.width,opacity:1}),r.scrollTo({left:c,behavior:`smooth`})}else{let t=e.getBoundingClientRect();p({left:t.left-m.current.getBoundingClientRect().left,width:t.width,opacity:1})}}}else p({opacity:0})},[u,s]);(0,n.useLayoutEffect)(()=>{g()},[g]),(0,n.useEffect)(()=>{let e=m.current;if(!e||typeof ResizeObserver>`u`)return;let t=new ResizeObserver(()=>g());return t.observe(e),e.querySelectorAll(`a`).forEach(e=>t.observe(e)),()=>t.disconnect()},[g,e]);let _=e=>(0,i.jsx)(`ul`,{className:(0,r.default)(t.default.list,t.default[s]),children:e.map(e=>(0,i.jsxs)(`li`,{className:(0,r.default)(t.default.item,u===e.href&&t.default.active),children:[(0,i.jsx)(`a`,{href:e.href,className:t.default.link,"aria-current":u===e.href?`location`:void 0,onClick:t=>h(t,e.href),title:typeof e.title==`string`?e.title:void 0,children:e.title}),e.children&&s===`vertical`&&_(e.children)]},e.key))});return(0,i.jsxs)(`div`,{className:(0,r.default)(`wim-anchor`,t.default.root,t.default[s],c),style:l,ref:m,children:[(0,i.jsx)(`div`,{className:t.default.ink,children:(0,i.jsx)(`span`,{className:t.default.inkBall,style:f})}),_(e)]})};exports.Anchor=a,exports.default=a;