wimui 0.54.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/components/data-display/Kanban/Kanban.cjs +1 -1
  2. package/dist/components/data-display/Kanban/Kanban.js +1 -1
  3. package/dist/components/form/CheckboxGroup/CheckboxGroup.cjs +1 -1
  4. package/dist/components/form/CheckboxGroup/CheckboxGroup.js +2 -2
  5. package/dist/components/form/CounterTextarea/CounterTextarea.cjs +1 -1
  6. package/dist/components/form/CounterTextarea/CounterTextarea.js +2 -2
  7. package/dist/components/form/ImageCropper/ImageCropper.cjs +1 -1
  8. package/dist/components/form/ImageCropper/ImageCropper.d.ts +36 -4
  9. package/dist/components/form/ImageCropper/ImageCropper.js +151 -103
  10. package/dist/components/form/ImageCropper/cropImage.cjs +2 -0
  11. package/dist/components/form/ImageCropper/cropImage.d.ts +58 -0
  12. package/dist/components/form/ImageCropper/cropImage.js +36 -0
  13. package/dist/components/form/ImageCropper/image-cropper.module.cjs +1 -1
  14. package/dist/components/form/ImageCropper/image-cropper.module.js +1 -1
  15. package/dist/components/form/RadioGroup/RadioGroup.cjs +1 -1
  16. package/dist/components/form/RadioGroup/RadioGroup.js +2 -2
  17. package/dist/components/form/SwitchGroup/SwitchGroup.cjs +1 -1
  18. package/dist/components/form/SwitchGroup/SwitchGroup.js +2 -2
  19. package/dist/components/form/TagInput/TagInput.cjs +1 -1
  20. package/dist/components/form/TagInput/TagInput.js +37 -36
  21. package/dist/components/form/ToggleGroup/ToggleGroup.cjs +1 -1
  22. package/dist/components/form/ToggleGroup/ToggleGroup.d.ts +2 -0
  23. package/dist/components/form/ToggleGroup/ToggleGroup.js +46 -46
  24. package/dist/components/navigation/Anchor/Anchor.cjs +1 -1
  25. package/dist/components/navigation/Anchor/Anchor.js +54 -45
  26. package/dist/components/overlay/Dialog/Dialog.cjs +1 -1
  27. package/dist/components/overlay/Dialog/Dialog.js +2 -2
  28. package/dist/components/overlay/Drawer/Drawer.cjs +1 -1
  29. package/dist/components/overlay/Drawer/Drawer.js +3 -3
  30. package/dist/i18n/generated/form.cjs +1 -1
  31. package/dist/i18n/generated/form.d.ts +1 -1
  32. package/dist/i18n/generated/form.js +6 -0
  33. package/dist/llms-full.txt +17 -3
  34. package/dist/llms.txt +1 -1
  35. package/dist/locales/en/form.json +2 -0
  36. package/dist/locales/ja/form.json +2 -0
  37. package/dist/locales/pt/form.json +2 -0
  38. package/dist/styles.css +1 -1
  39. package/dist/wimui.umd.css +1 -1
  40. package/dist/wimui.umd.js +5 -5
  41. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/@radix-ui/react-slot/dist/index.cjs"),n=require("../../../i18n/useWimTranslation.cjs"),r=require("../../../i18n/generated/common.cjs"),i=require("../../layout/VisuallyHidden/VisuallyHidden.cjs"),a=require("../../../icon/more-horizontal.cjs"),o=require("../../media/Icon/Icon.cjs"),s=require("./kanban.module.cjs");let c=require("react");c=e.__toESM(c,1);let l=require("classnames");l=e.__toESM(l,1);let u=require("react/jsx-runtime");var d=(0,c.forwardRef)(({columns:e,onMove:i,onCardMove:a,className:o,forceMobileUI:d=!1,children:p,asChild:m=!1,...g},_)=>{let{t:y}=n.useWimTranslation(r.commonNs),[b,x]=(0,c.useState)(null),[S,C]=(0,c.useState)(null),[w,T]=(0,c.useState)(null),E=i||a,D=(e,t,n)=>{x({itemId:t,columnId:n}),e.dataTransfer.setData(`text/plain`,`${n}:${t}`),e.dataTransfer.effectAllowed=`move`},O=(e,t)=>{e.preventDefault(),C(t)},k=(e,t)=>{e.preventDefault(),C(null);let[n,r]=e.dataTransfer.getData(`text/plain`).split(`:`);E?.(r,n,t),x(null)},A=(e,t,n)=>{E?.(e,t,n),T(null)},j=c.default.useMemo(()=>{if(e)return e;let t=[];return c.default.Children.forEach(p,e=>{if(c.default.isValidElement(e)){let n=e.props;typeof n.id==`string`&&typeof n.title==`string`&&t.push({id:n.id,title:n.title,items:[]})}}),t},[p,e]),M=()=>p||(e?e.map(e=>(0,u.jsx)(v,{id:e.id,title:e.title,cardCount:e.items.length,children:e.items.map(e=>(0,u.jsx)(h,{id:e.id,children:e.content},e.id))},e.id)):null),N=m?t.Root:`div`;return(0,u.jsx)(f.Provider,{value:{draggedItem:b,dragOverColumn:S,setDragOverColumn:C,handleDragStart:D,handleDragOver:O,handleDrop:k,handleMobileMove:A,activeMobileMenu:w,setActiveMobileMenu:T,columns:j},children:(0,u.jsx)(N,{...g,ref:_,className:(0,l.default)(`wim-kanban`,s.default.root,d&&s.default.touch,o),role:`region`,"aria-label":y(`a11y.kanban_board`),tabIndex:0,children:(0,u.jsx)(t.Slottable,{children:M()})})})}),f=c.default.createContext(null),p=()=>{let e=c.default.useContext(f);if(!e)throw Error(`Kanban compound components must be used within Kanban`);return e},m=({id:e,title:t,cardCount:a,children:o,className:d})=>{let{dragOverColumn:f,handleDragOver:m,handleDrop:g,setDragOverColumn:v}=p(),{t:y}=n.useWimTranslation(r.commonNs),b=c.default.useId(),x=c.default.Children.toArray(o),S=x.length>0&&x.every(e=>c.default.isValidElement(e)&&e.type===h);return(0,u.jsxs)(`div`,{className:(0,l.default)(s.default.column,{[s.default.dragOver]:f===e},d),role:`group`,"aria-labelledby":t?b:void 0,onDragOver:t=>m(t,e),onDrop:t=>g(t,e),onDragLeave:()=>v(null),children:[(0,u.jsxs)(`div`,{className:s.default.columnHeader,children:[(0,u.jsx)(`div`,{id:b,className:s.default.columnTitle,"aria-hidden":`true`,children:t}),a!==void 0&&(0,u.jsxs)(`div`,{className:s.default.columnCount,children:[(0,u.jsx)(`span`,{"aria-hidden":`true`,children:a}),(0,u.jsx)(i.VisuallyHidden,{children:y(`a11y.kanban_column_count`,{count:a})})]})]}),(0,u.jsx)(`div`,{className:s.default.columnBody,role:S?`list`:void 0,children:(0,u.jsx)(_.Provider,{value:S,children:o})})]})},h=({id:e,children:t,disabled:i,className:d})=>{let{t:f}=n.useWimTranslation(r.commonNs),{draggedItem:m,handleDragStart:h,handleMobileMove:v,activeMobileMenu:y,setActiveMobileMenu:b,columns:x}=p(),S=c.default.useContext(g),C=c.default.useContext(_);return(0,u.jsxs)(`div`,{role:C?`listitem`:void 0,className:(0,l.default)(s.default.card,{[s.default.dragging]:m?.itemId===e,[s.default.disabled]:i},d),draggable:!i,onDragStart:t=>S&&h(t,e,S),children:[(0,u.jsx)(`div`,{className:s.default.cardContent,children:t}),(0,u.jsxs)(`div`,{className:s.default.cardMove,children:[(0,u.jsx)(`button`,{type:`button`,className:s.default.cardMoveBtn,onClick:()=>b(y===e?null:e),"aria-label":f(`a11y.move_card`),disabled:i,children:(0,u.jsx)(o.Icon,{component:a.default,size:`sm`})}),y===e&&(0,u.jsx)(`div`,{className:s.default.cardMoveMenu,role:`listbox`,"aria-label":f(`a11y.move_to_column`),children:x.filter(e=>e.id!==S).map(t=>(0,u.jsx)(`button`,{type:`button`,className:s.default.cardMoveOption,onClick:()=>S&&v(e,S,t.id),role:`option`,"aria-selected":!1,children:t.title},t.id))})]})]})},g=c.default.createContext(null),_=c.default.createContext(!1),v=e=>(0,u.jsx)(g.Provider,{value:e.id,children:(0,u.jsx)(m,{...e})}),y=d;y.Column=v,y.Card=h,d.displayName=`Kanban`,y.displayName=`KanbanBoard`,m.displayName=`KanbanColumn`,h.displayName=`KanbanCard`,v.displayName=`KanbanColumnWrapper`,exports.Kanban=d,exports.KanbanBoard=y,exports.default=y,exports.KanbanCard=h,exports.KanbanColumn=m;
