@object-ui/plugin-kanban 0.3.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.
- package/CHANGELOG.md +48 -0
- package/LICENSE +21 -0
- package/README.md +170 -0
- package/dist/KanbanImpl-mGLdSHcd.js +3335 -0
- package/dist/KanbanImpl.d.ts +24 -0
- package/dist/KanbanImpl.d.ts.map +1 -0
- package/dist/index-i_5clVsp.js +746 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.umd.cjs +18 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +44 -0
- package/src/KanbanImpl.tsx +284 -0
- package/src/index.test.ts +104 -0
- package/src/index.tsx +168 -0
- package/src/types.ts +47 -0
- package/tsconfig.json +11 -0
- package/vite.config.ts +38 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type { KanbanSchema, KanbanCard, KanbanColumn } from './types';
|
|
3
|
+
export interface KanbanRendererProps {
|
|
4
|
+
schema: {
|
|
5
|
+
type: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
columns?: Array<any>;
|
|
9
|
+
data?: Array<any>;
|
|
10
|
+
groupBy?: string;
|
|
11
|
+
onCardMove?: (cardId: string, fromColumnId: string, toColumnId: string, newIndex: number) => void;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* KanbanRenderer - The public API for the kanban board component
|
|
16
|
+
* This wrapper handles lazy loading internally using React.Suspense
|
|
17
|
+
*/
|
|
18
|
+
export declare const KanbanRenderer: React.FC<KanbanRendererProps>;
|
|
19
|
+
export declare const kanbanComponents: {
|
|
20
|
+
kanban: React.FC<KanbanRendererProps>;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAKxC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAMtE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;KACnG,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAsCxD,CAAC;AAoGF,eAAO,MAAM,gBAAgB;;CAE5B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
(function(he,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("react"),require("@object-ui/core"),require("@object-ui/components"),require("react-dom")):typeof define=="function"&&define.amd?define(["exports","react","@object-ui/core","@object-ui/components","react-dom"],c):(he=typeof globalThis<"u"?globalThis:he||self,c(he.ObjectUIPluginKanban={},he.React,he.ObjectUICore,he.ObjectUIComponents,he.ReactDOM))})(this,(function(he,c,Qn,Te,rt){"use strict";function Zn(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const ze=Zn(c);var xt={exports:{}},ot={};var cn;function er(){if(cn)return ot;cn=1;var e=c,t=Symbol.for("react.element"),n=Symbol.for("react.fragment"),r=Object.prototype.hasOwnProperty,i=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,s={key:!0,ref:!0,__self:!0,__source:!0};function a(l,u,d){var f,v={},b=null,h=null;d!==void 0&&(b=""+d),u.key!==void 0&&(b=""+u.key),u.ref!==void 0&&(h=u.ref);for(f in u)r.call(u,f)&&!s.hasOwnProperty(f)&&(v[f]=u[f]);if(l&&l.defaultProps)for(f in u=l.defaultProps,u)v[f]===void 0&&(v[f]=u[f]);return{$$typeof:t,type:l,key:b,ref:h,props:v,_owner:i.current}}return ot.Fragment=n,ot.jsx=a,ot.jsxs=a,ot}var it={};var un;function tr(){return un||(un=1,process.env.NODE_ENV!=="production"&&(function(){var e=c,t=Symbol.for("react.element"),n=Symbol.for("react.portal"),r=Symbol.for("react.fragment"),i=Symbol.for("react.strict_mode"),s=Symbol.for("react.profiler"),a=Symbol.for("react.provider"),l=Symbol.for("react.context"),u=Symbol.for("react.forward_ref"),d=Symbol.for("react.suspense"),f=Symbol.for("react.suspense_list"),v=Symbol.for("react.memo"),b=Symbol.for("react.lazy"),h=Symbol.for("react.offscreen"),w=Symbol.iterator,m="@@iterator";function y(o){if(o===null||typeof o!="object")return null;var g=w&&o[w]||o[m];return typeof g=="function"?g:null}var C=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function x(o){{for(var g=arguments.length,p=new Array(g>1?g-1:0),S=1;S<g;S++)p[S-1]=arguments[S];E("error",o,p)}}function E(o,g,p){{var S=C.ReactDebugCurrentFrame,_=S.getStackAddendum();_!==""&&(g+="%s",p=p.concat([_]));var B=p.map(function(k){return String(k)});B.unshift("Warning: "+g),Function.prototype.apply.call(console[o],console,B)}}var T=!1,D=!1,I=!1,O=!1,A=!1,N;N=Symbol.for("react.module.reference");function L(o){return!!(typeof o=="string"||typeof o=="function"||o===r||o===s||A||o===i||o===d||o===f||O||o===h||T||D||I||typeof o=="object"&&o!==null&&(o.$$typeof===b||o.$$typeof===v||o.$$typeof===a||o.$$typeof===l||o.$$typeof===u||o.$$typeof===N||o.getModuleId!==void 0))}function M(o,g,p){var S=o.displayName;if(S)return S;var _=g.displayName||g.name||"";return _!==""?p+"("+_+")":p}function z(o){return o.displayName||"Context"}function Y(o){if(o==null)return null;if(typeof o.tag=="number"&&x("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),typeof o=="function")return o.displayName||o.name||null;if(typeof o=="string")return o;switch(o){case r:return"Fragment";case n:return"Portal";case s:return"Profiler";case i:return"StrictMode";case d:return"Suspense";case f:return"SuspenseList"}if(typeof o=="object")switch(o.$$typeof){case l:var g=o;return z(g)+".Consumer";case a:var p=o;return z(p._context)+".Provider";case u:return M(o,o.render,"ForwardRef");case v:var S=o.displayName||null;return S!==null?S:Y(o.type)||"Memo";case b:{var _=o,B=_._payload,k=_._init;try{return Y(k(B))}catch{return null}}}return null}var q=Object.assign,me=0,Ye,J,We,de,Me,Ue,H;function fe(){}fe.__reactDisabledLog=!0;function Ae(){{if(me===0){Ye=console.log,J=console.info,We=console.warn,de=console.error,Me=console.group,Ue=console.groupCollapsed,H=console.groupEnd;var o={configurable:!0,enumerable:!0,value:fe,writable:!0};Object.defineProperties(console,{info:o,log:o,warn:o,error:o,group:o,groupCollapsed:o,groupEnd:o})}me++}}function Ke(){{if(me--,me===0){var o={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:q({},o,{value:Ye}),info:q({},o,{value:J}),warn:q({},o,{value:We}),error:q({},o,{value:de}),group:q({},o,{value:Me}),groupCollapsed:q({},o,{value:Ue}),groupEnd:q({},o,{value:H})})}me<0&&x("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var G=C.ReactCurrentDispatcher,ke;function ie(o,g,p){{if(ke===void 0)try{throw Error()}catch(_){var S=_.stack.trim().match(/\n( *(at )?)/);ke=S&&S[1]||""}return`
|
|
2
|
+
`+ke+o}}var se=!1,j;{var Xe=typeof WeakMap=="function"?WeakMap:Map;j=new Xe}function ae(o,g){if(!o||se)return"";{var p=j.get(o);if(p!==void 0)return p}var S;se=!0;var _=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var B;B=G.current,G.current=null,Ae();try{if(g){var k=function(){throw Error()};if(Object.defineProperty(k.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(k,[])}catch(oe){S=oe}Reflect.construct(o,[],k)}else{try{k.call()}catch(oe){S=oe}o.call(k.prototype)}}else{try{throw Error()}catch(oe){S=oe}o()}}catch(oe){if(oe&&S&&typeof oe.stack=="string"){for(var R=oe.stack.split(`
|
|
3
|
+
`),ne=S.stack.split(`
|
|
4
|
+
`),$=R.length-1,U=ne.length-1;$>=1&&U>=0&&R[$]!==ne[U];)U--;for(;$>=1&&U>=0;$--,U--)if(R[$]!==ne[U]){if($!==1||U!==1)do if($--,U--,U<0||R[$]!==ne[U]){var ge=`
|
|
5
|
+
`+R[$].replace(" at new "," at ");return o.displayName&&ge.includes("<anonymous>")&&(ge=ge.replace("<anonymous>",o.displayName)),typeof o=="function"&&j.set(o,ge),ge}while($>=1&&U>=0);break}}}finally{se=!1,G.current=B,Ke(),Error.prepareStackTrace=_}var nt=o?o.displayName||o.name:"",He=nt?ie(nt):"";return typeof o=="function"&&j.set(o,He),He}function je(o,g,p){return ae(o,!1)}function ye(o){var g=o.prototype;return!!(g&&g.isReactComponent)}function xe(o,g,p){if(o==null)return"";if(typeof o=="function")return ae(o,ye(o));if(typeof o=="string")return ie(o);switch(o){case d:return ie("Suspense");case f:return ie("SuspenseList")}if(typeof o=="object")switch(o.$$typeof){case u:return je(o.render);case v:return xe(o.type,g,p);case b:{var S=o,_=S._payload,B=S._init;try{return xe(B(_),g,p)}catch{}}}return""}var ve=Object.prototype.hasOwnProperty,ht={},pt=C.ReactDebugCurrentFrame;function Pe(o){if(o){var g=o._owner,p=xe(o.type,o._source,g?g.type:null);pt.setExtraStackFrame(p)}else pt.setExtraStackFrame(null)}function Se(o,g,p,S,_){{var B=Function.call.bind(ve);for(var k in o)if(B(o,k)){var R=void 0;try{if(typeof o[k]!="function"){var ne=Error((S||"React class")+": "+p+" type `"+k+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof o[k]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw ne.name="Invariant Violation",ne}R=o[k](g,k,S,p,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch($){R=$}R&&!(R instanceof Error)&&(Pe(_),x("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",S||"React class",p,k,typeof R),Pe(null)),R instanceof Error&&!(R.message in ht)&&(ht[R.message]=!0,Pe(_),x("Failed %s type: %s",p,R.message),Pe(null))}}}var et=Array.isArray;function _e(o){return et(o)}function Pt(o){{var g=typeof Symbol=="function"&&Symbol.toStringTag,p=g&&o[Symbol.toStringTag]||o.constructor.name||"Object";return p}}function _t(o){try{return Lt(o),!1}catch{return!0}}function Lt(o){return""+o}function Ft(o){if(_t(o))return x("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",Pt(o)),Lt(o)}var Ie=C.ReactCurrentOwner,Le={key:!0,ref:!0,__self:!0,__source:!0},Fe,bt;function De(o){if(ve.call(o,"ref")){var g=Object.getOwnPropertyDescriptor(o,"ref").get;if(g&&g.isReactWarning)return!1}return o.ref!==void 0}function Bt(o){if(ve.call(o,"key")){var g=Object.getOwnPropertyDescriptor(o,"key").get;if(g&&g.isReactWarning)return!1}return o.key!==void 0}function on(o,g){typeof o.ref=="string"&&Ie.current}function sn(o,g){{var p=function(){Fe||(Fe=!0,x("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",g))};p.isReactWarning=!0,Object.defineProperty(o,"key",{get:p,configurable:!0})}}function mt(o,g){{var p=function(){bt||(bt=!0,x("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",g))};p.isReactWarning=!0,Object.defineProperty(o,"ref",{get:p,configurable:!0})}}var $t=function(o,g,p,S,_,B,k){var R={$$typeof:t,type:o,key:g,ref:p,props:k,_owner:B};return R._store={},Object.defineProperty(R._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(R,"_self",{configurable:!1,enumerable:!1,writable:!1,value:S}),Object.defineProperty(R,"_source",{configurable:!1,enumerable:!1,writable:!1,value:_}),Object.freeze&&(Object.freeze(R.props),Object.freeze(R)),R};function an(o,g,p,S,_){{var B,k={},R=null,ne=null;p!==void 0&&(Ft(p),R=""+p),Bt(g)&&(Ft(g.key),R=""+g.key),De(g)&&(ne=g.ref,on(g,_));for(B in g)ve.call(g,B)&&!Le.hasOwnProperty(B)&&(k[B]=g[B]);if(o&&o.defaultProps){var $=o.defaultProps;for(B in $)k[B]===void 0&&(k[B]=$[B])}if(R||ne){var U=typeof o=="function"?o.displayName||o.name||"Unknown":o;R&&sn(k,U),ne&&mt(k,U)}return $t(o,R,ne,_,S,Ie.current,k)}}var tt=C.ReactCurrentOwner,zt=C.ReactDebugCurrentFrame;function Be(o){if(o){var g=o._owner,p=xe(o.type,o._source,g?g.type:null);zt.setExtraStackFrame(p)}else zt.setExtraStackFrame(null)}var yt;yt=!1;function W(o){return typeof o=="object"&&o!==null&&o.$$typeof===t}function Q(){{if(tt.current){var o=Y(tt.current.type);if(o)return`
|
|
6
|
+
|
|
7
|
+
Check the render method of \``+o+"`."}return""}}function te(o){return""}var we={};function re(o){{var g=Q();if(!g){var p=typeof o=="string"?o:o.displayName||o.name;p&&(g=`
|
|
8
|
+
|
|
9
|
+
Check the top-level render call using <`+p+">.")}return g}}function Z(o,g){{if(!o._store||o._store.validated||o.key!=null)return;o._store.validated=!0;var p=re(g);if(we[p])return;we[p]=!0;var S="";o&&o._owner&&o._owner!==tt.current&&(S=" It was passed a child from "+Y(o._owner.type)+"."),Be(o),x('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',p,S),Be(null)}}function le(o,g){{if(typeof o!="object")return;if(_e(o))for(var p=0;p<o.length;p++){var S=o[p];W(S)&&Z(S,g)}else if(W(o))o._store&&(o._store.validated=!0);else if(o){var _=y(o);if(typeof _=="function"&&_!==o.entries)for(var B=_.call(o),k;!(k=B.next()).done;)W(k.value)&&Z(k.value,g)}}}function $e(o){{var g=o.type;if(g==null||typeof g=="string")return;var p;if(typeof g=="function")p=g.propTypes;else if(typeof g=="object"&&(g.$$typeof===u||g.$$typeof===v))p=g.propTypes;else return;if(p){var S=Y(g);Se(p,o.props,"prop",S,o)}else if(g.PropTypes!==void 0&&!yt){yt=!0;var _=Y(g);x("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",_||"Unknown")}typeof g.getDefaultProps=="function"&&!g.getDefaultProps.isReactClassApproved&&x("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}function X(o){{for(var g=Object.keys(o.props),p=0;p<g.length;p++){var S=g[p];if(S!=="children"&&S!=="key"){Be(o),x("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",S),Be(null);break}}o.ref!==null&&(Be(o),x("Invalid attribute `ref` supplied to `React.Fragment`."),Be(null))}}var Ce={};function ce(o,g,p,S,_,B){{var k=L(o);if(!k){var R="";(o===void 0||typeof o=="object"&&o!==null&&Object.keys(o).length===0)&&(R+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");var ne=te();ne?R+=ne:R+=Q();var $;o===null?$="null":_e(o)?$="array":o!==void 0&&o.$$typeof===t?($="<"+(Y(o.type)||"Unknown")+" />",R=" Did you accidentally export a JSX literal instead of a component?"):$=typeof o,x("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",$,R)}var U=an(o,g,p,_,B);if(U==null)return U;if(k){var ge=g.children;if(ge!==void 0)if(S)if(_e(ge)){for(var nt=0;nt<ge.length;nt++)le(ge[nt],o);Object.freeze&&Object.freeze(ge)}else x("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else le(ge,o)}if(ve.call(g,"key")){var He=Y(o),oe=Object.keys(g).filter(function(ni){return ni!=="key"}),ln=oe.length>0?"{key: someKey, "+oe.join(": ..., ")+": ...}":"{key: someKey}";if(!Ce[He+ln]){var ti=oe.length>0?"{"+oe.join(": ..., ")+": ...}":"{}";x(`A props object containing a "key" prop is being spread into JSX:
|
|
10
|
+
let props = %s;
|
|
11
|
+
<%s {...props} />
|
|
12
|
+
React keys must be passed directly to JSX without using spread:
|
|
13
|
+
let props = %s;
|
|
14
|
+
<%s key={someKey} {...props} />`,ln,He,ti,He),Ce[He+ln]=!0}}return o===r?X(U):$e(U),U}}function Ee(o,g,p){return ce(o,g,p,!0)}function Ve(o,g,p){return ce(o,g,p,!1)}var qe=Ve,Oe=Ee;it.Fragment=r,it.jsx=qe,it.jsxs=Oe})()),it}var dn;function nr(){return dn||(dn=1,process.env.NODE_ENV==="production"?xt.exports=er():xt.exports=tr()),xt.exports}var F=nr();const rr=c.lazy(()=>Promise.resolve().then(()=>ei)),Yt=({schema:e})=>{const t=c.useMemo(()=>{const{columns:n=[],data:r,groupBy:i}=e;if(r&&i&&Array.isArray(r)){const s=r.reduce((a,l)=>{const u=l[i];return a[u]||(a[u]=[]),a[u].push(l),a},{});return n.map(a=>({...a,cards:[...a.cards||[],...s[a.id]||[]]}))}return n},[e]);return F.jsx(c.Suspense,{fallback:F.jsx(Te.Skeleton,{className:"w-full h-[600px]"}),children:F.jsx(rr,{columns:t,onCardMove:e.onCardMove,className:e.className})})};Qn.ComponentRegistry.register("kanban",Yt,{label:"Kanban Board",icon:"LayoutDashboard",category:"plugin",inputs:[{name:"columns",type:"array",label:"Columns",description:"Array of { id, title, cards, limit, className }",required:!0},{name:"onCardMove",type:"code",label:"On Card Move",description:"Callback when a card is moved",advanced:!0},{name:"className",type:"string",label:"CSS Class"}],defaultProps:{columns:[{id:"todo",title:"To Do",cards:[{id:"card-1",title:"Task 1",description:"This is the first task",badges:[{label:"High Priority",variant:"destructive"},{label:"Feature",variant:"default"}]},{id:"card-2",title:"Task 2",description:"This is the second task",badges:[{label:"Bug",variant:"destructive"}]}]},{id:"in-progress",title:"In Progress",limit:3,cards:[{id:"card-3",title:"Task 3",description:"Currently working on this",badges:[{label:"In Progress",variant:"default"}]}]},{id:"done",title:"Done",cards:[{id:"card-4",title:"Task 4",description:"This task is completed",badges:[{label:"Completed",variant:"outline"}]},{id:"card-5",title:"Task 5",description:"Another completed task",badges:[{label:"Completed",variant:"outline"}]}]}],className:"w-full"}});const or={kanban:Yt};function ir(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return c.useMemo(()=>r=>{t.forEach(i=>i(r))},t)}const wt=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function Je(e){const t=Object.prototype.toString.call(e);return t==="[object Window]"||t==="[object global]"}function Wt(e){return"nodeType"in e}function ee(e){var t,n;return e?Je(e)?e:Wt(e)&&(t=(n=e.ownerDocument)==null?void 0:n.defaultView)!=null?t:window:window}function Ut(e){const{Document:t}=ee(e);return e instanceof t}function st(e){return Je(e)?!1:e instanceof ee(e).HTMLElement}function fn(e){return e instanceof ee(e).SVGElement}function Ge(e){return e?Je(e)?e.document:Wt(e)?Ut(e)?e:st(e)||fn(e)?e.ownerDocument:document:document:document}const pe=wt?c.useLayoutEffect:c.useEffect;function Ct(e){const t=c.useRef(e);return pe(()=>{t.current=e}),c.useCallback(function(){for(var n=arguments.length,r=new Array(n),i=0;i<n;i++)r[i]=arguments[i];return t.current==null?void 0:t.current(...r)},[])}function sr(){const e=c.useRef(null),t=c.useCallback((r,i)=>{e.current=setInterval(r,i)},[]),n=c.useCallback(()=>{e.current!==null&&(clearInterval(e.current),e.current=null)},[]);return[t,n]}function at(e,t){t===void 0&&(t=[e]);const n=c.useRef(e);return pe(()=>{n.current!==e&&(n.current=e)},t),n}function lt(e,t){const n=c.useRef();return c.useMemo(()=>{const r=e(n.current);return n.current=r,r},[...t])}function Et(e){const t=Ct(e),n=c.useRef(null),r=c.useCallback(i=>{i!==n.current&&t?.(i,n.current),n.current=i},[]);return[n,r]}function St(e){const t=c.useRef();return c.useEffect(()=>{t.current=e},[e]),t.current}let Kt={};function ct(e,t){return c.useMemo(()=>{if(t)return t;const n=Kt[e]==null?0:Kt[e]+1;return Kt[e]=n,e+"-"+n},[e,t])}function vn(e){return function(t){for(var n=arguments.length,r=new Array(n>1?n-1:0),i=1;i<n;i++)r[i-1]=arguments[i];return r.reduce((s,a)=>{const l=Object.entries(a);for(const[u,d]of l){const f=s[u];f!=null&&(s[u]=f+e*d)}return s},{...t})}}const Qe=vn(1),Dt=vn(-1);function ar(e){return"clientX"in e&&"clientY"in e}function Ot(e){if(!e)return!1;const{KeyboardEvent:t}=ee(e.target);return t&&e instanceof t}function lr(e){if(!e)return!1;const{TouchEvent:t}=ee(e.target);return t&&e instanceof t}function Tt(e){if(lr(e)){if(e.touches&&e.touches.length){const{clientX:t,clientY:n}=e.touches[0];return{x:t,y:n}}else if(e.changedTouches&&e.changedTouches.length){const{clientX:t,clientY:n}=e.changedTouches[0];return{x:t,y:n}}}return ar(e)?{x:e.clientX,y:e.clientY}:null}const Re=Object.freeze({Translate:{toString(e){if(!e)return;const{x:t,y:n}=e;return"translate3d("+(t?Math.round(t):0)+"px, "+(n?Math.round(n):0)+"px, 0)"}},Scale:{toString(e){if(!e)return;const{scaleX:t,scaleY:n}=e;return"scaleX("+t+") scaleY("+n+")"}},Transform:{toString(e){if(e)return[Re.Translate.toString(e),Re.Scale.toString(e)].join(" ")}},Transition:{toString(e){let{property:t,duration:n,easing:r}=e;return t+" "+n+"ms "+r}}}),gn="a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]";function cr(e){return e.matches(gn)?e:e.querySelector(gn)}const ur={display:"none"};function dr(e){let{id:t,value:n}=e;return c.createElement("div",{id:t,style:ur},n)}function fr(e){let{id:t,announcement:n,ariaLiveType:r="assertive"}=e;const i={position:"fixed",top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0 0 0 0)",clipPath:"inset(100%)",whiteSpace:"nowrap"};return c.createElement("div",{id:t,style:i,role:"status","aria-live":r,"aria-atomic":!0},n)}function vr(){const[e,t]=c.useState("");return{announce:c.useCallback(r=>{r!=null&&t(r)},[]),announcement:e}}const hn=c.createContext(null);function gr(e){const t=c.useContext(hn);c.useEffect(()=>{if(!t)throw new Error("useDndMonitor must be used within a children of <DndContext>");return t(e)},[e,t])}function hr(){const[e]=c.useState(()=>new Set),t=c.useCallback(r=>(e.add(r),()=>e.delete(r)),[e]);return[c.useCallback(r=>{let{type:i,event:s}=r;e.forEach(a=>{var l;return(l=a[i])==null?void 0:l.call(a,s)})},[e]),t]}const pr={draggable:`
|
|
15
|
+
To pick up a draggable item, press the space bar.
|
|
16
|
+
While dragging, use the arrow keys to move the item.
|
|
17
|
+
Press space again to drop the item in its new position, or press escape to cancel.
|
|
18
|
+
`},br={onDragStart(e){let{active:t}=e;return"Picked up draggable item "+t.id+"."},onDragOver(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was moved over droppable area "+n.id+".":"Draggable item "+t.id+" is no longer over a droppable area."},onDragEnd(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was dropped over droppable area "+n.id:"Draggable item "+t.id+" was dropped."},onDragCancel(e){let{active:t}=e;return"Dragging was cancelled. Draggable item "+t.id+" was dropped."}};function mr(e){let{announcements:t=br,container:n,hiddenTextDescribedById:r,screenReaderInstructions:i=pr}=e;const{announce:s,announcement:a}=vr(),l=ct("DndLiveRegion"),[u,d]=c.useState(!1);if(c.useEffect(()=>{d(!0)},[]),gr(c.useMemo(()=>({onDragStart(v){let{active:b}=v;s(t.onDragStart({active:b}))},onDragMove(v){let{active:b,over:h}=v;t.onDragMove&&s(t.onDragMove({active:b,over:h}))},onDragOver(v){let{active:b,over:h}=v;s(t.onDragOver({active:b,over:h}))},onDragEnd(v){let{active:b,over:h}=v;s(t.onDragEnd({active:b,over:h}))},onDragCancel(v){let{active:b,over:h}=v;s(t.onDragCancel({active:b,over:h}))}}),[s,t])),!u)return null;const f=c.createElement(c.Fragment,null,c.createElement(dr,{id:r,value:i.draggable}),c.createElement(fr,{id:l,announcement:a}));return n?rt.createPortal(f,n):f}var K;(function(e){e.DragStart="dragStart",e.DragMove="dragMove",e.DragEnd="dragEnd",e.DragCancel="dragCancel",e.DragOver="dragOver",e.RegisterDroppable="registerDroppable",e.SetDroppableDisabled="setDroppableDisabled",e.UnregisterDroppable="unregisterDroppable"})(K||(K={}));function At(){}function yr(e,t){return c.useMemo(()=>({sensor:e,options:t??{}}),[e,t])}function xr(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return c.useMemo(()=>[...t].filter(r=>r!=null),[...t])}const be=Object.freeze({x:0,y:0});function wr(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function Cr(e,t){const n=Tt(e);if(!n)return"0 0";const r={x:(n.x-t.left)/t.width*100,y:(n.y-t.top)/t.height*100};return r.x+"% "+r.y+"%"}function Er(e,t){let{data:{value:n}}=e,{data:{value:r}}=t;return n-r}function Sr(e,t){let{data:{value:n}}=e,{data:{value:r}}=t;return r-n}function pn(e){let{left:t,top:n,height:r,width:i}=e;return[{x:t,y:n},{x:t+i,y:n},{x:t,y:n+r},{x:t+i,y:n+r}]}function Dr(e,t){if(!e||e.length===0)return null;const[n]=e;return n[t]}const Or=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e;const i=pn(t),s=[];for(const a of r){const{id:l}=a,u=n.get(l);if(u){const d=pn(u),f=i.reduce((b,h,w)=>b+wr(d[w],h),0),v=Number((f/4).toFixed(4));s.push({id:l,data:{droppableContainer:a,value:v}})}}return s.sort(Er)};function Tr(e,t){const n=Math.max(t.top,e.top),r=Math.max(t.left,e.left),i=Math.min(t.left+t.width,e.left+e.width),s=Math.min(t.top+t.height,e.top+e.height),a=i-r,l=s-n;if(r<i&&n<s){const u=t.width*t.height,d=e.width*e.height,f=a*l,v=f/(u+d-f);return Number(v.toFixed(4))}return 0}const Ar=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e;const i=[];for(const s of r){const{id:a}=s,l=n.get(a);if(l){const u=Tr(l,t);u>0&&i.push({id:a,data:{droppableContainer:s,value:u}})}}return i.sort(Sr)};function Ir(e,t,n){return{...e,scaleX:t&&n?t.width/n.width:1,scaleY:t&&n?t.height/n.height:1}}function bn(e,t){return e&&t?{x:e.left-t.left,y:e.top-t.top}:be}function Rr(e){return function(n){for(var r=arguments.length,i=new Array(r>1?r-1:0),s=1;s<r;s++)i[s-1]=arguments[s];return i.reduce((a,l)=>({...a,top:a.top+e*l.y,bottom:a.bottom+e*l.y,left:a.left+e*l.x,right:a.right+e*l.x}),{...n})}}const Nr=Rr(1);function mn(e){if(e.startsWith("matrix3d(")){const t=e.slice(9,-1).split(/, /);return{x:+t[12],y:+t[13],scaleX:+t[0],scaleY:+t[5]}}else if(e.startsWith("matrix(")){const t=e.slice(7,-1).split(/, /);return{x:+t[4],y:+t[5],scaleX:+t[0],scaleY:+t[3]}}return null}function Mr(e,t,n){const r=mn(t);if(!r)return e;const{scaleX:i,scaleY:s,x:a,y:l}=r,u=e.left-a-(1-i)*parseFloat(n),d=e.top-l-(1-s)*parseFloat(n.slice(n.indexOf(" ")+1)),f=i?e.width/i:e.width,v=s?e.height/s:e.height;return{width:f,height:v,top:d,right:u+f,bottom:d+v,left:u}}const kr={ignoreTransform:!1};function Ze(e,t){t===void 0&&(t=kr);let n=e.getBoundingClientRect();if(t.ignoreTransform){const{transform:d,transformOrigin:f}=ee(e).getComputedStyle(e);d&&(n=Mr(n,d,f))}const{top:r,left:i,width:s,height:a,bottom:l,right:u}=n;return{top:r,left:i,width:s,height:a,bottom:l,right:u}}function yn(e){return Ze(e,{ignoreTransform:!0})}function jr(e){const t=e.innerWidth,n=e.innerHeight;return{top:0,left:0,right:t,bottom:n,width:t,height:n}}function Pr(e,t){return t===void 0&&(t=ee(e).getComputedStyle(e)),t.position==="fixed"}function _r(e,t){t===void 0&&(t=ee(e).getComputedStyle(e));const n=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(i=>{const s=t[i];return typeof s=="string"?n.test(s):!1})}function Xt(e,t){const n=[];function r(i){if(t!=null&&n.length>=t||!i)return n;if(Ut(i)&&i.scrollingElement!=null&&!n.includes(i.scrollingElement))return n.push(i.scrollingElement),n;if(!st(i)||fn(i)||n.includes(i))return n;const s=ee(e).getComputedStyle(i);return i!==e&&_r(i,s)&&n.push(i),Pr(i,s)?n:r(i.parentNode)}return e?r(e):n}function xn(e){const[t]=Xt(e,1);return t??null}function Vt(e){return!wt||!e?null:Je(e)?e:Wt(e)?Ut(e)||e===Ge(e).scrollingElement?window:st(e)?e:null:null}function wn(e){return Je(e)?e.scrollX:e.scrollLeft}function Cn(e){return Je(e)?e.scrollY:e.scrollTop}function qt(e){return{x:wn(e),y:Cn(e)}}var V;(function(e){e[e.Forward=1]="Forward",e[e.Backward=-1]="Backward"})(V||(V={}));function En(e){return!wt||!e?!1:e===document.scrollingElement}function Sn(e){const t={x:0,y:0},n=En(e)?{height:window.innerHeight,width:window.innerWidth}:{height:e.clientHeight,width:e.clientWidth},r={x:e.scrollWidth-n.width,y:e.scrollHeight-n.height},i=e.scrollTop<=t.y,s=e.scrollLeft<=t.x,a=e.scrollTop>=r.y,l=e.scrollLeft>=r.x;return{isTop:i,isLeft:s,isBottom:a,isRight:l,maxScroll:r,minScroll:t}}const Lr={x:.2,y:.2};function Fr(e,t,n,r,i){let{top:s,left:a,right:l,bottom:u}=n;r===void 0&&(r=10),i===void 0&&(i=Lr);const{isTop:d,isBottom:f,isLeft:v,isRight:b}=Sn(e),h={x:0,y:0},w={x:0,y:0},m={height:t.height*i.y,width:t.width*i.x};return!d&&s<=t.top+m.height?(h.y=V.Backward,w.y=r*Math.abs((t.top+m.height-s)/m.height)):!f&&u>=t.bottom-m.height&&(h.y=V.Forward,w.y=r*Math.abs((t.bottom-m.height-u)/m.height)),!b&&l>=t.right-m.width?(h.x=V.Forward,w.x=r*Math.abs((t.right-m.width-l)/m.width)):!v&&a<=t.left+m.width&&(h.x=V.Backward,w.x=r*Math.abs((t.left+m.width-a)/m.width)),{direction:h,speed:w}}function Br(e){if(e===document.scrollingElement){const{innerWidth:s,innerHeight:a}=window;return{top:0,left:0,right:s,bottom:a,width:s,height:a}}const{top:t,left:n,right:r,bottom:i}=e.getBoundingClientRect();return{top:t,left:n,right:r,bottom:i,width:e.clientWidth,height:e.clientHeight}}function Dn(e){return e.reduce((t,n)=>Qe(t,qt(n)),be)}function $r(e){return e.reduce((t,n)=>t+wn(n),0)}function zr(e){return e.reduce((t,n)=>t+Cn(n),0)}function On(e,t){if(t===void 0&&(t=Ze),!e)return;const{top:n,left:r,bottom:i,right:s}=t(e);xn(e)&&(i<=0||s<=0||n>=window.innerHeight||r>=window.innerWidth)&&e.scrollIntoView({block:"center",inline:"center"})}const Yr=[["x",["left","right"],$r],["y",["top","bottom"],zr]];class Ht{constructor(t,n){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const r=Xt(n),i=Dn(r);this.rect={...t},this.width=t.width,this.height=t.height;for(const[s,a,l]of Yr)for(const u of a)Object.defineProperty(this,u,{get:()=>{const d=l(r),f=i[s]-d;return this.rect[u]+f},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class ut{constructor(t){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(n=>{var r;return(r=this.target)==null?void 0:r.removeEventListener(...n)})},this.target=t}add(t,n,r){var i;(i=this.target)==null||i.addEventListener(t,n,r),this.listeners.push([t,n,r])}}function Wr(e){const{EventTarget:t}=ee(e);return e instanceof t?e:Ge(e)}function Jt(e,t){const n=Math.abs(e.x),r=Math.abs(e.y);return typeof t=="number"?Math.sqrt(n**2+r**2)>t:"x"in t&&"y"in t?n>t.x&&r>t.y:"x"in t?n>t.x:"y"in t?r>t.y:!1}var ue;(function(e){e.Click="click",e.DragStart="dragstart",e.Keydown="keydown",e.ContextMenu="contextmenu",e.Resize="resize",e.SelectionChange="selectionchange",e.VisibilityChange="visibilitychange"})(ue||(ue={}));function Tn(e){e.preventDefault()}function Ur(e){e.stopPropagation()}var P;(function(e){e.Space="Space",e.Down="ArrowDown",e.Right="ArrowRight",e.Left="ArrowLeft",e.Up="ArrowUp",e.Esc="Escape",e.Enter="Enter",e.Tab="Tab"})(P||(P={}));const An={start:[P.Space,P.Enter],cancel:[P.Esc],end:[P.Space,P.Enter,P.Tab]},Kr=(e,t)=>{let{currentCoordinates:n}=t;switch(e.code){case P.Right:return{...n,x:n.x+25};case P.Left:return{...n,x:n.x-25};case P.Down:return{...n,y:n.y+25};case P.Up:return{...n,y:n.y-25}}};class In{constructor(t){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=t;const{event:{target:n}}=t;this.props=t,this.listeners=new ut(Ge(n)),this.windowListeners=new ut(ee(n)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(ue.Resize,this.handleCancel),this.windowListeners.add(ue.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(ue.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:t,onStart:n}=this.props,r=t.node.current;r&&On(r),n(be)}handleKeyDown(t){if(Ot(t)){const{active:n,context:r,options:i}=this.props,{keyboardCodes:s=An,coordinateGetter:a=Kr,scrollBehavior:l="smooth"}=i,{code:u}=t;if(s.end.includes(u)){this.handleEnd(t);return}if(s.cancel.includes(u)){this.handleCancel(t);return}const{collisionRect:d}=r.current,f=d?{x:d.left,y:d.top}:be;this.referenceCoordinates||(this.referenceCoordinates=f);const v=a(t,{active:n,context:r.current,currentCoordinates:f});if(v){const b=Dt(v,f),h={x:0,y:0},{scrollableAncestors:w}=r.current;for(const m of w){const y=t.code,{isTop:C,isRight:x,isLeft:E,isBottom:T,maxScroll:D,minScroll:I}=Sn(m),O=Br(m),A={x:Math.min(y===P.Right?O.right-O.width/2:O.right,Math.max(y===P.Right?O.left:O.left+O.width/2,v.x)),y:Math.min(y===P.Down?O.bottom-O.height/2:O.bottom,Math.max(y===P.Down?O.top:O.top+O.height/2,v.y))},N=y===P.Right&&!x||y===P.Left&&!E,L=y===P.Down&&!T||y===P.Up&&!C;if(N&&A.x!==v.x){const M=m.scrollLeft+b.x,z=y===P.Right&&M<=D.x||y===P.Left&&M>=I.x;if(z&&!b.y){m.scrollTo({left:M,behavior:l});return}z?h.x=m.scrollLeft-M:h.x=y===P.Right?m.scrollLeft-D.x:m.scrollLeft-I.x,h.x&&m.scrollBy({left:-h.x,behavior:l});break}else if(L&&A.y!==v.y){const M=m.scrollTop+b.y,z=y===P.Down&&M<=D.y||y===P.Up&&M>=I.y;if(z&&!b.x){m.scrollTo({top:M,behavior:l});return}z?h.y=m.scrollTop-M:h.y=y===P.Down?m.scrollTop-D.y:m.scrollTop-I.y,h.y&&m.scrollBy({top:-h.y,behavior:l});break}}this.handleMove(t,Qe(Dt(v,this.referenceCoordinates),h))}}}handleMove(t,n){const{onMove:r}=this.props;t.preventDefault(),r(n)}handleEnd(t){const{onEnd:n}=this.props;t.preventDefault(),this.detach(),n()}handleCancel(t){const{onCancel:n}=this.props;t.preventDefault(),this.detach(),n()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}In.activators=[{eventName:"onKeyDown",handler:(e,t,n)=>{let{keyboardCodes:r=An,onActivation:i}=t,{active:s}=n;const{code:a}=e.nativeEvent;if(r.start.includes(a)){const l=s.activatorNode.current;return l&&e.target!==l?!1:(e.preventDefault(),i?.({event:e.nativeEvent}),!0)}return!1}}];function Rn(e){return!!(e&&"distance"in e)}function Nn(e){return!!(e&&"delay"in e)}class Gt{constructor(t,n,r){var i;r===void 0&&(r=Wr(t.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=t,this.events=n;const{event:s}=t,{target:a}=s;this.props=t,this.events=n,this.document=Ge(a),this.documentListeners=new ut(this.document),this.listeners=new ut(r),this.windowListeners=new ut(ee(a)),this.initialCoordinates=(i=Tt(s))!=null?i:be,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:t,props:{options:{activationConstraint:n,bypassActivationConstraint:r}}}=this;if(this.listeners.add(t.move.name,this.handleMove,{passive:!1}),this.listeners.add(t.end.name,this.handleEnd),t.cancel&&this.listeners.add(t.cancel.name,this.handleCancel),this.windowListeners.add(ue.Resize,this.handleCancel),this.windowListeners.add(ue.DragStart,Tn),this.windowListeners.add(ue.VisibilityChange,this.handleCancel),this.windowListeners.add(ue.ContextMenu,Tn),this.documentListeners.add(ue.Keydown,this.handleKeydown),n){if(r!=null&&r({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(Nn(n)){this.timeoutId=setTimeout(this.handleStart,n.delay),this.handlePending(n);return}if(Rn(n)){this.handlePending(n);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(t,n){const{active:r,onPending:i}=this.props;i(r,t,this.initialCoordinates,n)}handleStart(){const{initialCoordinates:t}=this,{onStart:n}=this.props;t&&(this.activated=!0,this.documentListeners.add(ue.Click,Ur,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(ue.SelectionChange,this.removeTextSelection),n(t))}handleMove(t){var n;const{activated:r,initialCoordinates:i,props:s}=this,{onMove:a,options:{activationConstraint:l}}=s;if(!i)return;const u=(n=Tt(t))!=null?n:be,d=Dt(i,u);if(!r&&l){if(Rn(l)){if(l.tolerance!=null&&Jt(d,l.tolerance))return this.handleCancel();if(Jt(d,l.distance))return this.handleStart()}if(Nn(l)&&Jt(d,l.tolerance))return this.handleCancel();this.handlePending(l,d);return}t.cancelable&&t.preventDefault(),a(u)}handleEnd(){const{onAbort:t,onEnd:n}=this.props;this.detach(),this.activated||t(this.props.active),n()}handleCancel(){const{onAbort:t,onCancel:n}=this.props;this.detach(),this.activated||t(this.props.active),n()}handleKeydown(t){t.code===P.Esc&&this.handleCancel()}removeTextSelection(){var t;(t=this.document.getSelection())==null||t.removeAllRanges()}}const Xr={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class Qt extends Gt{constructor(t){const{event:n}=t,r=Ge(n.target);super(t,Xr,r)}}Qt.activators=[{eventName:"onPointerDown",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;return!n.isPrimary||n.button!==0?!1:(r?.({event:n}),!0)}}];const Vr={move:{name:"mousemove"},end:{name:"mouseup"}};var Zt;(function(e){e[e.RightClick=2]="RightClick"})(Zt||(Zt={}));class qr extends Gt{constructor(t){super(t,Vr,Ge(t.event.target))}}qr.activators=[{eventName:"onMouseDown",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;return n.button===Zt.RightClick?!1:(r?.({event:n}),!0)}}];const en={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class Hr extends Gt{constructor(t){super(t,en)}static setup(){return window.addEventListener(en.move.name,t,{capture:!1,passive:!1}),function(){window.removeEventListener(en.move.name,t)};function t(){}}}Hr.activators=[{eventName:"onTouchStart",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;const{touches:i}=n;return i.length>1?!1:(r?.({event:n}),!0)}}];var dt;(function(e){e[e.Pointer=0]="Pointer",e[e.DraggableRect=1]="DraggableRect"})(dt||(dt={}));var It;(function(e){e[e.TreeOrder=0]="TreeOrder",e[e.ReversedTreeOrder=1]="ReversedTreeOrder"})(It||(It={}));function Jr(e){let{acceleration:t,activator:n=dt.Pointer,canScroll:r,draggingRect:i,enabled:s,interval:a=5,order:l=It.TreeOrder,pointerCoordinates:u,scrollableAncestors:d,scrollableAncestorRects:f,delta:v,threshold:b}=e;const h=Qr({delta:v,disabled:!s}),[w,m]=sr(),y=c.useRef({x:0,y:0}),C=c.useRef({x:0,y:0}),x=c.useMemo(()=>{switch(n){case dt.Pointer:return u?{top:u.y,bottom:u.y,left:u.x,right:u.x}:null;case dt.DraggableRect:return i}},[n,i,u]),E=c.useRef(null),T=c.useCallback(()=>{const I=E.current;if(!I)return;const O=y.current.x*C.current.x,A=y.current.y*C.current.y;I.scrollBy(O,A)},[]),D=c.useMemo(()=>l===It.TreeOrder?[...d].reverse():d,[l,d]);c.useEffect(()=>{if(!s||!d.length||!x){m();return}for(const I of D){if(r?.(I)===!1)continue;const O=d.indexOf(I),A=f[O];if(!A)continue;const{direction:N,speed:L}=Fr(I,A,x,t,b);for(const M of["x","y"])h[M][N[M]]||(L[M]=0,N[M]=0);if(L.x>0||L.y>0){m(),E.current=I,w(T,a),y.current=L,C.current=N;return}}y.current={x:0,y:0},C.current={x:0,y:0},m()},[t,T,r,m,s,a,JSON.stringify(x),JSON.stringify(h),w,d,D,f,JSON.stringify(b)])}const Gr={x:{[V.Backward]:!1,[V.Forward]:!1},y:{[V.Backward]:!1,[V.Forward]:!1}};function Qr(e){let{delta:t,disabled:n}=e;const r=St(t);return lt(i=>{if(n||!r||!i)return Gr;const s={x:Math.sign(t.x-r.x),y:Math.sign(t.y-r.y)};return{x:{[V.Backward]:i.x[V.Backward]||s.x===-1,[V.Forward]:i.x[V.Forward]||s.x===1},y:{[V.Backward]:i.y[V.Backward]||s.y===-1,[V.Forward]:i.y[V.Forward]||s.y===1}}},[n,t,r])}function Zr(e,t){const n=t!=null?e.get(t):void 0,r=n?n.node.current:null;return lt(i=>{var s;return t==null?null:(s=r??i)!=null?s:null},[r,t])}function eo(e,t){return c.useMemo(()=>e.reduce((n,r)=>{const{sensor:i}=r,s=i.activators.map(a=>({eventName:a.eventName,handler:t(a.handler,r)}));return[...n,...s]},[]),[e,t])}var ft;(function(e){e[e.Always=0]="Always",e[e.BeforeDragging=1]="BeforeDragging",e[e.WhileDragging=2]="WhileDragging"})(ft||(ft={}));var tn;(function(e){e.Optimized="optimized"})(tn||(tn={}));const Mn=new Map;function to(e,t){let{dragging:n,dependencies:r,config:i}=t;const[s,a]=c.useState(null),{frequency:l,measure:u,strategy:d}=i,f=c.useRef(e),v=y(),b=at(v),h=c.useCallback(function(C){C===void 0&&(C=[]),!b.current&&a(x=>x===null?C:x.concat(C.filter(E=>!x.includes(E))))},[b]),w=c.useRef(null),m=lt(C=>{if(v&&!n)return Mn;if(!C||C===Mn||f.current!==e||s!=null){const x=new Map;for(let E of e){if(!E)continue;if(s&&s.length>0&&!s.includes(E.id)&&E.rect.current){x.set(E.id,E.rect.current);continue}const T=E.node.current,D=T?new Ht(u(T),T):null;E.rect.current=D,D&&x.set(E.id,D)}return x}return C},[e,s,n,v,u]);return c.useEffect(()=>{f.current=e},[e]),c.useEffect(()=>{v||h()},[n,v]),c.useEffect(()=>{s&&s.length>0&&a(null)},[JSON.stringify(s)]),c.useEffect(()=>{v||typeof l!="number"||w.current!==null||(w.current=setTimeout(()=>{h(),w.current=null},l))},[l,v,h,...r]),{droppableRects:m,measureDroppableContainers:h,measuringScheduled:s!=null};function y(){switch(d){case ft.Always:return!1;case ft.BeforeDragging:return n;default:return!n}}}function nn(e,t){return lt(n=>e?n||(typeof t=="function"?t(e):e):null,[t,e])}function no(e,t){return nn(e,t)}function ro(e){let{callback:t,disabled:n}=e;const r=Ct(t),i=c.useMemo(()=>{if(n||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:s}=window;return new s(r)},[r,n]);return c.useEffect(()=>()=>i?.disconnect(),[i]),i}function Rt(e){let{callback:t,disabled:n}=e;const r=Ct(t),i=c.useMemo(()=>{if(n||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:s}=window;return new s(r)},[n]);return c.useEffect(()=>()=>i?.disconnect(),[i]),i}function oo(e){return new Ht(Ze(e),e)}function kn(e,t,n){t===void 0&&(t=oo);const[r,i]=c.useState(null);function s(){i(u=>{if(!e)return null;if(e.isConnected===!1){var d;return(d=u??n)!=null?d:null}const f=t(e);return JSON.stringify(u)===JSON.stringify(f)?u:f})}const a=ro({callback(u){if(e)for(const d of u){const{type:f,target:v}=d;if(f==="childList"&&v instanceof HTMLElement&&v.contains(e)){s();break}}}}),l=Rt({callback:s});return pe(()=>{s(),e?(l?.observe(e),a?.observe(document.body,{childList:!0,subtree:!0})):(l?.disconnect(),a?.disconnect())},[e]),r}function io(e){const t=nn(e);return bn(e,t)}const jn=[];function so(e){const t=c.useRef(e),n=lt(r=>e?r&&r!==jn&&e&&t.current&&e.parentNode===t.current.parentNode?r:Xt(e):jn,[e]);return c.useEffect(()=>{t.current=e},[e]),n}function ao(e){const[t,n]=c.useState(null),r=c.useRef(e),i=c.useCallback(s=>{const a=Vt(s.target);a&&n(l=>l?(l.set(a,qt(a)),new Map(l)):null)},[]);return c.useEffect(()=>{const s=r.current;if(e!==s){a(s);const l=e.map(u=>{const d=Vt(u);return d?(d.addEventListener("scroll",i,{passive:!0}),[d,qt(d)]):null}).filter(u=>u!=null);n(l.length?new Map(l):null),r.current=e}return()=>{a(e),a(s)};function a(l){l.forEach(u=>{const d=Vt(u);d?.removeEventListener("scroll",i)})}},[i,e]),c.useMemo(()=>e.length?t?Array.from(t.values()).reduce((s,a)=>Qe(s,a),be):Dn(e):be,[e,t])}function Pn(e,t){t===void 0&&(t=[]);const n=c.useRef(null);return c.useEffect(()=>{n.current=null},t),c.useEffect(()=>{const r=e!==be;r&&!n.current&&(n.current=e),!r&&n.current&&(n.current=null)},[e]),n.current?Dt(e,n.current):be}function lo(e){c.useEffect(()=>{if(!wt)return;const t=e.map(n=>{let{sensor:r}=n;return r.setup==null?void 0:r.setup()});return()=>{for(const n of t)n?.()}},e.map(t=>{let{sensor:n}=t;return n}))}function co(e,t){return c.useMemo(()=>e.reduce((n,r)=>{let{eventName:i,handler:s}=r;return n[i]=a=>{s(a,t)},n},{}),[e,t])}function _n(e){return c.useMemo(()=>e?jr(e):null,[e])}const Ln=[];function uo(e,t){t===void 0&&(t=Ze);const[n]=e,r=_n(n?ee(n):null),[i,s]=c.useState(Ln);function a(){s(()=>e.length?e.map(u=>En(u)?r:new Ht(t(u),u)):Ln)}const l=Rt({callback:a});return pe(()=>{l?.disconnect(),a(),e.forEach(u=>l?.observe(u))},[e]),i}function Fn(e){if(!e)return null;if(e.children.length>1)return e;const t=e.children[0];return st(t)?t:e}function fo(e){let{measure:t}=e;const[n,r]=c.useState(null),i=c.useCallback(d=>{for(const{target:f}of d)if(st(f)){r(v=>{const b=t(f);return v?{...v,width:b.width,height:b.height}:b});break}},[t]),s=Rt({callback:i}),a=c.useCallback(d=>{const f=Fn(d);s?.disconnect(),f&&s?.observe(f),r(f?t(f):null)},[t,s]),[l,u]=Et(a);return c.useMemo(()=>({nodeRef:l,rect:n,setRef:u}),[n,l,u])}const vo=[{sensor:Qt,options:{}},{sensor:In,options:{}}],go={current:{}},Nt={draggable:{measure:yn},droppable:{measure:yn,strategy:ft.WhileDragging,frequency:tn.Optimized},dragOverlay:{measure:Ze}};class vt extends Map{get(t){var n;return t!=null&&(n=super.get(t))!=null?n:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(t=>{let{disabled:n}=t;return!n})}getNodeFor(t){var n,r;return(n=(r=this.get(t))==null?void 0:r.node.current)!=null?n:void 0}}const ho={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new vt,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:At},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:Nt,measureDroppableContainers:At,windowRect:null,measuringScheduled:!1},Bn={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:At,draggableNodes:new Map,over:null,measureDroppableContainers:At},gt=c.createContext(Bn),$n=c.createContext(ho);function po(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new vt}}}function bo(e,t){switch(t.type){case K.DragStart:return{...e,draggable:{...e.draggable,initialCoordinates:t.initialCoordinates,active:t.active}};case K.DragMove:return e.draggable.active==null?e:{...e,draggable:{...e.draggable,translate:{x:t.coordinates.x-e.draggable.initialCoordinates.x,y:t.coordinates.y-e.draggable.initialCoordinates.y}}};case K.DragEnd:case K.DragCancel:return{...e,draggable:{...e.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case K.RegisterDroppable:{const{element:n}=t,{id:r}=n,i=new vt(e.droppable.containers);return i.set(r,n),{...e,droppable:{...e.droppable,containers:i}}}case K.SetDroppableDisabled:{const{id:n,key:r,disabled:i}=t,s=e.droppable.containers.get(n);if(!s||r!==s.key)return e;const a=new vt(e.droppable.containers);return a.set(n,{...s,disabled:i}),{...e,droppable:{...e.droppable,containers:a}}}case K.UnregisterDroppable:{const{id:n,key:r}=t,i=e.droppable.containers.get(n);if(!i||r!==i.key)return e;const s=new vt(e.droppable.containers);return s.delete(n),{...e,droppable:{...e.droppable,containers:s}}}default:return e}}function mo(e){let{disabled:t}=e;const{active:n,activatorEvent:r,draggableNodes:i}=c.useContext(gt),s=St(r),a=St(n?.id);return c.useEffect(()=>{if(!t&&!r&&s&&a!=null){if(!Ot(s)||document.activeElement===s.target)return;const l=i.get(a);if(!l)return;const{activatorNode:u,node:d}=l;if(!u.current&&!d.current)return;requestAnimationFrame(()=>{for(const f of[u.current,d.current]){if(!f)continue;const v=cr(f);if(v){v.focus();break}}})}},[r,t,i,a,s]),null}function zn(e,t){let{transform:n,...r}=t;return e!=null&&e.length?e.reduce((i,s)=>s({transform:i,...r}),n):n}function yo(e){return c.useMemo(()=>({draggable:{...Nt.draggable,...e?.draggable},droppable:{...Nt.droppable,...e?.droppable},dragOverlay:{...Nt.dragOverlay,...e?.dragOverlay}}),[e?.draggable,e?.droppable,e?.dragOverlay])}function xo(e){let{activeNode:t,measure:n,initialRect:r,config:i=!0}=e;const s=c.useRef(!1),{x:a,y:l}=typeof i=="boolean"?{x:i,y:i}:i;pe(()=>{if(!a&&!l||!t){s.current=!1;return}if(s.current||!r)return;const d=t?.node.current;if(!d||d.isConnected===!1)return;const f=n(d),v=bn(f,r);if(a||(v.x=0),l||(v.y=0),s.current=!0,Math.abs(v.x)>0||Math.abs(v.y)>0){const b=xn(d);b&&b.scrollBy({top:v.y,left:v.x})}},[t,a,l,r,n])}const Mt=c.createContext({...be,scaleX:1,scaleY:1});var Ne;(function(e){e[e.Uninitialized=0]="Uninitialized",e[e.Initializing=1]="Initializing",e[e.Initialized=2]="Initialized"})(Ne||(Ne={}));const wo=c.memo(function(t){var n,r,i,s;let{id:a,accessibility:l,autoScroll:u=!0,children:d,sensors:f=vo,collisionDetection:v=Ar,measuring:b,modifiers:h,...w}=t;const m=c.useReducer(bo,void 0,po),[y,C]=m,[x,E]=hr(),[T,D]=c.useState(Ne.Uninitialized),I=T===Ne.Initialized,{draggable:{active:O,nodes:A,translate:N},droppable:{containers:L}}=y,M=O!=null?A.get(O):null,z=c.useRef({initial:null,translated:null}),Y=c.useMemo(()=>{var W;return O!=null?{id:O,data:(W=M?.data)!=null?W:go,rect:z}:null},[O,M]),q=c.useRef(null),[me,Ye]=c.useState(null),[J,We]=c.useState(null),de=at(w,Object.values(w)),Me=ct("DndDescribedBy",a),Ue=c.useMemo(()=>L.getEnabled(),[L]),H=yo(b),{droppableRects:fe,measureDroppableContainers:Ae,measuringScheduled:Ke}=to(Ue,{dragging:I,dependencies:[N.x,N.y],config:H.droppable}),G=Zr(A,O),ke=c.useMemo(()=>J?Tt(J):null,[J]),ie=yt(),se=no(G,H.draggable.measure);xo({activeNode:O!=null?A.get(O):null,config:ie.layoutShiftCompensation,initialRect:se,measure:H.draggable.measure});const j=kn(G,H.draggable.measure,se),Xe=kn(G?G.parentElement:null),ae=c.useRef({activatorEvent:null,active:null,activeNode:G,collisionRect:null,collisions:null,droppableRects:fe,draggableNodes:A,draggingNode:null,draggingNodeRect:null,droppableContainers:L,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),je=L.getNodeFor((n=ae.current.over)==null?void 0:n.id),ye=fo({measure:H.dragOverlay.measure}),xe=(r=ye.nodeRef.current)!=null?r:G,ve=I?(i=ye.rect)!=null?i:j:null,ht=!!(ye.nodeRef.current&&ye.rect),pt=io(ht?null:j),Pe=_n(xe?ee(xe):null),Se=so(I?je??G:null),et=uo(Se),_e=zn(h,{transform:{x:N.x-pt.x,y:N.y-pt.y,scaleX:1,scaleY:1},activatorEvent:J,active:Y,activeNodeRect:j,containerNodeRect:Xe,draggingNodeRect:ve,over:ae.current.over,overlayNodeRect:ye.rect,scrollableAncestors:Se,scrollableAncestorRects:et,windowRect:Pe}),Pt=ke?Qe(ke,N):null,_t=ao(Se),Lt=Pn(_t),Ft=Pn(_t,[j]),Ie=Qe(_e,Lt),Le=ve?Nr(ve,_e):null,Fe=Y&&Le?v({active:Y,collisionRect:Le,droppableRects:fe,droppableContainers:Ue,pointerCoordinates:Pt}):null,bt=Dr(Fe,"id"),[De,Bt]=c.useState(null),on=ht?_e:Qe(_e,Ft),sn=Ir(on,(s=De?.rect)!=null?s:null,j),mt=c.useRef(null),$t=c.useCallback((W,Q)=>{let{sensor:te,options:we}=Q;if(q.current==null)return;const re=A.get(q.current);if(!re)return;const Z=W.nativeEvent,le=new te({active:q.current,activeNode:re,event:Z,options:we,context:ae,onAbort(X){if(!A.get(X))return;const{onDragAbort:ce}=de.current,Ee={id:X};ce?.(Ee),x({type:"onDragAbort",event:Ee})},onPending(X,Ce,ce,Ee){if(!A.get(X))return;const{onDragPending:qe}=de.current,Oe={id:X,constraint:Ce,initialCoordinates:ce,offset:Ee};qe?.(Oe),x({type:"onDragPending",event:Oe})},onStart(X){const Ce=q.current;if(Ce==null)return;const ce=A.get(Ce);if(!ce)return;const{onDragStart:Ee}=de.current,Ve={activatorEvent:Z,active:{id:Ce,data:ce.data,rect:z}};rt.unstable_batchedUpdates(()=>{Ee?.(Ve),D(Ne.Initializing),C({type:K.DragStart,initialCoordinates:X,active:Ce}),x({type:"onDragStart",event:Ve}),Ye(mt.current),We(Z)})},onMove(X){C({type:K.DragMove,coordinates:X})},onEnd:$e(K.DragEnd),onCancel:$e(K.DragCancel)});mt.current=le;function $e(X){return async function(){const{active:ce,collisions:Ee,over:Ve,scrollAdjustedTranslate:qe}=ae.current;let Oe=null;if(ce&&qe){const{cancelDrop:o}=de.current;Oe={activatorEvent:Z,active:ce,collisions:Ee,delta:qe,over:Ve},X===K.DragEnd&&typeof o=="function"&&await Promise.resolve(o(Oe))&&(X=K.DragCancel)}q.current=null,rt.unstable_batchedUpdates(()=>{C({type:X}),D(Ne.Uninitialized),Bt(null),Ye(null),We(null),mt.current=null;const o=X===K.DragEnd?"onDragEnd":"onDragCancel";if(Oe){const g=de.current[o];g?.(Oe),x({type:o,event:Oe})}})}}},[A]),an=c.useCallback((W,Q)=>(te,we)=>{const re=te.nativeEvent,Z=A.get(we);if(q.current!==null||!Z||re.dndKit||re.defaultPrevented)return;const le={active:Z};W(te,Q.options,le)===!0&&(re.dndKit={capturedBy:Q.sensor},q.current=we,$t(te,Q))},[A,$t]),tt=eo(f,an);lo(f),pe(()=>{j&&T===Ne.Initializing&&D(Ne.Initialized)},[j,T]),c.useEffect(()=>{const{onDragMove:W}=de.current,{active:Q,activatorEvent:te,collisions:we,over:re}=ae.current;if(!Q||!te)return;const Z={active:Q,activatorEvent:te,collisions:we,delta:{x:Ie.x,y:Ie.y},over:re};rt.unstable_batchedUpdates(()=>{W?.(Z),x({type:"onDragMove",event:Z})})},[Ie.x,Ie.y]),c.useEffect(()=>{const{active:W,activatorEvent:Q,collisions:te,droppableContainers:we,scrollAdjustedTranslate:re}=ae.current;if(!W||q.current==null||!Q||!re)return;const{onDragOver:Z}=de.current,le=we.get(bt),$e=le&&le.rect.current?{id:le.id,rect:le.rect.current,data:le.data,disabled:le.disabled}:null,X={active:W,activatorEvent:Q,collisions:te,delta:{x:re.x,y:re.y},over:$e};rt.unstable_batchedUpdates(()=>{Bt($e),Z?.(X),x({type:"onDragOver",event:X})})},[bt]),pe(()=>{ae.current={activatorEvent:J,active:Y,activeNode:G,collisionRect:Le,collisions:Fe,droppableRects:fe,draggableNodes:A,draggingNode:xe,draggingNodeRect:ve,droppableContainers:L,over:De,scrollableAncestors:Se,scrollAdjustedTranslate:Ie},z.current={initial:ve,translated:Le}},[Y,G,Fe,Le,A,xe,ve,fe,L,De,Se,Ie]),Jr({...ie,delta:N,draggingRect:Le,pointerCoordinates:Pt,scrollableAncestors:Se,scrollableAncestorRects:et});const zt=c.useMemo(()=>({active:Y,activeNode:G,activeNodeRect:j,activatorEvent:J,collisions:Fe,containerNodeRect:Xe,dragOverlay:ye,draggableNodes:A,droppableContainers:L,droppableRects:fe,over:De,measureDroppableContainers:Ae,scrollableAncestors:Se,scrollableAncestorRects:et,measuringConfiguration:H,measuringScheduled:Ke,windowRect:Pe}),[Y,G,j,J,Fe,Xe,ye,A,L,fe,De,Ae,Se,et,H,Ke,Pe]),Be=c.useMemo(()=>({activatorEvent:J,activators:tt,active:Y,activeNodeRect:j,ariaDescribedById:{draggable:Me},dispatch:C,draggableNodes:A,over:De,measureDroppableContainers:Ae}),[J,tt,Y,j,C,Me,A,De,Ae]);return c.createElement(hn.Provider,{value:E},c.createElement(gt.Provider,{value:Be},c.createElement($n.Provider,{value:zt},c.createElement(Mt.Provider,{value:sn},d)),c.createElement(mo,{disabled:l?.restoreFocus===!1})),c.createElement(mr,{...l,hiddenTextDescribedById:Me}));function yt(){const W=me?.autoScrollEnabled===!1,Q=typeof u=="object"?u.enabled===!1:u===!1,te=I&&!W&&!Q;return typeof u=="object"?{...u,enabled:te}:{enabled:te}}}),Co=c.createContext(null),Yn="button",Eo="Draggable";function So(e){let{id:t,data:n,disabled:r=!1,attributes:i}=e;const s=ct(Eo),{activators:a,activatorEvent:l,active:u,activeNodeRect:d,ariaDescribedById:f,draggableNodes:v,over:b}=c.useContext(gt),{role:h=Yn,roleDescription:w="draggable",tabIndex:m=0}=i??{},y=u?.id===t,C=c.useContext(y?Mt:Co),[x,E]=Et(),[T,D]=Et(),I=co(a,t),O=at(n);pe(()=>(v.set(t,{id:t,key:s,node:x,activatorNode:T,data:O}),()=>{const N=v.get(t);N&&N.key===s&&v.delete(t)}),[v,t]);const A=c.useMemo(()=>({role:h,tabIndex:m,"aria-disabled":r,"aria-pressed":y&&h===Yn?!0:void 0,"aria-roledescription":w,"aria-describedby":f.draggable}),[r,h,m,y,w,f.draggable]);return{active:u,activatorEvent:l,activeNodeRect:d,attributes:A,isDragging:y,listeners:r?void 0:I,node:x,over:b,setNodeRef:E,setActivatorNodeRef:D,transform:C}}function Wn(){return c.useContext($n)}const Do="Droppable",Oo={timeout:25};function To(e){let{data:t,disabled:n=!1,id:r,resizeObserverConfig:i}=e;const s=ct(Do),{active:a,dispatch:l,over:u,measureDroppableContainers:d}=c.useContext(gt),f=c.useRef({disabled:n}),v=c.useRef(!1),b=c.useRef(null),h=c.useRef(null),{disabled:w,updateMeasurementsFor:m,timeout:y}={...Oo,...i},C=at(m??r),x=c.useCallback(()=>{if(!v.current){v.current=!0;return}h.current!=null&&clearTimeout(h.current),h.current=setTimeout(()=>{d(Array.isArray(C.current)?C.current:[C.current]),h.current=null},y)},[y]),E=Rt({callback:x,disabled:w||!a}),T=c.useCallback((A,N)=>{E&&(N&&(E.unobserve(N),v.current=!1),A&&E.observe(A))},[E]),[D,I]=Et(T),O=at(t);return c.useEffect(()=>{!E||!D.current||(E.disconnect(),v.current=!1,E.observe(D.current))},[D,E]),c.useEffect(()=>(l({type:K.RegisterDroppable,element:{id:r,key:s,disabled:n,node:D,rect:b,data:O}}),()=>l({type:K.UnregisterDroppable,key:s,id:r})),[r]),c.useEffect(()=>{n!==f.current.disabled&&(l({type:K.SetDroppableDisabled,id:r,key:s,disabled:n}),f.current.disabled=n)},[r,s,n,l]),{active:a,rect:b,isOver:u?.id===r,node:D,over:u,setNodeRef:I}}function Ao(e){let{animation:t,children:n}=e;const[r,i]=c.useState(null),[s,a]=c.useState(null),l=St(n);return!n&&!r&&l&&i(l),pe(()=>{if(!s)return;const u=r?.key,d=r?.props.id;if(u==null||d==null){i(null);return}Promise.resolve(t(d,s)).then(()=>{i(null)})},[t,r,s]),c.createElement(c.Fragment,null,n,r?c.cloneElement(r,{ref:a}):null)}const Io={x:0,y:0,scaleX:1,scaleY:1};function Ro(e){let{children:t}=e;return c.createElement(gt.Provider,{value:Bn},c.createElement(Mt.Provider,{value:Io},t))}const No={position:"fixed",touchAction:"none"},Mo=e=>Ot(e)?"transform 250ms ease":void 0,ko=c.forwardRef((e,t)=>{let{as:n,activatorEvent:r,adjustScale:i,children:s,className:a,rect:l,style:u,transform:d,transition:f=Mo}=e;if(!l)return null;const v=i?d:{...d,scaleX:1,scaleY:1},b={...No,width:l.width,height:l.height,top:l.top,left:l.left,transform:Re.Transform.toString(v),transformOrigin:i&&r?Cr(r,l):void 0,transition:typeof f=="function"?f(r):f,...u};return c.createElement(n,{className:a,style:b,ref:t},s)}),jo={duration:250,easing:"ease",keyframes:e=>{let{transform:{initial:t,final:n}}=e;return[{transform:Re.Transform.toString(t)},{transform:Re.Transform.toString(n)}]},sideEffects:(e=>t=>{let{active:n,dragOverlay:r}=t;const i={},{styles:s,className:a}=e;if(s!=null&&s.active)for(const[l,u]of Object.entries(s.active))u!==void 0&&(i[l]=n.node.style.getPropertyValue(l),n.node.style.setProperty(l,u));if(s!=null&&s.dragOverlay)for(const[l,u]of Object.entries(s.dragOverlay))u!==void 0&&r.node.style.setProperty(l,u);return a!=null&&a.active&&n.node.classList.add(a.active),a!=null&&a.dragOverlay&&r.node.classList.add(a.dragOverlay),function(){for(const[u,d]of Object.entries(i))n.node.style.setProperty(u,d);a!=null&&a.active&&n.node.classList.remove(a.active)}})({styles:{active:{opacity:"0"}}})};function Po(e){let{config:t,draggableNodes:n,droppableContainers:r,measuringConfiguration:i}=e;return Ct((s,a)=>{if(t===null)return;const l=n.get(s);if(!l)return;const u=l.node.current;if(!u)return;const d=Fn(a);if(!d)return;const{transform:f}=ee(a).getComputedStyle(a),v=mn(f);if(!v)return;const b=typeof t=="function"?t:_o(t);return On(u,i.draggable.measure),b({active:{id:s,data:l.data,node:u,rect:i.draggable.measure(u)},draggableNodes:n,dragOverlay:{node:a,rect:i.dragOverlay.measure(d)},droppableContainers:r,measuringConfiguration:i,transform:v})})}function _o(e){const{duration:t,easing:n,sideEffects:r,keyframes:i}={...jo,...e};return s=>{let{active:a,dragOverlay:l,transform:u,...d}=s;if(!t)return;const f={x:l.rect.left-a.rect.left,y:l.rect.top-a.rect.top},v={scaleX:u.scaleX!==1?a.rect.width*u.scaleX/l.rect.width:1,scaleY:u.scaleY!==1?a.rect.height*u.scaleY/l.rect.height:1},b={x:u.x-f.x,y:u.y-f.y,...v},h=i({...d,active:a,dragOverlay:l,transform:{initial:u,final:b}}),[w]=h,m=h[h.length-1];if(JSON.stringify(w)===JSON.stringify(m))return;const y=r?.({active:a,dragOverlay:l,...d}),C=l.node.animate(h,{duration:t,easing:n,fill:"forwards"});return new Promise(x=>{C.onfinish=()=>{y?.(),x()}})}}let Un=0;function Lo(e){return c.useMemo(()=>{if(e!=null)return Un++,Un},[e])}const Fo=c.memo(e=>{let{adjustScale:t=!1,children:n,dropAnimation:r,style:i,transition:s,modifiers:a,wrapperElement:l="div",className:u,zIndex:d=999}=e;const{activatorEvent:f,active:v,activeNodeRect:b,containerNodeRect:h,draggableNodes:w,droppableContainers:m,dragOverlay:y,over:C,measuringConfiguration:x,scrollableAncestors:E,scrollableAncestorRects:T,windowRect:D}=Wn(),I=c.useContext(Mt),O=Lo(v?.id),A=zn(a,{activatorEvent:f,active:v,activeNodeRect:b,containerNodeRect:h,draggingNodeRect:y.rect,over:C,overlayNodeRect:y.rect,scrollableAncestors:E,scrollableAncestorRects:T,transform:I,windowRect:D}),N=nn(b),L=Po({config:r,draggableNodes:w,droppableContainers:m,measuringConfiguration:x}),M=N?y.setRef:void 0;return c.createElement(Ro,null,c.createElement(Ao,{animation:L},v&&O?c.createElement(ko,{key:O,id:v.id,ref:M,as:l,activatorEvent:f,adjustScale:t,className:u,transition:s,rect:N,style:{zIndex:d,...i},transform:A},n):null))});function rn(e,t,n){const r=e.slice();return r.splice(n<0?r.length+n:n,0,r.splice(t,1)[0]),r}function Bo(e,t){return e.reduce((n,r,i)=>{const s=t.get(r);return s&&(n[i]=s),n},Array(e.length))}function kt(e){return e!==null&&e>=0}function $o(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function zo(e){return typeof e=="boolean"?{draggable:e,droppable:e}:e}const Kn=e=>{let{rects:t,activeIndex:n,overIndex:r,index:i}=e;const s=rn(t,r,n),a=t[i],l=s[i];return!l||!a?null:{x:l.left-a.left,y:l.top-a.top,scaleX:l.width/a.width,scaleY:l.height/a.height}},jt={scaleX:1,scaleY:1},Yo=e=>{var t;let{activeIndex:n,activeNodeRect:r,index:i,rects:s,overIndex:a}=e;const l=(t=s[n])!=null?t:r;if(!l)return null;if(i===n){const d=s[a];return d?{x:0,y:n<a?d.top+d.height-(l.top+l.height):d.top-l.top,...jt}:null}const u=Wo(s,i,n);return i>n&&i<=a?{x:0,y:-l.height-u,...jt}:i<n&&i>=a?{x:0,y:l.height+u,...jt}:{x:0,y:0,...jt}};function Wo(e,t,n){const r=e[t],i=e[t-1],s=e[t+1];return r?n<t?i?r.top-(i.top+i.height):s?s.top-(r.top+r.height):0:s?s.top-(r.top+r.height):i?r.top-(i.top+i.height):0:0}const Xn="Sortable",Vn=c.createContext({activeIndex:-1,containerId:Xn,disableTransforms:!1,items:[],overIndex:-1,useDragOverlay:!1,sortedRects:[],strategy:Kn,disabled:{draggable:!1,droppable:!1}});function Uo(e){let{children:t,id:n,items:r,strategy:i=Kn,disabled:s=!1}=e;const{active:a,dragOverlay:l,droppableRects:u,over:d,measureDroppableContainers:f}=Wn(),v=ct(Xn,n),b=l.rect!==null,h=c.useMemo(()=>r.map(I=>typeof I=="object"&&"id"in I?I.id:I),[r]),w=a!=null,m=a?h.indexOf(a.id):-1,y=d?h.indexOf(d.id):-1,C=c.useRef(h),x=!$o(h,C.current),E=y!==-1&&m===-1||x,T=zo(s);pe(()=>{x&&w&&f(h)},[x,h,w,f]),c.useEffect(()=>{C.current=h},[h]);const D=c.useMemo(()=>({activeIndex:m,containerId:v,disabled:T,disableTransforms:E,items:h,overIndex:y,useDragOverlay:b,sortedRects:Bo(h,u),strategy:i}),[m,v,T.draggable,T.droppable,E,h,y,u,b,i]);return c.createElement(Vn.Provider,{value:D},t)}const Ko=e=>{let{id:t,items:n,activeIndex:r,overIndex:i}=e;return rn(n,r,i).indexOf(t)},Xo=e=>{let{containerId:t,isSorting:n,wasDragging:r,index:i,items:s,newIndex:a,previousItems:l,previousContainerId:u,transition:d}=e;return!d||!r||l!==s&&i===a?!1:n?!0:a!==i&&t===u},Vo={duration:200,easing:"ease"},qn="transform",qo=Re.Transition.toString({property:qn,duration:0,easing:"linear"}),Ho={roleDescription:"sortable"};function Jo(e){let{disabled:t,index:n,node:r,rect:i}=e;const[s,a]=c.useState(null),l=c.useRef(n);return pe(()=>{if(!t&&n!==l.current&&r.current){const u=i.current;if(u){const d=Ze(r.current,{ignoreTransform:!0}),f={x:u.left-d.left,y:u.top-d.top,scaleX:u.width/d.width,scaleY:u.height/d.height};(f.x||f.y)&&a(f)}}n!==l.current&&(l.current=n)},[t,n,r,i]),c.useEffect(()=>{s&&a(null)},[s]),s}function Hn(e){let{animateLayoutChanges:t=Xo,attributes:n,disabled:r,data:i,getNewIndex:s=Ko,id:a,strategy:l,resizeObserverConfig:u,transition:d=Vo}=e;const{items:f,containerId:v,activeIndex:b,disabled:h,disableTransforms:w,sortedRects:m,overIndex:y,useDragOverlay:C,strategy:x}=c.useContext(Vn),E=Go(r,h),T=f.indexOf(a),D=c.useMemo(()=>({sortable:{containerId:v,index:T,items:f},...i}),[v,i,T,f]),I=c.useMemo(()=>f.slice(f.indexOf(a)),[f,a]),{rect:O,node:A,isOver:N,setNodeRef:L}=To({id:a,data:D,disabled:E.droppable,resizeObserverConfig:{updateMeasurementsFor:I,...u}}),{active:M,activatorEvent:z,activeNodeRect:Y,attributes:q,setNodeRef:me,listeners:Ye,isDragging:J,over:We,setActivatorNodeRef:de,transform:Me}=So({id:a,data:D,attributes:{...Ho,...n},disabled:E.draggable}),Ue=ir(L,me),H=!!M,fe=H&&!w&&kt(b)&&kt(y),Ae=!C&&J,Ke=Ae&&fe?Me:null,ke=fe?Ke??(l??x)({rects:m,activeNodeRect:Y,activeIndex:b,overIndex:y,index:T}):null,ie=kt(b)&&kt(y)?s({id:a,items:f,activeIndex:b,overIndex:y}):T,se=M?.id,j=c.useRef({activeId:se,items:f,newIndex:ie,containerId:v}),Xe=f!==j.current.items,ae=t({active:M,containerId:v,isDragging:J,isSorting:H,id:a,index:T,items:f,newIndex:j.current.newIndex,previousItems:j.current.items,previousContainerId:j.current.containerId,transition:d,wasDragging:j.current.activeId!=null}),je=Jo({disabled:!ae,index:T,node:A,rect:O});return c.useEffect(()=>{H&&j.current.newIndex!==ie&&(j.current.newIndex=ie),v!==j.current.containerId&&(j.current.containerId=v),f!==j.current.items&&(j.current.items=f)},[H,ie,v,f]),c.useEffect(()=>{if(se===j.current.activeId)return;if(se!=null&&j.current.activeId==null){j.current.activeId=se;return}const xe=setTimeout(()=>{j.current.activeId=se},50);return()=>clearTimeout(xe)},[se]),{active:M,activeIndex:b,attributes:q,data:D,rect:O,index:T,newIndex:ie,items:f,isOver:N,isSorting:H,isDragging:J,listeners:Ye,node:A,overIndex:y,over:We,setNodeRef:Ue,setActivatorNodeRef:de,setDroppableNodeRef:L,setDraggableNodeRef:me,transform:je??ke,transition:ye()};function ye(){if(je||Xe&&j.current.newIndex===T)return qo;if(!(Ae&&!Ot(z)||!d)&&(H||ae))return Re.Transition.toString({...d,property:qn})}}function Go(e,t){var n,r;return typeof e=="boolean"?{draggable:e,droppable:!1}:{draggable:(n=e?.draggable)!=null?n:t.draggable,droppable:(r=e?.droppable)!=null?r:t.droppable}}P.Down,P.Right,P.Up,P.Left;const Jn=(...e)=>e.filter(Boolean).join(" ");function Gn({card:e}){const{attributes:t,listeners:n,setNodeRef:r,transform:i,transition:s,isDragging:a}=Hn({id:e.id}),l={transform:Re.Transform.toString(i),transition:s,opacity:a?.5:void 0};return F.jsx("div",{ref:r,style:l,...t,...n,children:F.jsxs(Te.Card,{className:"mb-2 cursor-grab active:cursor-grabbing border-border bg-card/60 hover:border-primary/40 hover:shadow-lg hover:shadow-primary/10 transition-all duration-300 group",children:[F.jsxs(Te.CardHeader,{className:"p-4",children:[F.jsx(Te.CardTitle,{className:"text-sm font-medium font-mono tracking-tight text-foreground group-hover:text-primary transition-colors",children:e.title}),e.description&&F.jsx(Te.CardDescription,{className:"text-xs text-muted-foreground font-mono",children:e.description})]}),e.badges&&e.badges.length>0&&F.jsx(Te.CardContent,{className:"p-4 pt-0",children:F.jsx("div",{className:"flex flex-wrap gap-1",children:e.badges.map((u,d)=>F.jsx(Te.Badge,{variant:u.variant||"default",className:"text-xs",children:u.label},d))})})]})})}function Qo({column:e,cards:t}){const n=t||[],{setNodeRef:r}=Hn({id:e.id,data:{type:"column"}}),i=e.limit&&n.length>=e.limit;return F.jsxs("div",{ref:r,className:Jn("flex flex-col w-80 flex-shrink-0 rounded-lg border border-border bg-card/20 backdrop-blur-sm shadow-xl",e.className),children:[F.jsx("div",{className:"p-4 border-b border-border/50 bg-muted/20",children:F.jsxs("div",{className:"flex items-center justify-between",children:[F.jsx("h3",{className:"font-mono text-sm font-semibold tracking-wider text-primary/90 uppercase",children:e.title}),F.jsxs("div",{className:"flex items-center gap-2",children:[F.jsxs("span",{className:"font-mono text-xs text-muted-foreground",children:[n.length,e.limit&&` / ${e.limit}`]}),i&&F.jsx(Te.Badge,{variant:"destructive",className:"text-xs",children:"Full"})]})]})}),F.jsx(Te.ScrollArea,{className:"flex-1 p-4",children:F.jsx(Uo,{items:n.map(s=>s.id),strategy:Yo,children:F.jsx("div",{className:"space-y-2",children:n.map(s=>F.jsx(Gn,{card:s},s.id))})})})]})}function Zo({columns:e,onCardMove:t,className:n}){const[r,i]=ze.useState(null),s=ze.useMemo(()=>(e||[]).map(w=>({...w,cards:w.cards||[]})),[e]),[a,l]=ze.useState(s);ze.useEffect(()=>{l(s)},[s]);const u=xr(yr(Qt,{activationConstraint:{distance:8}})),d=w=>{const{active:m}=w,y=v(m.id);i(y)},f=w=>{const{active:m,over:y}=w;if(i(null),!y)return;const C=m.id,x=y.id;if(C===x)return;const E=b(C),T=b(x)||h(x);if(!(!E||!T))if(E.id===T.id){const D=[...E.cards],I=D.findIndex(N=>N.id===C),O=D.findIndex(N=>N.id===x),A=rn(D,I,O);l(N=>N.map(L=>L.id===E.id?{...L,cards:A}:L))}else{const D=[...E.cards],I=[...T.cards],O=D.findIndex(M=>M.id===C),N=x===T.id?I.length:I.findIndex(M=>M.id===x),[L]=D.splice(O,1);I.splice(N,0,L),l(M=>M.map(z=>z.id===E.id?{...z,cards:D}:z.id===T.id?{...z,cards:I}:z)),t&&t(C,E.id,T.id,N)}},v=ze.useCallback(w=>{for(const m of a){const y=m.cards.find(C=>C.id===w);if(y)return y}return null},[a]),b=ze.useCallback(w=>a.find(m=>m.cards.some(y=>y.id===w))||null,[a]),h=ze.useCallback(w=>a.find(m=>m.id===w)||null,[a]);return F.jsxs(wo,{sensors:u,collisionDetection:Or,onDragStart:d,onDragEnd:f,children:[F.jsx("div",{className:Jn("flex gap-4 overflow-x-auto p-4",n),children:a.map(w=>F.jsx(Qo,{column:w,cards:w.cards},w.id))}),F.jsx(Fo,{children:r?F.jsx(Gn,{card:r}):null})]})}const ei=Object.freeze(Object.defineProperty({__proto__:null,default:Zo},Symbol.toStringTag,{value:"Module"}));he.KanbanRenderer=Yt,he.kanbanComponents=or,Object.defineProperty(he,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { BaseSchema } from '../../types/src';
|
|
2
|
+
/**
|
|
3
|
+
* Kanban card interface.
|
|
4
|
+
*/
|
|
5
|
+
export interface KanbanCard {
|
|
6
|
+
id: string;
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
badges?: Array<{
|
|
10
|
+
label: string;
|
|
11
|
+
variant?: "default" | "secondary" | "destructive" | "outline";
|
|
12
|
+
}>;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Kanban column interface.
|
|
17
|
+
*/
|
|
18
|
+
export interface KanbanColumn {
|
|
19
|
+
id: string;
|
|
20
|
+
title: string;
|
|
21
|
+
cards: KanbanCard[];
|
|
22
|
+
limit?: number;
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Kanban Board component schema.
|
|
27
|
+
* Renders a drag-and-drop kanban board for task management.
|
|
28
|
+
*/
|
|
29
|
+
export interface KanbanSchema extends BaseSchema {
|
|
30
|
+
type: 'kanban';
|
|
31
|
+
/**
|
|
32
|
+
* Array of columns to display in the kanban board.
|
|
33
|
+
* Each column contains an array of cards.
|
|
34
|
+
*/
|
|
35
|
+
columns?: KanbanColumn[];
|
|
36
|
+
/**
|
|
37
|
+
* Callback function when a card is moved between columns or reordered.
|
|
38
|
+
*/
|
|
39
|
+
onCardMove?: (cardId: string, fromColumnId: string, toColumnId: string, newIndex: number) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Optional CSS class name to apply custom styling.
|
|
42
|
+
*/
|
|
43
|
+
className?: string;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IACjG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,IAAI,EAAE,QAAQ,CAAC;IAEf;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IAEzB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAElG;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@object-ui/plugin-kanban",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.umd.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.umd.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@dnd-kit/core": "^6.3.1",
|
|
18
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
19
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
20
|
+
"@object-ui/components": "0.3.0",
|
|
21
|
+
"@object-ui/core": "0.3.0",
|
|
22
|
+
"@object-ui/react": "0.3.0",
|
|
23
|
+
"@object-ui/types": "0.3.0"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
27
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/react": "^18.3.12",
|
|
31
|
+
"@types/react-dom": "^18.3.1",
|
|
32
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
33
|
+
"typescript": "^5.9.3",
|
|
34
|
+
"vite": "^7.3.1",
|
|
35
|
+
"vite-plugin-dts": "^4.5.4"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "vite build",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest",
|
|
41
|
+
"type-check": "tsc --noEmit",
|
|
42
|
+
"lint": "eslint ."
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import {
|
|
3
|
+
DndContext,
|
|
4
|
+
DragEndEvent,
|
|
5
|
+
DragOverlay,
|
|
6
|
+
DragStartEvent,
|
|
7
|
+
PointerSensor,
|
|
8
|
+
useSensor,
|
|
9
|
+
useSensors,
|
|
10
|
+
closestCorners,
|
|
11
|
+
} from "@dnd-kit/core"
|
|
12
|
+
import {
|
|
13
|
+
SortableContext,
|
|
14
|
+
arrayMove,
|
|
15
|
+
useSortable,
|
|
16
|
+
verticalListSortingStrategy,
|
|
17
|
+
} from "@dnd-kit/sortable"
|
|
18
|
+
import { CSS } from "@dnd-kit/utilities"
|
|
19
|
+
import { Badge, Card, CardHeader, CardTitle, CardDescription, CardContent, ScrollArea } from "@object-ui/components"
|
|
20
|
+
|
|
21
|
+
// Utility function to merge class names (inline to avoid external dependency)
|
|
22
|
+
const cn = (...classes: (string | undefined)[]) => classes.filter(Boolean).join(' ')
|
|
23
|
+
|
|
24
|
+
export interface KanbanCard {
|
|
25
|
+
id: string
|
|
26
|
+
title: string
|
|
27
|
+
description?: string
|
|
28
|
+
badges?: Array<{ label: string; variant?: "default" | "secondary" | "destructive" | "outline" }>
|
|
29
|
+
[key: string]: any
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface KanbanColumn {
|
|
33
|
+
id: string
|
|
34
|
+
title: string
|
|
35
|
+
cards: KanbanCard[]
|
|
36
|
+
limit?: number
|
|
37
|
+
className?: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface KanbanBoardProps {
|
|
41
|
+
columns: KanbanColumn[]
|
|
42
|
+
onCardMove?: (cardId: string, fromColumnId: string, toColumnId: string, newIndex: number) => void
|
|
43
|
+
className?: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function SortableCard({ card }: { card: KanbanCard }) {
|
|
47
|
+
const {
|
|
48
|
+
attributes,
|
|
49
|
+
listeners,
|
|
50
|
+
setNodeRef,
|
|
51
|
+
transform,
|
|
52
|
+
transition,
|
|
53
|
+
isDragging,
|
|
54
|
+
} = useSortable({ id: card.id })
|
|
55
|
+
|
|
56
|
+
const style = {
|
|
57
|
+
transform: CSS.Transform.toString(transform),
|
|
58
|
+
transition,
|
|
59
|
+
opacity: isDragging ? 0.5 : undefined,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div ref={setNodeRef} style={style} {...attributes} {...listeners}>
|
|
64
|
+
<Card className="mb-2 cursor-grab active:cursor-grabbing border-border bg-card/60 hover:border-primary/40 hover:shadow-lg hover:shadow-primary/10 transition-all duration-300 group">
|
|
65
|
+
<CardHeader className="p-4">
|
|
66
|
+
<CardTitle className="text-sm font-medium font-mono tracking-tight text-foreground group-hover:text-primary transition-colors">{card.title}</CardTitle>
|
|
67
|
+
{card.description && (
|
|
68
|
+
<CardDescription className="text-xs text-muted-foreground font-mono">
|
|
69
|
+
{card.description}
|
|
70
|
+
</CardDescription>
|
|
71
|
+
)}
|
|
72
|
+
</CardHeader>
|
|
73
|
+
{card.badges && card.badges.length > 0 && (
|
|
74
|
+
<CardContent className="p-4 pt-0">
|
|
75
|
+
<div className="flex flex-wrap gap-1">
|
|
76
|
+
{card.badges.map((badge, index) => (
|
|
77
|
+
<Badge key={index} variant={badge.variant || "default"} className="text-xs">
|
|
78
|
+
{badge.label}
|
|
79
|
+
</Badge>
|
|
80
|
+
))}
|
|
81
|
+
</div>
|
|
82
|
+
</CardContent>
|
|
83
|
+
)}
|
|
84
|
+
</Card>
|
|
85
|
+
</div>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function KanbanColumn({
|
|
90
|
+
column,
|
|
91
|
+
cards,
|
|
92
|
+
}: {
|
|
93
|
+
column: KanbanColumn
|
|
94
|
+
cards: KanbanCard[]
|
|
95
|
+
}) {
|
|
96
|
+
const safeCards = cards || [];
|
|
97
|
+
const { setNodeRef } = useSortable({
|
|
98
|
+
id: column.id,
|
|
99
|
+
data: {
|
|
100
|
+
type: "column",
|
|
101
|
+
},
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
const isLimitExceeded = column.limit && safeCards.length >= column.limit
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<div
|
|
108
|
+
ref={setNodeRef}
|
|
109
|
+
className={cn(
|
|
110
|
+
"flex flex-col w-80 flex-shrink-0 rounded-lg border border-border bg-card/20 backdrop-blur-sm shadow-xl",
|
|
111
|
+
column.className
|
|
112
|
+
)}
|
|
113
|
+
>
|
|
114
|
+
<div className="p-4 border-b border-border/50 bg-muted/20">
|
|
115
|
+
<div className="flex items-center justify-between">
|
|
116
|
+
<h3 className="font-mono text-sm font-semibold tracking-wider text-primary/90 uppercase">{column.title}</h3>
|
|
117
|
+
<div className="flex items-center gap-2">
|
|
118
|
+
<span className="font-mono text-xs text-muted-foreground">
|
|
119
|
+
{safeCards.length}
|
|
120
|
+
{column.limit && ` / ${column.limit}`}
|
|
121
|
+
</span>
|
|
122
|
+
{isLimitExceeded && (
|
|
123
|
+
<Badge variant="destructive" className="text-xs">
|
|
124
|
+
Full
|
|
125
|
+
</Badge>
|
|
126
|
+
)}
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
<ScrollArea className="flex-1 p-4">
|
|
131
|
+
<SortableContext
|
|
132
|
+
items={safeCards.map((c) => c.id)}
|
|
133
|
+
strategy={verticalListSortingStrategy}
|
|
134
|
+
>
|
|
135
|
+
<div className="space-y-2">
|
|
136
|
+
{safeCards.map((card) => (
|
|
137
|
+
<SortableCard key={card.id} card={card} />
|
|
138
|
+
))}
|
|
139
|
+
</div>
|
|
140
|
+
</SortableContext>
|
|
141
|
+
</ScrollArea>
|
|
142
|
+
</div>
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export default function KanbanBoard({ columns, onCardMove, className }: KanbanBoardProps) {
|
|
147
|
+
const [activeCard, setActiveCard] = React.useState<KanbanCard | null>(null)
|
|
148
|
+
|
|
149
|
+
// Ensure we always have valid columns with cards array
|
|
150
|
+
const safeColumns = React.useMemo(() => {
|
|
151
|
+
return (columns || []).map(col => ({
|
|
152
|
+
...col,
|
|
153
|
+
cards: col.cards || []
|
|
154
|
+
}));
|
|
155
|
+
}, [columns]);
|
|
156
|
+
|
|
157
|
+
const [boardColumns, setBoardColumns] = React.useState<KanbanColumn[]>(safeColumns)
|
|
158
|
+
|
|
159
|
+
React.useEffect(() => {
|
|
160
|
+
setBoardColumns(safeColumns)
|
|
161
|
+
}, [safeColumns])
|
|
162
|
+
|
|
163
|
+
const sensors = useSensors(
|
|
164
|
+
useSensor(PointerSensor, {
|
|
165
|
+
activationConstraint: {
|
|
166
|
+
distance: 8,
|
|
167
|
+
},
|
|
168
|
+
})
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
const handleDragStart = (event: DragStartEvent) => {
|
|
172
|
+
const { active } = event
|
|
173
|
+
const card = findCard(active.id as string)
|
|
174
|
+
setActiveCard(card)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const handleDragEnd = (event: DragEndEvent) => {
|
|
178
|
+
const { active, over } = event
|
|
179
|
+
setActiveCard(null)
|
|
180
|
+
|
|
181
|
+
if (!over) return
|
|
182
|
+
|
|
183
|
+
const activeId = active.id as string
|
|
184
|
+
const overId = over.id as string
|
|
185
|
+
|
|
186
|
+
if (activeId === overId) return
|
|
187
|
+
|
|
188
|
+
const activeColumn = findColumnByCardId(activeId)
|
|
189
|
+
const overColumn = findColumnByCardId(overId) || findColumnById(overId)
|
|
190
|
+
|
|
191
|
+
if (!activeColumn || !overColumn) return
|
|
192
|
+
|
|
193
|
+
if (activeColumn.id === overColumn.id) {
|
|
194
|
+
// Same column reordering
|
|
195
|
+
const cards = [...activeColumn.cards]
|
|
196
|
+
const oldIndex = cards.findIndex((c) => c.id === activeId)
|
|
197
|
+
const newIndex = cards.findIndex((c) => c.id === overId)
|
|
198
|
+
|
|
199
|
+
const newCards = arrayMove(cards, oldIndex, newIndex)
|
|
200
|
+
setBoardColumns((prev) =>
|
|
201
|
+
prev.map((col) =>
|
|
202
|
+
col.id === activeColumn.id ? { ...col, cards: newCards } : col
|
|
203
|
+
)
|
|
204
|
+
)
|
|
205
|
+
} else {
|
|
206
|
+
// Moving between columns
|
|
207
|
+
const activeCards = [...activeColumn.cards]
|
|
208
|
+
const overCards = [...overColumn.cards]
|
|
209
|
+
const activeIndex = activeCards.findIndex((c) => c.id === activeId)
|
|
210
|
+
|
|
211
|
+
// Calculate target index: if dropping on column itself, append to end; otherwise insert at card position
|
|
212
|
+
const isDroppingOnColumn = overId === overColumn.id
|
|
213
|
+
const overIndex = isDroppingOnColumn
|
|
214
|
+
? overCards.length
|
|
215
|
+
: overCards.findIndex((c) => c.id === overId)
|
|
216
|
+
|
|
217
|
+
const [movedCard] = activeCards.splice(activeIndex, 1)
|
|
218
|
+
overCards.splice(overIndex, 0, movedCard)
|
|
219
|
+
|
|
220
|
+
setBoardColumns((prev) =>
|
|
221
|
+
prev.map((col) => {
|
|
222
|
+
if (col.id === activeColumn.id) {
|
|
223
|
+
return { ...col, cards: activeCards }
|
|
224
|
+
}
|
|
225
|
+
if (col.id === overColumn.id) {
|
|
226
|
+
return { ...col, cards: overCards }
|
|
227
|
+
}
|
|
228
|
+
return col
|
|
229
|
+
})
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
if (onCardMove) {
|
|
233
|
+
onCardMove(activeId, activeColumn.id, overColumn.id, overIndex)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const findCard = React.useCallback(
|
|
239
|
+
(cardId: string): KanbanCard | null => {
|
|
240
|
+
for (const column of boardColumns) {
|
|
241
|
+
const card = column.cards.find((c) => c.id === cardId)
|
|
242
|
+
if (card) return card
|
|
243
|
+
}
|
|
244
|
+
return null
|
|
245
|
+
},
|
|
246
|
+
[boardColumns]
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
const findColumnByCardId = React.useCallback(
|
|
250
|
+
(cardId: string): KanbanColumn | null => {
|
|
251
|
+
return boardColumns.find((col) => col.cards.some((c) => c.id === cardId)) || null
|
|
252
|
+
},
|
|
253
|
+
[boardColumns]
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
const findColumnById = React.useCallback(
|
|
257
|
+
(columnId: string): KanbanColumn | null => {
|
|
258
|
+
return boardColumns.find((col) => col.id === columnId) || null
|
|
259
|
+
},
|
|
260
|
+
[boardColumns]
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<DndContext
|
|
265
|
+
sensors={sensors}
|
|
266
|
+
collisionDetection={closestCorners}
|
|
267
|
+
onDragStart={handleDragStart}
|
|
268
|
+
onDragEnd={handleDragEnd}
|
|
269
|
+
>
|
|
270
|
+
<div className={cn("flex gap-4 overflow-x-auto p-4", className)}>
|
|
271
|
+
{boardColumns.map((column) => (
|
|
272
|
+
<KanbanColumn
|
|
273
|
+
key={column.id}
|
|
274
|
+
column={column}
|
|
275
|
+
cards={column.cards}
|
|
276
|
+
/>
|
|
277
|
+
))}
|
|
278
|
+
</div>
|
|
279
|
+
<DragOverlay>
|
|
280
|
+
{activeCard ? <SortableCard card={activeCard} /> : null}
|
|
281
|
+
</DragOverlay>
|
|
282
|
+
</DndContext>
|
|
283
|
+
)
|
|
284
|
+
}
|