2
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/@radix-ui/react-slot/dist/index.cjs"),n=require("../../../i18n/useWimTranslation.cjs"),r=require("../../../i18n/generated/common.cjs"),i=require("../../layout/VisuallyHidden/VisuallyHidden.cjs"),a=require("../../../icon/more-horizontal.cjs"),o=require("../../media/Icon/Icon.cjs"),s=require("./kanban.module.cjs");let c=require("react");c=e.__toESM(c,1);let l=require("classnames");l=e.__toESM(l,1);let u=require("react/jsx-runtime");var d=(0,c.forwardRef)(({columns:e,onMove:i,onCardMove:a,className:o,forceMobileUI:d=!1,children:p,asChild:m=!1,...g},_)=>{let{t:y}=n.useWimTranslation(r.commonNs),[b,x]=(0,c.useState)(null),[S,C]=(0,c.useState)(null),[w,T]=(0,c.useState)(null),E=i||a,D=(e,t,n)=>{x({itemId:t,columnId:n}),e.dataTransfer.setData(`text/plain`,`${n}:${t}`),e.dataTransfer.effectAllowed=`move`},O=(e,t)=>{e.preventDefault(),C(t)},k=(e,t)=>{e.preventDefault(),C(null);let[n,r]=e.dataTransfer.getData(`text/plain`).split(`:`);E?.(r,n,t),x(null)},A=(e,t,n)=>{E?.(e,t,n),T(null)},j=c.default.useMemo(()=>{if(e)return e;let t=[];return c.default.Children.forEach(p,e=>{if(c.default.isValidElement(e)){let n=e.props;typeof n.id==`string`&&typeof n.title==`string`&&t.push({id:n.id,title:n.title,items:[]})}}),t},[p,e]),M=()=>p||(e?e.map(e=>(0,u.jsx)(v,{id:e.id,title:e.title,cardCount:e.items.length,children:e.items.map(e=>(0,u.jsx)(h,{id:e.id,children:e.content},e.id))},e.id)):null),N=m?t.Root:`div`;return(0,u.jsx)(f.Provider,{value:{draggedItem:b,dragOverColumn:S,setDragOverColumn:C,handleDragStart:D,handleDragOver:O,handleDrop:k,handleMobileMove:A,activeMobileMenu:w,setActiveMobileMenu:T,columns:j},children:(0,u.jsx)(N,{...g,ref:_,className:(0,l.default)(`wim-kanban`,s.default.root,d&&s.default.touch,o),role:`region`,"aria-label":g[`aria-labelledby`]?void 0:g[`aria-label`]??y(`a11y.kanban_board`),tabIndex:0,children:(0,u.jsx)(t.Slottable,{children:M()})})})}),f=c.default.createContext(null),p=()=>{let e=c.default.useContext(f);if(!e)throw Error(`Kanban compound components must be used within Kanban`);return e},m=({id:e,title:t,cardCount:a,children:o,className:d})=>{let{dragOverColumn:f,handleDragOver:m,handleDrop:g,setDragOverColumn:v}=p(),{t:y}=n.useWimTranslation(r.commonNs),b=c.default.useId(),x=c.default.Children.toArray(o),S=x.length>0&&x.every(e=>c.default.isValidElement(e)&&e.type===h);return(0,u.jsxs)(`div`,{className:(0,l.default)(s.default.column,{[s.default.dragOver]:f===e},d),role:`group`,"aria-labelledby":t?b:void 0,onDragOver:t=>m(t,e),onDrop:t=>g(t,e),onDragLeave:()=>v(null),children:[(0,u.jsxs)(`div`,{className:s.default.columnHeader,children:[(0,u.jsx)(`div`,{id:b,className:s.default.columnTitle,"aria-hidden":`true`,children:t}),a!==void 0&&(0,u.jsxs)(`div`,{className:s.default.columnCount,children:[(0,u.jsx)(`span`,{"aria-hidden":`true`,children:a}),(0,u.jsx)(i.VisuallyHidden,{children:y(`a11y.kanban_column_count`,{count:a})})]})]}),(0,u.jsx)(`div`,{className:s.default.columnBody,role:S?`list`:void 0,children:(0,u.jsx)(_.Provider,{value:S,children:o})})]})},h=({id:e,children:t,disabled:i,className:d})=>{let{t:f}=n.useWimTranslation(r.commonNs),{draggedItem:m,handleDragStart:h,handleMobileMove:v,activeMobileMenu:y,setActiveMobileMenu:b,columns:x}=p(),S=c.default.useContext(g),C=c.default.useContext(_);return(0,u.jsxs)(`div`,{role:C?`listitem`:void 0,className:(0,l.default)(s.default.card,{[s.default.dragging]:m?.itemId===e,[s.default.disabled]:i},d),draggable:!i,onDragStart:t=>S&&h(t,e,S),children:[(0,u.jsx)(`div`,{className:s.default.cardContent,children:t}),(0,u.jsxs)(`div`,{className:s.default.cardMove,children:[(0,u.jsx)(`button`,{type:`button`,className:s.default.cardMoveBtn,onClick:()=>b(y===e?null:e),"aria-label":f(`a11y.move_card`),disabled:i,children:(0,u.jsx)(o.Icon,{component:a.default,size:`sm`})}),y===e&&(0,u.jsx)(`div`,{className:s.default.cardMoveMenu,role:`listbox`,"aria-label":f(`a11y.move_to_column`),children:x.filter(e=>e.id!==S).map(t=>(0,u.jsx)(`button`,{type:`button`,className:s.default.cardMoveOption,onClick:()=>S&&v(e,S,t.id),role:`option`,"aria-selected":!1,children:t.title},t.id))})]})]})},g=c.default.createContext(null),_=c.default.createContext(!1),v=e=>(0,u.jsx)(g.Provider,{value:e.id,children:(0,u.jsx)(m,{...e})}),y=d;y.Column=v,y.Card=h,d.displayName=`Kanban`,y.displayName=`KanbanBoard`,m.displayName=`KanbanColumn`,h.displayName=`KanbanCard`,v.displayName=`KanbanColumnWrapper`,exports.Kanban=d,exports.KanbanBoard=y,exports.default=y,exports.KanbanCard=h,exports.KanbanColumn=m;
@@ -64,7 +64,7 @@ var m = l(({ columns: i, onMove: a, onCardMove: o, className: l, forceMobileUI:
64
64
  ref: y,
65
65
  className: d("wim-kanban", s.root, p && s.touch, l),
66
66
  role: "region",
67
- "aria-label": b("a11y.kanban_board"),
67
+ "aria-label": _["aria-labelledby"] ? void 0 : _["aria-label"] ?? b("a11y.kanban_board"),
68
68
  tabIndex: 0,
69
69
  children: /* @__PURE__ */ f(t, { children: P() })
70
70
  })
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/@radix-ui/react-slot/dist/index.cjs"),n=require("../FieldTemplate/FieldTemplate.cjs"),r=require("../Checkbox/Checkbox.cjs"),i=require("./checkbox-group.module.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("classnames");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=(0,a.forwardRef)(({options:e,value:c,defaultValue:l=[],onChange:u,direction:d=`vertical`,name:f,className:p,label:m,error:h,required:g,disabled:_,asChild:v=!1,children:y,...b},x)=>{let S=c!==void 0,[C,w]=(0,a.useState)(l),T=`wim-checkbox-group-${(0,a.useId)()}`,E=`${T}-label`,D=h?`${T}-error`:void 0,O=S?c:C,k=(e,t)=>{let n;n=t?[...O,e]:O.filter(t=>t!==e),S||w(n),u&&u(n)};return(0,s.jsx)(n.FieldTemplate,{label:m,error:h,required:g,labelId:E,errorId:D,className:p,children:(0,s.jsxs)(v?t.Root:`div`,{...b,ref:x,className:(0,o.default)(`wim-checkbox-group`,i.default.root,d===`horizontal`&&i.default.horizontal),role:`group`,"aria-labelledby":m?E:void 0,"aria-describedby":D,children:[(0,s.jsx)(t.Slottable,{children:e.map(e=>(0,s.jsx)(r.Checkbox,{value:e.value,checked:O.includes(e.value),disabled:_||e.disabled,error:!!h,name:f,onChange:t=>k(e.value,t.target.checked),children:e.label},e.value))}),y]})})});c.displayName=`CheckboxGroup`,exports.CheckboxGroup=c,exports.default=c;
2
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/@radix-ui/react-slot/dist/index.cjs"),n=require("../FieldTemplate/FieldTemplate.cjs"),r=require("../Checkbox/Checkbox.cjs"),i=require("./checkbox-group.module.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("classnames");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=(0,a.forwardRef)(({options:e,value:c,defaultValue:l=[],onChange:u,direction:d=`vertical`,name:f,className:p,label:m,error:h,required:g,disabled:_,asChild:v=!1,children:y,...b},x)=>{let S=c!==void 0,[C,w]=(0,a.useState)(l),T=`wim-checkbox-group-${(0,a.useId)()}`,E=`${T}-label`,D=h?`${T}-error`:void 0,O=S?c:C,k=(e,t)=>{let n;n=t?[...O,e]:O.filter(t=>t!==e),S||w(n),u&&u(n)};return(0,s.jsx)(n.FieldTemplate,{label:m,error:h,required:g,labelId:E,errorId:D,className:p,children:(0,s.jsxs)(v?t.Root:`div`,{...b,ref:x,className:(0,o.default)(`wim-checkbox-group`,i.default.root,d===`horizontal`&&i.default.horizontal),role:`group`,"aria-labelledby":m?E:b[`aria-labelledby`],"aria-describedby":[b[`aria-describedby`],D].filter(Boolean).join(` `)||void 0,children:[(0,s.jsx)(t.Slottable,{children:e.map(e=>(0,s.jsx)(r.Checkbox,{value:e.value,checked:O.includes(e.value),disabled:_||e.disabled,error:!!h,name:f,onChange:t=>k(e.value,t.target.checked),children:e.label},e.value))}),y]})})});c.displayName=`CheckboxGroup`,exports.CheckboxGroup=c,exports.default=c;
@@ -24,8 +24,8 @@ var d = a(({ options: a, value: d, defaultValue: f = [], onChange: p, direction:
24
24
  ref: w,
25
25
  className: c("wim-checkbox-group", i.root, m === "horizontal" && i.horizontal),
26
26
  role: "group",
27
- "aria-labelledby": _ ? k : void 0,
28
- "aria-describedby": A,
27
+ "aria-labelledby": _ ? k : C["aria-labelledby"],
28
+ "aria-describedby": [C["aria-describedby"], A].filter(Boolean).join(" ") || void 0,
29
29
  children: [/* @__PURE__ */ l(t, { children: a.map((e) => /* @__PURE__ */ l(r, {
30
30
  value: e.value,
31
31
  checked: j.includes(e.value),
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../FieldTemplate/FieldTemplate.cjs"),n=require("../Textarea/Textarea.cjs"),r=require("../../_internal/FieldCharacterCount/FieldCharacterCount.cjs"),i=require("./counter-textarea.module.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("classnames");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=a.default.forwardRef(({showCount:e=!0,counterPosition:c=`bottom`,maxLength:l,onChange:u,value:d,defaultValue:f,className:p,fullWidth:m=!1,children:h,...g},_)=>{let[v,y]=(0,a.useState)(f??``),b=String(d===void 0?v:d).length,x=(0,a.useCallback)(e=>{d===void 0&&y(e.target.value),u?.(e)},[d,u]),S=a.default.useId(),C=g.id||`wim-counter-textarea-${S}`,w=g.label?`${C}-label`:void 0,T=g.error?`${C}-error`:void 0;return(0,s.jsx)(t.FieldTemplate,{label:g.label,error:g.error,required:g.required,layout:g.layout,labelId:w,htmlFor:C,errorId:T,className:(0,o.default)(`wim-counter-textarea`,p),children:(0,s.jsxs)(`div`,{className:(0,o.default)(i.default.container,c===`overlay`&&i.default[`container--overlay`],m&&i.default.fullWidth),children:[(0,s.jsx)(n.Textarea,{...g,ref:_,id:C,value:d,defaultValue:f,onChange:x,maxLength:l,fullWidth:m,label:void 0,error:void 0,className:i.default.textarea,"aria-labelledby":w,"aria-describedby":T,children:h}),e&&(0,s.jsx)(r.FieldCharacterCount,{count:b,maxLength:l,className:i.default.counter})]})})});c.displayName=`CounterTextarea`,exports.CounterTextarea=c;
2
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../FieldTemplate/FieldTemplate.cjs"),n=require("../Textarea/Textarea.cjs"),r=require("../../_internal/FieldCharacterCount/FieldCharacterCount.cjs"),i=require("./counter-textarea.module.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("classnames");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=a.default.forwardRef(({showCount:e=!0,counterPosition:c=`bottom`,maxLength:l,onChange:u,value:d,defaultValue:f,className:p,fullWidth:m=!1,children:h,...g},_)=>{let[v,y]=(0,a.useState)(f??``),b=String(d===void 0?v:d).length,x=(0,a.useCallback)(e=>{d===void 0&&y(e.target.value),u?.(e)},[d,u]),S=a.default.useId(),C=g.id||`wim-counter-textarea-${S}`,w=g.label?`${C}-label`:void 0,T=g.error?`${C}-error`:void 0;return(0,s.jsx)(t.FieldTemplate,{label:g.label,error:g.error,required:g.required,layout:g.layout,labelId:w,htmlFor:C,errorId:T,className:(0,o.default)(`wim-counter-textarea`,p),children:(0,s.jsxs)(`div`,{className:(0,o.default)(i.default.container,c===`overlay`&&i.default[`container--overlay`],m&&i.default.fullWidth),children:[(0,s.jsx)(n.Textarea,{...g,ref:_,id:C,value:d,defaultValue:f,onChange:x,maxLength:l,fullWidth:m,label:void 0,error:void 0,className:i.default.textarea,"aria-labelledby":w??g[`aria-labelledby`],"aria-describedby":[g[`aria-describedby`],T].filter(Boolean).join(` `)||void 0,children:h}),e&&(0,s.jsx)(r.FieldCharacterCount,{count:b,maxLength:l,className:i.default.counter})]})})});c.displayName=`CounterTextarea`,exports.CounterTextarea=c;
@@ -34,8 +34,8 @@ var u = i.forwardRef(({ showCount: u = !0, counterPosition: d = "bottom", maxLen
34
34
  label: void 0,
35
35
  error: void 0,
36
36
  className: r.textarea,
37
- "aria-labelledby": D,
38
- "aria-describedby": O,
37
+ "aria-labelledby": D ?? y["aria-labelledby"],
38
+ "aria-describedby": [y["aria-describedby"], O].filter(Boolean).join(" ") || void 0,
39
39
  children: v
40
40
  }), u && /* @__PURE__ */ c(n, {
41
41
  count: C,
@@ -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("../Button/Button.cjs"),i=require("../../../i18n/generated/form.cjs"),a=require("../Slider/Slider.cjs"),o=require("../IconButton/IconButton.cjs"),s=require("../../overlay/Dialog/Dialog.cjs"),c=require("./image-cropper.module.cjs");let l=require("react");l=e.__toESM(l,1);let u=require("classnames");u=e.__toESM(u,1);let d=require("react/jsx-runtime");var f=l.default.forwardRef(({src:e,aspectRatio:f=1,circular:p=!1,onCrop:m,showRotation:h=!0,showZoom:g=!0,showApplyButton:_=!0,applyLabel:v,onApply:y,className:b,...x},S)=>{let{t:C}=t.useWimTranslation([i.formNs,n.commonNs]),[w,T]=(0,l.useState)(1),[E,D]=(0,l.useState)(0),[O,k]=(0,l.useState)({x:0,y:0}),[A,j]=(0,l.useState)(!1),[M,N]=(0,l.useState)({x:0,y:0}),[P,F]=(0,l.useState)(!1),I=(0,l.useRef)(null),L=(0,l.useRef)(null);(0,l.useEffect)(()=>{k({x:0,y:0}),T(1),D(0)},[e]);let R=e=>{j(!0),N({x:e.clientX-O.x,y:e.clientY-O.y})},z=(0,l.useCallback)(e=>{A&&k({x:e.clientX-M.x,y:e.clientY-M.y})},[A,M]),B=(0,l.useCallback)(()=>{j(!1)},[]);(0,l.useEffect)(()=>(A?(window.addEventListener(`mousemove`,z),window.addEventListener(`mouseup`,B)):(window.removeEventListener(`mousemove`,z),window.removeEventListener(`mouseup`,B)),()=>{window.removeEventListener(`mousemove`,z),window.removeEventListener(`mouseup`,B)}),[A,z,B]);let V=()=>{D(e=>(e+90)%360)},H=()=>{F(!0)},U=()=>{let t=e||``;m?.(t),y?.(t),F(!1)};return e?(0,d.jsxs)(`div`,{ref:S,className:(0,u.default)(`wim-image-cropper`,c.default.root,b),...x,children:[(0,d.jsxs)(`div`,{ref:L,className:c.default.viewer,onMouseDown:R,role:`presentation`,children:[(0,d.jsx)(`div`,{className:c.default.imageContainer,children:(0,d.jsx)(`img`,{ref:I,src:e,alt:C(`a11y.crop_target`),className:c.default.image,style:{transform:`translate(${O.x}px, ${O.y}px) rotate(${E}deg) scale(${w})`},draggable:!1})}),(0,d.jsx)(`div`,{className:c.default.overlay,children:(0,d.jsx)(`div`,{className:(0,u.default)(c.default.cropArea,{[c.default.circular]:p}),style:{aspectRatio:f}})})]}),(0,d.jsxs)(`div`,{className:c.default.controls,children:[g&&(0,d.jsx)(`div`,{className:c.default.zoomControl,children:(0,d.jsx)(a.Slider,{min:1,max:3,step:.1,value:w,onChange:e=>T(e),label:C(`image_cropper.zoom`),styles:{root:c.default.zoomSlider}})}),h&&(0,d.jsx)(`div`,{className:c.default.rotationControl,children:(0,d.jsx)(o.IconButton,{iconName:`RefreshIcon`,onClick:V,"aria-label":C(`image_cropper.rotate`),variant:`outline`,size:`sm`})}),_&&(0,d.jsx)(`div`,{className:c.default.applyControl,children:(0,d.jsx)(r.Button,{onClick:H,size:`sm`,variant:`solid`,children:v||C(`image_cropper.apply`)})})]}),(0,d.jsx)(s.Dialog,{open:P,onOpenChange:F,children:(0,d.jsxs)(s.DialogContent,{children:[(0,d.jsx)(s.DialogHeader,{children:(0,d.jsx)(s.DialogTitle,{children:C(`image_cropper.confirm_title`)})}),(0,d.jsx)(s.DialogDescription,{children:C(`image_cropper.confirm_message`)}),(0,d.jsxs)(s.DialogFooter,{children:[(0,d.jsx)(s.DialogClose,{asChild:!0,children:(0,d.jsx)(r.Button,{variant:`ghost`,children:C(`image_cropper.cancel`)})}),(0,d.jsx)(r.Button,{onClick:U,variant:`solid`,children:C(`image_cropper.confirm`)})]})]})})]}):(0,d.jsx)(`div`,{ref:S,className:(0,u.default)(`wim-image-cropper`,c.default.root,c.default.empty,b),...x,children:(0,d.jsx)(`div`,{className:c.default.emptyContent,children:C(`image_cropper.no_image`)})})});f.displayName=`ImageCropper`,exports.ImageCropper=f;
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=>{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)(()=>(z?(window.addEventListener(`mousemove`,X),window.addEventListener(`mouseup`,Z)):(window.removeEventListener(`mousemove`,X),window.removeEventListener(`mouseup`,Z)),()=>{window.removeEventListener(`mousemove`,X),window.removeEventListener(`mouseup`,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,onMouseDown: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.
@@ -1,152 +1,200 @@
1
1
  "use client";
2
2
  import { useWimTranslation as e } from "../../../i18n/useWimTranslation.js";
3
3
  import { commonNs as t } from "../../../i18n/generated/common.js";
4
- import { Button as n } from "../Button/Button.js";
5
- import { formNs as r } from "../../../i18n/generated/form.js";
6
- import { Slider as i } from "../Slider/Slider.js";
7
- import { IconButton as a } from "../IconButton/IconButton.js";
8
- import { Dialog as o, DialogClose as s, DialogContent as c, DialogDescription as l, DialogFooter as u, DialogHeader as d, DialogTitle as f } from "../../overlay/Dialog/Dialog.js";
9
- import p from "./image-cropper.module.js";
10
- import m, { useCallback as h, useEffect as g, useRef as _, useState as v } from "react";
11
- import y from "classnames";
12
- import { jsx as b, jsxs as x } from "react/jsx-runtime";
4
+ import { VisuallyHidden as n } from "../../layout/VisuallyHidden/VisuallyHidden.js";
5
+ import { Button as r } from "../Button/Button.js";
6
+ import { formNs as i } from "../../../i18n/generated/form.js";
7
+ import { Slider as a } from "../Slider/Slider.js";
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 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";
13
15
  //#region src/components/form/ImageCropper/ImageCropper.tsx
14
- var S = m.forwardRef(({ src: m, aspectRatio: S = 1, circular: C = !1, onCrop: w, showRotation: T = !0, showZoom: E = !0, showApplyButton: D = !0, applyLabel: O, onApply: k, className: A, ...j }, M) => {
15
- let { t: N } = e([r, t]), [P, F] = v(1), [I, L] = v(0), [R, z] = v({
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({
16
18
  x: 0,
17
19
  y: 0
18
- }), [B, V] = v(!1), [H, U] = v({
20
+ }), [W, G] = b(!1), [K, q] = b({
19
21
  x: 0,
20
22
  y: 0
21
- }), [W, G] = v(!1), K = _(null), q = _(null);
22
- g(() => {
23
- z({
23
+ }), [se, J] = b(!1), Y = y(null), ce = y(null), X = y(null), Z = v();
24
+ _(() => {
25
+ U({
24
26
  x: 0,
25
27
  y: 0
26
- }), F(1), L(0);
27
- }, [m]);
28
- let J = (e) => {
29
- V(!0), U({
30
- x: e.clientX - R.x,
31
- y: e.clientY - R.y
32
- });
33
- }, Y = h((e) => {
34
- B && z({
28
+ }), z(1), V(0);
29
+ }, [h]);
30
+ let le = (e) => {
31
+ G(!0), q({
35
32
  x: e.clientX - H.x,
36
33
  y: e.clientY - H.y
37
34
  });
38
- }, [B, H]), X = h(() => {
39
- V(!1);
35
+ }, Q = g((e) => {
36
+ W && U({
37
+ x: e.clientX - K.x,
38
+ y: e.clientY - K.y
39
+ });
40
+ }, [W, K]), $ = g(() => {
41
+ G(!1);
40
42
  }, []);
41
- g(() => (B ? (window.addEventListener("mousemove", Y), window.addEventListener("mouseup", X)) : (window.removeEventListener("mousemove", Y), window.removeEventListener("mouseup", X)), () => {
42
- window.removeEventListener("mousemove", Y), window.removeEventListener("mouseup", X);
43
+ _(() => (W ? (window.addEventListener("mousemove", Q), window.addEventListener("mouseup", $)) : (window.removeEventListener("mousemove", Q), window.removeEventListener("mouseup", $)), () => {
44
+ window.removeEventListener("mousemove", Q), window.removeEventListener("mouseup", $);
43
45
  }), [
44
- B,
45
- Y,
46
- X
46
+ W,
47
+ Q,
48
+ $
47
49
  ]);
48
- let Z = () => {
49
- L((e) => (e + 90) % 360);
50
- }, Q = () => {
51
- G(!0);
52
- }, $ = () => {
53
- let e = m || "";
54
- w?.(e), k?.(e), G(!1);
50
+ let ue = (e) => {
51
+ let t = e.shiftKey ? T : w, n = {
52
+ ArrowLeft: [-t, 0],
53
+ ArrowRight: [t, 0],
54
+ ArrowUp: [0, -t],
55
+ ArrowDown: [0, t]
56
+ }[e.key];
57
+ n ? (e.preventDefault(), U((e) => ({
58
+ x: e.x + n[0],
59
+ y: e.y + n[1]
60
+ }))) : e.key === "Home" && (e.preventDefault(), U({
61
+ x: 0,
62
+ y: 0
63
+ }));
64
+ }, de = () => {
65
+ V((e) => (e + 90) % 360);
66
+ }, fe = () => {
67
+ J(!0);
68
+ }, pe = () => {
69
+ let e = Y.current, t = X.current;
70
+ if (J(!1), !e || !t) return;
71
+ let n = {
72
+ x: H.x,
73
+ y: H.y,
74
+ zoom: R,
75
+ rotation: B,
76
+ frameWidth: t.clientWidth,
77
+ frameHeight: t.clientHeight,
78
+ layoutWidth: e.offsetWidth,
79
+ layoutHeight: e.offsetHeight,
80
+ naturalWidth: e.naturalWidth,
81
+ naturalHeight: e.naturalHeight,
82
+ maxOutputSize: A
83
+ };
84
+ try {
85
+ let { dataUrl: t, detail: r } = f(e, n, j, M);
86
+ re?.(t, r), O?.(t, r);
87
+ } catch (e) {
88
+ k?.(e instanceof Error ? e : Error(String(e)), p(n).detail);
89
+ }
55
90
  };
56
- return m ? /* @__PURE__ */ x("div", {
57
- ref: M,
58
- className: y("wim-image-cropper", p.root, A),
59
- ...j,
91
+ return h ? /* @__PURE__ */ C("div", {
92
+ ref: I,
93
+ className: x("wim-image-cropper", m.root, P),
94
+ ...F,
60
95
  children: [
61
- /* @__PURE__ */ x("div", {
62
- ref: q,
63
- className: p.viewer,
64
- onMouseDown: J,
65
- role: "presentation",
66
- children: [/* @__PURE__ */ b("div", {
67
- className: p.imageContainer,
68
- children: /* @__PURE__ */ b("img", {
69
- ref: K,
70
- src: m,
71
- alt: N("a11y.crop_target"),
72
- className: p.image,
73
- style: { transform: `translate(${R.x}px, ${R.y}px) rotate(${I}deg) scale(${P})` },
74
- draggable: !1
75
- })
76
- }), /* @__PURE__ */ b("div", {
77
- className: p.overlay,
78
- children: /* @__PURE__ */ b("div", {
79
- className: y(p.cropArea, { [p.circular]: C }),
80
- style: { aspectRatio: S }
96
+ /* @__PURE__ */ C("div", {
97
+ ref: ce,
98
+ className: m.viewer,
99
+ onMouseDown: le,
100
+ onKeyDown: ue,
101
+ role: "application",
102
+ tabIndex: 0,
103
+ "aria-label": L("image_cropper.position_label"),
104
+ "aria-describedby": Z,
105
+ children: [
106
+ /* @__PURE__ */ S(n, {
107
+ id: Z,
108
+ children: L("image_cropper.position_hint")
109
+ }),
110
+ /* @__PURE__ */ S("div", {
111
+ className: m.imageContainer,
112
+ children: /* @__PURE__ */ S("img", {
113
+ ref: Y,
114
+ src: h,
115
+ alt: L("a11y.crop_target"),
116
+ crossOrigin: N,
117
+ className: m.image,
118
+ style: { transform: `translate(${H.x}px, ${H.y}px) rotate(${B}deg) scale(${R})` },
119
+ draggable: !1
120
+ })
121
+ }),
122
+ /* @__PURE__ */ S("div", {
123
+ className: m.overlay,
124
+ children: /* @__PURE__ */ S("div", {
125
+ ref: X,
126
+ className: x(m.cropArea, { [m.circular]: ne }),
127
+ style: { aspectRatio: E }
128
+ })
81
129
  })
82
- })]
130
+ ]
83
131
  }),
84
- /* @__PURE__ */ x("div", {
85
- className: p.controls,
132
+ /* @__PURE__ */ C("div", {
133
+ className: m.controls,
86
134
  children: [
87
- E && /* @__PURE__ */ b("div", {
88
- className: p.zoomControl,
89
- children: /* @__PURE__ */ b(i, {
135
+ ae && /* @__PURE__ */ S("div", {
136
+ className: m.zoomControl,
137
+ children: /* @__PURE__ */ S(a, {
90
138
  min: 1,
91
139
  max: 3,
92
140
  step: .1,
93
- value: P,
94
- onChange: (e) => F(e),
95
- label: N("image_cropper.zoom"),
96
- styles: { root: p.zoomSlider }
141
+ value: R,
142
+ onChange: (e) => z(e),
143
+ label: L("image_cropper.zoom"),
144
+ styles: { root: m.zoomSlider }
97
145
  })
98
146
  }),
99
- T && /* @__PURE__ */ b("div", {
100
- className: p.rotationControl,
101
- children: /* @__PURE__ */ b(a, {
147
+ ie && /* @__PURE__ */ S("div", {
148
+ className: m.rotationControl,
149
+ children: /* @__PURE__ */ S(o, {
102
150
  iconName: "RefreshIcon",
103
- onClick: Z,
104
- "aria-label": N("image_cropper.rotate"),
151
+ onClick: de,
152
+ "aria-label": L("image_cropper.rotate"),
105
153
  variant: "outline",
106
154
  size: "sm"
107
155
  })
108
156
  }),
109
- D && /* @__PURE__ */ b("div", {
110
- className: p.applyControl,
111
- children: /* @__PURE__ */ b(n, {
112
- onClick: Q,
157
+ oe && /* @__PURE__ */ S("div", {
158
+ className: m.applyControl,
159
+ children: /* @__PURE__ */ S(r, {
160
+ onClick: fe,
113
161
  size: "sm",
114
162
  variant: "solid",
115
- children: O || N("image_cropper.apply")
163
+ children: D || L("image_cropper.apply")
116
164
  })
117
165
  })
118
166
  ]
119
167
  }),
120
- /* @__PURE__ */ b(o, {
121
- open: W,
122
- onOpenChange: G,
123
- children: /* @__PURE__ */ x(c, { children: [
124
- /* @__PURE__ */ b(d, { children: /* @__PURE__ */ b(f, { children: N("image_cropper.confirm_title") }) }),
125
- /* @__PURE__ */ b(l, { children: N("image_cropper.confirm_message") }),
126
- /* @__PURE__ */ x(u, { children: [/* @__PURE__ */ b(s, {
168
+ /* @__PURE__ */ S(s, {
169
+ open: se,
170
+ onOpenChange: J,
171
+ children: /* @__PURE__ */ C(l, { children: [
172
+ /* @__PURE__ */ S(d, { children: /* @__PURE__ */ S(te, { children: L("image_cropper.confirm_title") }) }),
173
+ /* @__PURE__ */ S(u, { children: L("image_cropper.confirm_message") }),
174
+ /* @__PURE__ */ C(ee, { children: [/* @__PURE__ */ S(c, {
127
175
  asChild: !0,
128
- children: /* @__PURE__ */ b(n, {
176
+ children: /* @__PURE__ */ S(r, {
129
177
  variant: "ghost",
130
- children: N("image_cropper.cancel")
178
+ children: L("image_cropper.cancel")
131
179
  })
132
- }), /* @__PURE__ */ b(n, {
133
- onClick: $,
180
+ }), /* @__PURE__ */ S(r, {
181
+ onClick: pe,
134
182
  variant: "solid",
135
- children: N("image_cropper.confirm")
183
+ children: L("image_cropper.confirm")
136
184
  })] })
137
185
  ] })
138
186
  })
139
187
  ]
140
- }) : /* @__PURE__ */ b("div", {
141
- ref: M,
142
- className: y("wim-image-cropper", p.root, p.empty, A),
143
- ...j,
144
- children: /* @__PURE__ */ b("div", {
145
- className: p.emptyContent,
146
- children: N("image_cropper.no_image")
188
+ }) : /* @__PURE__ */ S("div", {
189
+ ref: I,
190
+ className: x("wim-image-cropper", m.root, m.empty, P),
191
+ ...F,
192
+ children: /* @__PURE__ */ S("div", {
193
+ className: m.emptyContent,
194
+ children: L("image_cropper.no_image")
147
195
  })
148
196
  });
149
197
  });
150
- S.displayName = "ImageCropper";
198
+ E.displayName = "ImageCropper";
151
199
  //#endregion
152
- export { S as ImageCropper };
200
+ 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_13usn_3`,t=`_viewer_13usn_13`,n=`_imageContainer_13usn_24`,r=`_image_13usn_24`,i=`_overlay_13usn_36`,a=`_cropArea_13usn_45`,o=`_circular_13usn_51`,s=`_controls_13usn_54`,c=`_zoomControl_13usn_62`,l=`_zoomSlider_13usn_65`,u=`_rotationControl_13usn_68`,d=`_applyControl_13usn_71`,f=`_empty_13usn_75`,p=`_emptyContent_13usn_84`,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_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;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  //#region src/components/form/ImageCropper/image-cropper.module.scss
3
- var e = "_root_13usn_3", t = "_viewer_13usn_13", n = "_imageContainer_13usn_24", r = "_image_13usn_24", i = "_overlay_13usn_36", a = "_cropArea_13usn_45", o = "_circular_13usn_51", s = "_controls_13usn_54", c = "_zoomControl_13usn_62", l = "_zoomSlider_13usn_65", u = "_rotationControl_13usn_68", d = "_applyControl_13usn_71", f = "_empty_13usn_75", p = "_emptyContent_13usn_84", m = {
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 = {
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("../../../node_modules/@radix-ui/react-slot/dist/index.cjs"),n=require("../FieldTemplate/FieldTemplate.cjs"),r=require("../Radio/Radio.cjs"),i=require("./radio-group.module.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("classnames");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=(0,a.forwardRef)(({options:e,value:c,defaultValue:l,onChange:u,direction:d=`vertical`,name:f,className:p,label:m,error:h,required:g,disabled:_,asChild:v=!1,children:y,...b},x)=>{let S=c!==void 0,[C,w]=(0,a.useState)(l),T=`wim-radio-group-${(0,a.useId)()}`,E=`${T}-label`,D=h?`${T}-error`:void 0,O=S?c:C,k=e=>{S||w(e),u&&u(e)};return(0,s.jsx)(n.FieldTemplate,{label:m,error:h,required:g,labelId:E,errorId:D,className:p,children:(0,s.jsxs)(v?t.Root:`div`,{...b,ref:x,className:(0,o.default)(`wim-radio-group`,i.default.root,d===`horizontal`&&i.default.horizontal),role:`radiogroup`,"aria-labelledby":m?E:void 0,"aria-describedby":D,"aria-required":g,"aria-invalid":!!h,children:[(0,s.jsx)(t.Slottable,{children:e.map(e=>(0,s.jsx)(r.Radio,{value:e.value,checked:O===e.value,disabled:_||e.disabled,error:!!h,name:f,onChange:()=>k(e.value),children:e.label},e.value))}),y]})})});c.displayName=`RadioGroup`,exports.RadioGroup=c,exports.default=c;
2
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/@radix-ui/react-slot/dist/index.cjs"),n=require("../FieldTemplate/FieldTemplate.cjs"),r=require("../Radio/Radio.cjs"),i=require("./radio-group.module.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("classnames");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=(0,a.forwardRef)(({options:e,value:c,defaultValue:l,onChange:u,direction:d=`vertical`,name:f,className:p,label:m,error:h,required:g,disabled:_,asChild:v=!1,children:y,...b},x)=>{let S=c!==void 0,[C,w]=(0,a.useState)(l),T=`wim-radio-group-${(0,a.useId)()}`,E=`${T}-label`,D=h?`${T}-error`:void 0,O=S?c:C,k=e=>{S||w(e),u&&u(e)};return(0,s.jsx)(n.FieldTemplate,{label:m,error:h,required:g,labelId:E,errorId:D,className:p,children:(0,s.jsxs)(v?t.Root:`div`,{...b,ref:x,className:(0,o.default)(`wim-radio-group`,i.default.root,d===`horizontal`&&i.default.horizontal),role:`radiogroup`,"aria-labelledby":m?E:b[`aria-labelledby`],"aria-describedby":[b[`aria-describedby`],D].filter(Boolean).join(` `)||void 0,"aria-required":g,"aria-invalid":!!h,children:[(0,s.jsx)(t.Slottable,{children:e.map(e=>(0,s.jsx)(r.Radio,{value:e.value,checked:O===e.value,disabled:_||e.disabled,error:!!h,name:f,onChange:()=>k(e.value),children:e.label},e.value))}),y]})})});c.displayName=`RadioGroup`,exports.RadioGroup=c,exports.default=c;
@@ -23,8 +23,8 @@ var d = a(({ options: a, value: d, defaultValue: f, onChange: p, direction: m =
23
23
  ref: w,
24
24
  className: c("wim-radio-group", i.root, m === "horizontal" && i.horizontal),
25
25
  role: "radiogroup",
26
- "aria-labelledby": _ ? k : void 0,
27
- "aria-describedby": A,
26
+ "aria-labelledby": _ ? k : C["aria-labelledby"],
27
+ "aria-describedby": [C["aria-describedby"], A].filter(Boolean).join(" ") || void 0,
28
28
  "aria-required": y,
29
29
  "aria-invalid": !!v,
30
30
  children: [/* @__PURE__ */ l(t, { children: a.map((e) => /* @__PURE__ */ l(r, {