@misael703/ui 1.57.1 → 1.59.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/dist/{chunk-CPMQ2DFS.js → chunk-2ET7IM4U.js} +77 -33
- package/dist/chunk-2ET7IM4U.js.map +1 -0
- package/dist/chunk-2RBVHLG4.mjs +305 -0
- package/dist/chunk-2RBVHLG4.mjs.map +1 -0
- package/dist/{chunk-HKHGODQE.js → chunk-4HHP3WT7.js} +4 -4
- package/dist/{chunk-HKHGODQE.js.map → chunk-4HHP3WT7.js.map} +1 -1
- package/dist/chunk-BULIPFOG.js +313 -0
- package/dist/chunk-BULIPFOG.js.map +1 -0
- package/dist/{chunk-S3DEFKS5.js → chunk-DLDTUVHR.js} +3 -3
- package/dist/{chunk-S3DEFKS5.js.map → chunk-DLDTUVHR.js.map} +1 -1
- package/dist/{chunk-O6FCBNWN.mjs → chunk-EJY4QWHT.mjs} +77 -33
- package/dist/chunk-EJY4QWHT.mjs.map +1 -0
- package/dist/{chunk-G4OOD6AR.mjs → chunk-F5EK5PIR.mjs} +3 -3
- package/dist/{chunk-G4OOD6AR.mjs.map → chunk-F5EK5PIR.mjs.map} +1 -1
- package/dist/{chunk-6OBFBETV.mjs → chunk-I7JH3OEO.mjs} +3 -3
- package/dist/{chunk-6OBFBETV.mjs.map → chunk-I7JH3OEO.mjs.map} +1 -1
- package/dist/{chunk-T46LLZHX.js → chunk-KNQOG43N.js} +4 -4
- package/dist/{chunk-T46LLZHX.js.map → chunk-KNQOG43N.js.map} +1 -1
- package/dist/{chunk-MSDFMVIF.js → chunk-NPUNAVWM.js} +3 -3
- package/dist/{chunk-MSDFMVIF.js.map → chunk-NPUNAVWM.js.map} +1 -1
- package/dist/{chunk-J2HHAZHV.mjs → chunk-X7BV2JFX.mjs} +3 -3
- package/dist/{chunk-J2HHAZHV.mjs.map → chunk-X7BV2JFX.mjs.map} +1 -1
- package/dist/{chunk-XJHK3RH5.mjs → chunk-ZAKJKBUX.mjs} +3 -3
- package/dist/{chunk-XJHK3RH5.mjs.map → chunk-ZAKJKBUX.mjs.map} +1 -1
- package/dist/components/AppShell.js +4 -4
- package/dist/components/AppShell.mjs +2 -2
- package/dist/components/Charts.d.mts +25 -15
- package/dist/components/Charts.d.ts +25 -15
- package/dist/components/Charts.js +6 -6
- package/dist/components/Charts.mjs +1 -1
- package/dist/components/Commerce.js +14 -14
- package/dist/components/Commerce.mjs +3 -3
- package/dist/components/Editing.js +9 -9
- package/dist/components/Editing.mjs +3 -3
- package/dist/components/Metrics.d.mts +130 -0
- package/dist/components/Metrics.d.ts +130 -0
- package/dist/components/Metrics.js +41 -0
- package/dist/components/Metrics.js.map +1 -0
- package/dist/components/Metrics.mjs +8 -0
- package/dist/components/Metrics.mjs.map +1 -0
- package/dist/components/Overlay.js +4 -4
- package/dist/components/Overlay.mjs +2 -2
- package/dist/hooks/index.js +5 -5
- package/dist/hooks/index.mjs +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +98 -69
- package/dist/index.mjs +12 -11
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-CPMQ2DFS.js.map +0 -1
- package/dist/chunk-O6FCBNWN.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkDLDTUVHR_js = require('./chunk-DLDTUVHR.js');
|
|
5
5
|
var chunk6SSTTJV4_js = require('./chunk-6SSTTJV4.js');
|
|
6
6
|
var chunkA42WMR4M_js = require('./chunk-A42WMR4M.js');
|
|
7
7
|
var chunkC4AKMVDZ_js = require('./chunk-C4AKMVDZ.js');
|
|
@@ -55,7 +55,7 @@ function ConfirmDialog({
|
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
57
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
58
|
-
|
|
58
|
+
chunkDLDTUVHR_js.Modal,
|
|
59
59
|
{
|
|
60
60
|
open,
|
|
61
61
|
onClose,
|
|
@@ -306,5 +306,5 @@ exports.DescriptionListItem = DescriptionListItem;
|
|
|
306
306
|
exports.DiffViewer = DiffViewer;
|
|
307
307
|
exports.EditableCell = EditableCell;
|
|
308
308
|
exports.TransferList = TransferList;
|
|
309
|
-
//# sourceMappingURL=chunk-
|
|
310
|
-
//# sourceMappingURL=chunk-
|
|
309
|
+
//# sourceMappingURL=chunk-4HHP3WT7.js.map
|
|
310
|
+
//# sourceMappingURL=chunk-4HHP3WT7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Editing.tsx"],"names":["React","useLocale","jsx","Modal","jsxs","Fragment","cx","Checkbox","ChevronRight","ChevronLeft","Edit"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EAAM,OAAA;AAAA,EAAS,SAAA;AAAA,EAAW,KAAA;AAAA,EAAO,WAAA;AAAA,EACjC,YAAA;AAAA,EAAc,WAAA;AAAA,EACd,IAAA,GAAO,SAAA;AAAA,EAAW;AACpB,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUA,0BAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,SAAS,OAAA,IAAW,IAAA;AAC1B,EAAA,MAAM,IAAIC,0BAAA,EAAU;AACpB,EAAA,MAAM,WAAA,GAAc,YAAA,IAAgB,CAAA,CAAE,gBAAgB,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,WAAA,IAAe,CAAA,CAAE,eAAe,CAAA;AAEnD,EAAA,MAAM,gBAAgB,YAAY;AAChC,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA,MAAM,SAAA,EAAU;AAChB,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA,SAAE;AACA,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf;AAAA,EACF,CAAA;AAEA,EAAA,uBACEC,cAAA;AAAA,IAACC,sBAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA,EAAK,IAAA;AAAA,MACL,KAAA;AAAA,MACA,wBACEC,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAAH,cAAA,CAAC,QAAA,EAAA,EAAO,MAAK,QAAA,EAAS,SAAA,EAAU,0BAAyB,OAAA,EAAS,OAAA,EAAS,QAAA,EAAU,MAAA,EAClF,QAAA,EAAA,UAAA,EACH,CAAA;AAAA,wBACAE,eAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,WAAWE,mBAAA,CAAG,KAAA,EAAO,SAAS,QAAA,GAAW,aAAA,GAAgB,gBAAgB,SAAS,CAAA;AAAA,YAClF,OAAA,EAAS,aAAA;AAAA,YACT,QAAA,EAAU,MAAA;AAAA,YACV,aAAW,MAAA,IAAU,MAAA;AAAA,YAEpB,QAAA,EAAA;AAAA,cAAA,MAAA,kCAAU,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA2B,aAAA,EAAY,QAAO,CAAA,GAAK,IAAA;AAAA,cAC5E;AAAA;AAAA;AAAA;AACH,OAAA,EACF,CAAA;AAAA,MAGD,QAAA,EAAA,WAAA,oBAAeJ,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iBAAiB,QAAA,EAAA,WAAA,EAAY;AAAA;AAAA,GAC5D;AAEJ;AAWO,SAAS,gBAAgB,EAAE,QAAA,EAAU,SAAA,EAAW,GAAG,MAAK,EAA2C;AACxG,EAAA,uBAAOA,cAAA,CAAC,QAAG,SAAA,EAAWI,mBAAA,CAAG,aAAa,SAAS,CAAA,EAAI,GAAG,IAAA,EAAO,QAAA,EAAS,CAAA;AACxE;AAEO,SAAS,oBAAoB,EAAE,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,UAAS,EAA6B;AAChG,EAAA,MAAM,IAAIL,0BAAA,EAAU;AACpB,EAAA,uBACEG,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAH,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,kBAAA,EAAoB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,oBACxCE,eAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,kBAAA,EACZ,QAAA,EAAA;AAAA,sBAAAF,cAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MACZ,QAAA,IAAY,MAAA,oBACXA,cAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,SAAA,EAAU,iBAAA,EAAkB,OAAA,EAAS,MAAA,EACxD,QAAA,EAAA,CAAA,CAAE,eAAe,CAAA,EACpB;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;AAaO,SAAS,WAAW,EAAE,OAAA,EAAS,SAAA,EAAW,GAAG,MAAK,EAAoB;AAC3E,EAAA,MAAM,IAAID,0BAAA,EAAU;AAGpB,EAAA,MAAM,WAAA,GAAc,OAAO,CAAA,CAAE,aAAa,MAAM,QAAA,GAAW,CAAA,CAAE,aAAa,CAAA,GAAI,MAAA;AAC9E,EAAA,MAAM,UAAA,GAAa,OAAO,CAAA,CAAE,YAAY,MAAM,QAAA,GAAW,CAAA,CAAE,YAAY,CAAA,GAAI,MAAA;AAC3E,EAAA,uBACEG,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAWE,mBAAA,CAAG,QAAQ,SAAS,CAAA,EAAG,IAAA,EAAK,OAAA,EAAQ,YAAA,EAAY,CAAA,CAAE,YAAY,CAAA,EAAI,GAAG,IAAA,EACnF,QAAA,EAAA;AAAA,oBAAAF,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,YAAA,EAAa,IAAA,EAAK,KAAA,EAC/B,QAAA,EAAA;AAAA,sBAAAF,cAAA,CAAC,KAAA,EAAA,EAAI,IAAA,EAAK,cAAA,EAAgB,QAAA,EAAA,CAAA,CAAE,YAAY,CAAA,EAAE,CAAA;AAAA,qCACzC,KAAA,EAAA,EAAI,IAAA,EAAK,cAAA,EAAgB,QAAA,EAAA,CAAA,CAAE,aAAa,CAAA,EAAE,CAAA;AAAA,qCAC1C,KAAA,EAAA,EAAI,IAAA,EAAK,cAAA,EAAgB,QAAA,EAAA,CAAA,CAAE,YAAY,CAAA,EAAE;AAAA,KAAA,EAC5C,CAAA;AAAA,IACC,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qCACd,KAAA,EAAA,EAAY,SAAA,EAAU,WAAA,EAAY,IAAA,EAAK,KAAA,EACtC,QAAA,EAAA;AAAA,sBAAAA,cAAA,CAAC,SAAI,SAAA,EAAU,aAAA,EAAc,IAAA,EAAK,MAAA,EAAQ,YAAE,KAAA,EAAM,CAAA;AAAA,sBAClDA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,cAAA,EAAe,IAAA,EAAK,MAAA,EAAO,YAAA,EAAY,WAAA,EAAa,QAAA,kBAAAA,cAAA,CAAC,KAAA,EAAA,EAAK,QAAA,EAAA,CAAA,CAAE,MAAA,EAAO,CAAA,EAAM,CAAA;AAAA,sBACxFA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EAAc,IAAA,EAAK,MAAA,EAAO,YAAA,EAAY,UAAA,EAAY,QAAA,kBAAAA,cAAA,CAAC,KAAA,EAAA,EAAK,QAAA,EAAA,CAAA,CAAE,KAAA,EAAM,CAAA,EAAM;AAAA,KAAA,EAAA,EAH7E,CAIV,CACD;AAAA,GAAA,EACH,CAAA;AAEJ;AAmBO,SAAS,YAAA,CAAa;AAAA,EAC3B,MAAA;AAAA,EAAQ,QAAA;AAAA,EAAU,QAAA;AAAA,EAClB,WAAA;AAAA,EAAa,aAAA;AAAA,EACb;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,IAAUF,gBAAA,CAAA,QAAA,iBAAsB,IAAI,KAAK,CAAA;AAC3E,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,IAAUA,gBAAA,CAAA,QAAA,iBAAsB,IAAI,KAAK,CAAA;AAC7E,EAAA,MAAM,IAAIC,0BAAA,EAAU;AACpB,EAAA,MAAM,QAAA,GAAW,WAAA,IAAe,CAAA,CAAE,oBAAoB,CAAA;AACtD,EAAA,MAAM,QAAA,GAAW,aAAA,IAAiB,CAAA,CAAE,mBAAmB,CAAA;AAKvD,EAAA,MAAM,WAAA,GAAoBD,gBAAA,CAAA,OAAA;AAAA,IACxB,MAAM,IAAI,GAAA,CAAI,QAAA,CAAS,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,IACvC,CAAC,QAAQ;AAAA,GACX;AACA,EAAA,MAAM,IAAA,GAAaA,gBAAA,CAAA,OAAA;AAAA,IACjB,MAAM,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,IACjD,CAAC,QAAQ,WAAW;AAAA,GACtB;AACA,EAAA,MAAM,KAAA,GAAQ,QAAA;AAEd,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,MAAM,MAAA,GAAS,KAAK,MAAA,CAAO,CAAC,MAAM,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AACvD,IAAA,QAAA,CAAS,CAAC,GAAG,KAAA,EAAO,GAAG,MAAM,CAAC,CAAA;AAC9B,IAAA,cAAA,iBAAe,IAAI,KAAK,CAAA;AAAA,EAC1B,CAAA;AACA,EAAA,MAAM,WAAW,MAAM;AACrB,IAAA,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,aAAa,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAC,CAAA;AACrD,IAAA,eAAA,iBAAgB,IAAI,KAAK,CAAA;AAAA,EAC3B,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,GAAA,EAAkB,MAAA,EAAkC,EAAA,KAAe;AACtF,IAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,GAAG,CAAA;AACxB,IAAA,IAAI,KAAK,GAAA,CAAI,EAAE,CAAA,EAAG,IAAA,CAAK,OAAO,EAAE,CAAA;AAAA,SAAQ,IAAA,CAAK,IAAI,EAAE,CAAA;AACnD,IAAA,MAAA,CAAO,IAAI,CAAA;AAAA,EACb,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,KAAA,EAAwB,KAAA,EAAuB,SAAsB,UAAA,qBACzFI,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,oBAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,sBAC7CA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAA,EAAuB,gBAAM,MAAA,EAAO;AAAA,KAAA,EACtD,CAAA;AAAA,oBACAA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,gBAAA,EAAiB,IAAA,EAAK,SAAA,EAAU,YAAA,EAAY,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA,EAC3F,QAAA,EAAA,KAAA,CAAM,WAAW,CAAA,mBAChBA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,iBAAA,EAAmB,QAAA,EAAA,CAAA,CAAE,gBAAgB,CAAA,EAAE,CAAA,GACnD,KAAA,CAAM,GAAA,CAAI,CAAC,EAAA,qBACbE,eAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QAEC,SAAA,EAAWE,mBAAA,CAAG,gBAAA,EAAkB,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA,IAAK,YAAA,EAAc,EAAA,CAAG,QAAA,IAAY,aAAa,CAAA;AAAA,QAChG,IAAA,EAAK,QAAA;AAAA,QACL,eAAA,EAAe,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA;AAAA,QAChC,OAAA,EAAS,MAAM,CAAC,EAAA,CAAG,YAAY,WAAA,CAAY,OAAA,EAAS,UAAA,EAAY,EAAA,CAAG,EAAE,CAAA;AAAA,QAErE,QAAA,EAAA;AAAA,0BAAAJ,cAAA,CAAC,UAAK,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,iBAAgB,EACtC,QAAA,kBAAAA,cAAA;AAAA,YAACK,yBAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA;AAAA,cAC1B,UAAU,EAAA,CAAG,QAAA;AAAA,cACb,UAAU,MAAM,WAAA,CAAY,OAAA,EAAS,UAAA,EAAY,GAAG,EAAE;AAAA;AAAA,WACxD,EACF,CAAA;AAAA,0BACAH,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,4BAAAF,cAAA,CAAC,KAAA,EAAA,EAAK,aAAG,KAAA,EAAM,CAAA;AAAA,YACd,GAAG,WAAA,oBAAeA,cAAA,CAAC,SAAI,SAAA,EAAU,qBAAA,EAAuB,aAAG,WAAA,EAAY;AAAA,WAAA,EAC1E;AAAA;AAAA,OAAA;AAAA,MAhBK,EAAA,CAAG;AAAA,KAkBX,CAAA,EACH;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,uCACG,KAAA,EAAA,EAAI,SAAA,EAAWI,mBAAA,CAAG,UAAA,EAAY,SAAS,CAAA,EACrC,QAAA,EAAA;AAAA,IAAA,YAAA,CAAa,QAAA,EAAU,IAAA,EAAM,WAAA,EAAa,cAAc,CAAA;AAAA,oBACzDF,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,cAAA,CAAC,YAAO,IAAA,EAAK,QAAA,EAAS,WAAU,0BAAA,EAA2B,QAAA,EAAU,YAAY,IAAA,KAAS,CAAA,EAAG,SAAS,SAAA,EAAW,YAAA,EAAY,EAAE,yBAAyB,CAAA,EACtJ,yCAACM,6BAAA,EAAA,EAAa,IAAA,EAAM,IAAI,CAAA,EAC1B,CAAA;AAAA,sBACAN,cAAA,CAAC,YAAO,IAAA,EAAK,QAAA,EAAS,WAAU,0BAAA,EAA2B,QAAA,EAAU,aAAa,IAAA,KAAS,CAAA,EAAG,SAAS,QAAA,EAAU,YAAA,EAAY,EAAE,yBAAyB,CAAA,EACtJ,yCAACO,4BAAA,EAAA,EAAY,IAAA,EAAM,IAAI,CAAA,EACzB;AAAA,KAAA,EACF,CAAA;AAAA,IACC,YAAA,CAAa,QAAA,EAAU,KAAA,EAAO,YAAA,EAAc,eAAe;AAAA,GAAA,EAC9D,CAAA;AAEJ;AA0CO,SAAS,YAAA,CAAa;AAAA,EAC3B,KAAA;AAAA,EAAO,QAAA;AAAA,EAAU,IAAA,GAAO,MAAA;AAAA,EAAQ,aAAA;AAAA,EAAe,QAAA;AAAA,EAC/C,QAAA;AAAA,EAAU,WAAA;AAAA,EAAa,SAAA;AAAA,EAAW;AACpC,CAAA,EAAsB;AACpB,EAAA,MAAM,IAAIR,0BAAA,EAAU;AACpB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAUD,0BAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,0BAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAUA,0BAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,0BAAwB,IAAI,CAAA;AAC5D,EAAA,MAAM,QAAA,GAAiBA,wBAAyB,IAAI,CAAA;AAEpD,EAAA,MAAM,YAAA,GAAqBA,wBAAO,KAAK,CAAA;AAEvC,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,IAAI,QAAA,EAAU;AACd,IAAA,QAAA,CAAS,KAAK,CAAA;AACd,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,EACjB,CAAA;AAEA,EAAMA,2BAAU,MAAM;AACpB,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AACxB,MAAA,QAAA,CAAS,SAAS,MAAA,EAAO;AAAA,IAC3B;AAAA,EACF,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,SAAS,YAAY;AACzB,IAAA,IAAI,OAAA,EAAS;AACb,IAAA,IAAI,UAAU,KAAA,EAAO;AAAE,MAAA,UAAA,CAAW,KAAK,CAAA;AAAG,MAAA,QAAA,CAAS,IAAI,CAAA;AAAG,MAAA;AAAA,IAAQ;AAClE,IAAA,MAAM,OAAA,GAAU,QAAA,GAAW,KAAK,CAAA,IAAK,IAAA;AACrC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,QAAA,CAAS,OAAO,CAAA;AAChB,MAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AACxB,MAAA;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,MAAM,SAAS,KAAK,CAAA;AACpB,MAAA,UAAA,CAAW,KAAK,CAAA;AAChB,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,IACf,CAAA,CAAA,MAAQ;AAEN,MAAA,QAAA,CAAS,CAAA,CAAE,sBAAsB,CAAC,CAAA;AAClC,MAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,IAC1B,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,SAAS,MAAM;AACnB,IAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AACvB,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,uBACEI,eAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAWE,mBAAA,CAAG,eAAA,EAAiB,QAAA,IAAY,eAAe,SAAS,CAAA;AAAA,QACnE,OAAA,EAAS,SAAA;AAAA,QACT,QAAA;AAAA,QACA,YAAA,EAAY,SAAA;AAAA,QAEZ,QAAA,EAAA;AAAA,0BAAAJ,cAAA,CAAC,MAAA,EAAA,EAAK,WAAU,sBAAA,EACb,QAAA,EAAA,aAAA,GAAgB,cAAc,KAAK,CAAA,GAAK,SAAS,WAAA,EACpD,CAAA;AAAA,yCACCQ,qBAAA,EAAA,EAAS,IAAA,EAAM,IAAI,SAAA,EAAU,qBAAA,EAAsB,eAAY,MAAA,EAAO;AAAA;AAAA;AAAA,KACzE;AAAA,EAEJ;AAEA,EAAA,uBACER,cAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,QAAA;AAAA,MACL,IAAA;AAAA,MACA,WAAWI,mBAAA,CAAG,OAAA,EAAS,wBAAwB,KAAA,IAAS,IAAA,IAAQ,cAAc,SAAS,CAAA;AAAA,MACvF,KAAA,EAAO,KAAA;AAAA,MACP,QAAA,EAAU,OAAA;AAAA,MACV,WAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MACZ,cAAA,EAAc,SAAS,IAAA,IAAQ,MAAA;AAAA,MAC/B,OAAO,KAAA,IAAS,MAAA;AAAA,MAChB,QAAA,EAAU,CAAC,CAAA,KAAM;AAAE,QAAA,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAG,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MAAG,CAAA;AAAA,MAC7D,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,QAAA,IAAI,CAAA,CAAE,QAAQ,OAAA,EAAS;AAAE,UAAA,CAAA,CAAE,cAAA,EAAe;AAAG,UAAA,KAAK,MAAA,EAAO;AAAA,QAAG,CAAA,MAAA,IACnD,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU;AAAE,UAAA,CAAA,CAAE,cAAA,EAAe;AAAG,UAAA,MAAA,EAAO;AAAA,QAAG;AAAA,MAC/D,CAAA;AAAA,MACA,QAAQ,MAAM;AACZ,QAAA,IAAI,aAAa,OAAA,EAAS;AAAE,UAAA,YAAA,CAAa,OAAA,GAAU,KAAA;AAAO,UAAA;AAAA,QAAQ;AAClE,QAAA,KAAK,MAAA,EAAO;AAAA,MACd;AAAA;AAAA,GACF;AAEJ","file":"chunk-HKHGODQE.js","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { Modal } from './Overlay';\nimport { ChevronLeft, ChevronRight, Edit as EditIcon } from './Icons';\nimport { Checkbox } from './Form';\nimport { useLocale } from '../locale/LocaleProvider';\n\n// ---------- ConfirmDialog -----------------------------------------------\nexport interface ConfirmDialogProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void | Promise<void>;\n title: React.ReactNode;\n description?: React.ReactNode;\n confirmLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n /** 'danger' usa botón rojo. */\n tone?: 'default' | 'danger';\n /** Si true, deshabilita el confirm mientras se ejecuta. */\n loading?: boolean;\n}\n\nexport function ConfirmDialog({\n open, onClose, onConfirm, title, description,\n confirmLabel, cancelLabel,\n tone = 'default', loading,\n}: ConfirmDialogProps) {\n const [busy, setBusy] = React.useState(false);\n const isBusy = loading ?? busy;\n const t = useLocale();\n const confirmText = confirmLabel ?? t['common.confirm'];\n const cancelText = cancelLabel ?? t['common.cancel'];\n\n const handleConfirm = async () => {\n try {\n setBusy(true);\n await onConfirm();\n onClose();\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n size=\"sm\"\n title={title}\n footer={\n <>\n <button type=\"button\" className=\"btn btn--ghost btn--md\" onClick={onClose} disabled={isBusy}>\n {cancelText}\n </button>\n <button\n type=\"button\"\n className={cx('btn', tone === 'danger' ? 'btn--danger' : 'btn--primary', 'btn--md')}\n onClick={handleConfirm}\n disabled={isBusy}\n aria-busy={isBusy || undefined}\n >\n {isBusy ? <span className=\"spinner spinner--inverse\" aria-hidden=\"true\" /> : null}\n {confirmText}\n </button>\n </>\n }\n >\n {description && <p className=\"confirm__desc\">{description}</p>}\n </Modal>\n );\n}\n\n// ---------- DescriptionList (KeyValue editable) ------------------------\nexport interface DescriptionListItemProps {\n label: React.ReactNode;\n value: React.ReactNode;\n /** Si se pasa, el valor se vuelve editable inline. */\n onEdit?: () => void;\n editable?: boolean;\n}\n\nexport function DescriptionList({ children, className, ...rest }: React.HTMLAttributes<HTMLDListElement>) {\n return <dl className={cx('desc-list', className)} {...rest}>{children}</dl>;\n}\n\nexport function DescriptionListItem({ label, value, onEdit, editable }: DescriptionListItemProps) {\n const t = useLocale();\n return (\n <>\n <dt className=\"desc-list__label\">{label}</dt>\n <dd className=\"desc-list__value\">\n <span>{value}</span>\n {editable && onEdit && (\n <button type=\"button\" className=\"desc-list__edit\" onClick={onEdit}>\n {t['descList.edit']}\n </button>\n )}\n </dd>\n </>\n );\n}\n\n// ---------- DiffViewer (before / after) --------------------------------\nexport interface DiffEntry {\n field: React.ReactNode;\n before: React.ReactNode;\n after: React.ReactNode;\n}\n\nexport interface DiffViewerProps extends React.HTMLAttributes<HTMLDivElement> {\n entries: DiffEntry[];\n}\n\nexport function DiffViewer({ entries, className, ...rest }: DiffViewerProps) {\n const t = useLocale();\n // data-label feeds the mobile stacked layout's ::before pseudo-elements\n // so the \"Antes\" / \"Después\" labels remain i18n-able.\n const beforeLabel = typeof t['diff.before'] === 'string' ? t['diff.before'] : undefined;\n const afterLabel = typeof t['diff.after'] === 'string' ? t['diff.after'] : undefined;\n return (\n <div className={cx('diff', className)} role=\"table\" aria-label={t['diff.label']} {...rest}>\n <div className=\"diff__head\" role=\"row\">\n <div role=\"columnheader\">{t['diff.field']}</div>\n <div role=\"columnheader\">{t['diff.before']}</div>\n <div role=\"columnheader\">{t['diff.after']}</div>\n </div>\n {entries.map((e, i) => (\n <div key={i} className=\"diff__row\" role=\"row\">\n <div className=\"diff__field\" role=\"cell\">{e.field}</div>\n <div className=\"diff__before\" role=\"cell\" data-label={beforeLabel}><del>{e.before}</del></div>\n <div className=\"diff__after\" role=\"cell\" data-label={afterLabel}><ins>{e.after}</ins></div>\n </div>\n ))}\n </div>\n );\n}\n\n// ---------- TransferList (dual list select) ----------------------------\nexport interface TransferItem {\n id: string;\n label: React.ReactNode;\n description?: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface TransferListProps {\n source: TransferItem[];\n selected: TransferItem[];\n onChange: (selected: TransferItem[]) => void;\n sourceTitle?: React.ReactNode;\n selectedTitle?: React.ReactNode;\n className?: string;\n}\n\nexport function TransferList({\n source, selected, onChange,\n sourceTitle, selectedTitle,\n className,\n}: TransferListProps) {\n const [leftChecked, setLeftChecked] = React.useState<Set<string>>(new Set());\n const [rightChecked, setRightChecked] = React.useState<Set<string>>(new Set());\n const t = useLocale();\n const srcTitle = sourceTitle ?? t['transfer.available'];\n const selTitle = selectedTitle ?? t['transfer.assigned'];\n\n // Without memo, every checkbox click rebuilt selectedIds and re-filtered\n // `source` to compute `left`. At ~500 source items that's a measurable\n // O(n) hit per click.\n const selectedIds = React.useMemo(\n () => new Set(selected.map((s) => s.id)),\n [selected]\n );\n const left = React.useMemo(\n () => source.filter((s) => !selectedIds.has(s.id)),\n [source, selectedIds]\n );\n const right = selected;\n\n const moveRight = () => {\n const toMove = left.filter((i) => leftChecked.has(i.id));\n onChange([...right, ...toMove]);\n setLeftChecked(new Set());\n };\n const moveLeft = () => {\n onChange(right.filter((i) => !rightChecked.has(i.id)));\n setRightChecked(new Set());\n };\n\n const toggleCheck = (set: Set<string>, setSet: (s: Set<string>) => void, id: string) => {\n const next = new Set(set);\n if (next.has(id)) next.delete(id); else next.add(id);\n setSet(next);\n };\n\n const renderColumn = (title: React.ReactNode, items: TransferItem[], checked: Set<string>, setChecked: (s: Set<string>) => void) => (\n <div className=\"transfer__col\">\n <div className=\"transfer__col-head\">\n <span className=\"transfer__col-title\">{title}</span>\n <span className=\"transfer__col-count\">{items.length}</span>\n </div>\n <ul className=\"transfer__list\" role=\"listbox\" aria-label={typeof title === 'string' ? title : undefined}>\n {items.length === 0 ? (\n <li className=\"transfer__empty\">{t['transfer.empty']}</li>\n ) : items.map((it) => (\n <li\n key={it.id}\n className={cx('transfer__item', checked.has(it.id) && 'is-checked', it.disabled && 'is-disabled')}\n role=\"option\"\n aria-selected={checked.has(it.id)}\n onClick={() => !it.disabled && toggleCheck(checked, setChecked, it.id)}\n >\n <span onClick={(e) => e.stopPropagation()}>\n <Checkbox\n checked={checked.has(it.id)}\n disabled={it.disabled}\n onChange={() => toggleCheck(checked, setChecked, it.id)}\n />\n </span>\n <div className=\"transfer__item-body\">\n <div>{it.label}</div>\n {it.description && <div className=\"transfer__item-desc\">{it.description}</div>}\n </div>\n </li>\n ))}\n </ul>\n </div>\n );\n\n return (\n <div className={cx('transfer', className)}>\n {renderColumn(srcTitle, left, leftChecked, setLeftChecked)}\n <div className=\"transfer__controls\">\n <button type=\"button\" className=\"btn btn--outline btn--sm\" disabled={leftChecked.size === 0} onClick={moveRight} aria-label={t['transfer.assignSelected']}>\n <ChevronRight size={16} />\n </button>\n <button type=\"button\" className=\"btn btn--outline btn--sm\" disabled={rightChecked.size === 0} onClick={moveLeft} aria-label={t['transfer.removeSelected']}>\n <ChevronLeft size={16} />\n </button>\n </div>\n {renderColumn(selTitle, right, rightChecked, setRightChecked)}\n </div>\n );\n}\n\n// ---------- EditableCell ---------------------------------------------------\nexport interface EditableCellProps {\n /** Committed value (controlled — the consumer owns it). */\n value: string;\n /**\n * Called on commit (Enter or blur) with the edited raw value. May return\n * a promise: while it's pending the input is disabled; on rejection the\n * cell STAYS in edit mode with the invalid style, so the user's typing\n * is never lost to a failed PATCH. Not called when the value is\n * unchanged.\n */\n onCommit: (next: string) => void | Promise<void>;\n /** Input mode. `'number'` renders a numeric input. */\n type?: 'text' | 'number';\n /**\n * Display-mode formatter (e.g. `formatCurrency`) — editing always works\n * on the RAW `value`; only the resting presentation is formatted.\n */\n formatDisplay?: (value: string) => React.ReactNode;\n /**\n * Sync validation before commit. Return an error message to block the\n * commit (cell stays editing, invalid style, message via title/aria);\n * return `null` to allow it.\n */\n validate?: (next: string) => string | null;\n disabled?: boolean;\n placeholder?: string;\n /** Accessible name of the edit affordance (e.g. \"Editar precio de Taladro\"). */\n ariaLabel?: string;\n className?: string;\n}\n\n/**\n * Click-to-edit primitive for inline editing (Airtable/Notion semantics):\n * click or Enter to edit, Enter/blur commits, Escape cancels. Composable\n * anywhere — typically inside a `DataTable` cell via `accessor`. The kit\n * deliberately ships the CELL, not an editable-table subsystem: commit\n * orchestration (optimistic update, refetch, toast) stays in the consumer,\n * where the data layer lives.\n */\nexport function EditableCell({\n value, onCommit, type = 'text', formatDisplay, validate,\n disabled, placeholder, ariaLabel, className,\n}: EditableCellProps) {\n const t = useLocale();\n const [editing, setEditing] = React.useState(false);\n const [draft, setDraft] = React.useState(value);\n const [pending, setPending] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n // Distinguishes Escape-initiated blur from a committing blur.\n const cancelledRef = React.useRef(false);\n\n const startEdit = () => {\n if (disabled) return;\n setDraft(value);\n setError(null);\n setEditing(true);\n };\n\n React.useEffect(() => {\n if (editing) {\n inputRef.current?.focus();\n inputRef.current?.select();\n }\n }, [editing]);\n\n const commit = async () => {\n if (pending) return;\n if (draft === value) { setEditing(false); setError(null); return; }\n const invalid = validate?.(draft) ?? null;\n if (invalid) {\n setError(invalid);\n inputRef.current?.focus();\n return;\n }\n try {\n setPending(true);\n await onCommit(draft);\n setEditing(false);\n setError(null);\n } catch {\n // Keep the draft and the edit mode — the user decides to retry or Esc.\n setError(t['editable.commitError']);\n inputRef.current?.focus();\n } finally {\n setPending(false);\n }\n };\n\n const cancel = () => {\n cancelledRef.current = true;\n setEditing(false);\n setError(null);\n };\n\n if (!editing) {\n return (\n <button\n type=\"button\"\n className={cx('editable-cell', disabled && 'is-disabled', className)}\n onClick={startEdit}\n disabled={disabled}\n aria-label={ariaLabel}\n >\n <span className=\"editable-cell__value\">\n {formatDisplay ? formatDisplay(value) : (value || placeholder)}\n </span>\n <EditIcon size={12} className=\"editable-cell__icon\" aria-hidden=\"true\" />\n </button>\n );\n }\n\n return (\n <input\n ref={inputRef}\n type={type}\n className={cx('input', 'editable-cell__input', error != null && 'is-invalid', className)}\n value={draft}\n disabled={pending}\n placeholder={placeholder}\n aria-label={ariaLabel}\n aria-invalid={error != null || undefined}\n title={error ?? undefined}\n onChange={(e) => { setDraft(e.target.value); setError(null); }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') { e.preventDefault(); void commit(); }\n else if (e.key === 'Escape') { e.preventDefault(); cancel(); }\n }}\n onBlur={() => {\n if (cancelledRef.current) { cancelledRef.current = false; return; }\n void commit();\n }}\n />\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/Editing.tsx"],"names":["React","useLocale","jsx","Modal","jsxs","Fragment","cx","Checkbox","ChevronRight","ChevronLeft","Edit"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EAAM,OAAA;AAAA,EAAS,SAAA;AAAA,EAAW,KAAA;AAAA,EAAO,WAAA;AAAA,EACjC,YAAA;AAAA,EAAc,WAAA;AAAA,EACd,IAAA,GAAO,SAAA;AAAA,EAAW;AACpB,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUA,0BAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,SAAS,OAAA,IAAW,IAAA;AAC1B,EAAA,MAAM,IAAIC,0BAAA,EAAU;AACpB,EAAA,MAAM,WAAA,GAAc,YAAA,IAAgB,CAAA,CAAE,gBAAgB,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,WAAA,IAAe,CAAA,CAAE,eAAe,CAAA;AAEnD,EAAA,MAAM,gBAAgB,YAAY;AAChC,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA,MAAM,SAAA,EAAU;AAChB,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA,SAAE;AACA,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf;AAAA,EACF,CAAA;AAEA,EAAA,uBACEC,cAAA;AAAA,IAACC,sBAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA,EAAK,IAAA;AAAA,MACL,KAAA;AAAA,MACA,wBACEC,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAAH,cAAA,CAAC,QAAA,EAAA,EAAO,MAAK,QAAA,EAAS,SAAA,EAAU,0BAAyB,OAAA,EAAS,OAAA,EAAS,QAAA,EAAU,MAAA,EAClF,QAAA,EAAA,UAAA,EACH,CAAA;AAAA,wBACAE,eAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,WAAWE,mBAAA,CAAG,KAAA,EAAO,SAAS,QAAA,GAAW,aAAA,GAAgB,gBAAgB,SAAS,CAAA;AAAA,YAClF,OAAA,EAAS,aAAA;AAAA,YACT,QAAA,EAAU,MAAA;AAAA,YACV,aAAW,MAAA,IAAU,MAAA;AAAA,YAEpB,QAAA,EAAA;AAAA,cAAA,MAAA,kCAAU,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA2B,aAAA,EAAY,QAAO,CAAA,GAAK,IAAA;AAAA,cAC5E;AAAA;AAAA;AAAA;AACH,OAAA,EACF,CAAA;AAAA,MAGD,QAAA,EAAA,WAAA,oBAAeJ,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iBAAiB,QAAA,EAAA,WAAA,EAAY;AAAA;AAAA,GAC5D;AAEJ;AAWO,SAAS,gBAAgB,EAAE,QAAA,EAAU,SAAA,EAAW,GAAG,MAAK,EAA2C;AACxG,EAAA,uBAAOA,cAAA,CAAC,QAAG,SAAA,EAAWI,mBAAA,CAAG,aAAa,SAAS,CAAA,EAAI,GAAG,IAAA,EAAO,QAAA,EAAS,CAAA;AACxE;AAEO,SAAS,oBAAoB,EAAE,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,UAAS,EAA6B;AAChG,EAAA,MAAM,IAAIL,0BAAA,EAAU;AACpB,EAAA,uBACEG,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAH,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,kBAAA,EAAoB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,oBACxCE,eAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,kBAAA,EACZ,QAAA,EAAA;AAAA,sBAAAF,cAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MACZ,QAAA,IAAY,MAAA,oBACXA,cAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,SAAA,EAAU,iBAAA,EAAkB,OAAA,EAAS,MAAA,EACxD,QAAA,EAAA,CAAA,CAAE,eAAe,CAAA,EACpB;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;AAaO,SAAS,WAAW,EAAE,OAAA,EAAS,SAAA,EAAW,GAAG,MAAK,EAAoB;AAC3E,EAAA,MAAM,IAAID,0BAAA,EAAU;AAGpB,EAAA,MAAM,WAAA,GAAc,OAAO,CAAA,CAAE,aAAa,MAAM,QAAA,GAAW,CAAA,CAAE,aAAa,CAAA,GAAI,MAAA;AAC9E,EAAA,MAAM,UAAA,GAAa,OAAO,CAAA,CAAE,YAAY,MAAM,QAAA,GAAW,CAAA,CAAE,YAAY,CAAA,GAAI,MAAA;AAC3E,EAAA,uBACEG,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAWE,mBAAA,CAAG,QAAQ,SAAS,CAAA,EAAG,IAAA,EAAK,OAAA,EAAQ,YAAA,EAAY,CAAA,CAAE,YAAY,CAAA,EAAI,GAAG,IAAA,EACnF,QAAA,EAAA;AAAA,oBAAAF,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,YAAA,EAAa,IAAA,EAAK,KAAA,EAC/B,QAAA,EAAA;AAAA,sBAAAF,cAAA,CAAC,KAAA,EAAA,EAAI,IAAA,EAAK,cAAA,EAAgB,QAAA,EAAA,CAAA,CAAE,YAAY,CAAA,EAAE,CAAA;AAAA,qCACzC,KAAA,EAAA,EAAI,IAAA,EAAK,cAAA,EAAgB,QAAA,EAAA,CAAA,CAAE,aAAa,CAAA,EAAE,CAAA;AAAA,qCAC1C,KAAA,EAAA,EAAI,IAAA,EAAK,cAAA,EAAgB,QAAA,EAAA,CAAA,CAAE,YAAY,CAAA,EAAE;AAAA,KAAA,EAC5C,CAAA;AAAA,IACC,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qCACd,KAAA,EAAA,EAAY,SAAA,EAAU,WAAA,EAAY,IAAA,EAAK,KAAA,EACtC,QAAA,EAAA;AAAA,sBAAAA,cAAA,CAAC,SAAI,SAAA,EAAU,aAAA,EAAc,IAAA,EAAK,MAAA,EAAQ,YAAE,KAAA,EAAM,CAAA;AAAA,sBAClDA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,cAAA,EAAe,IAAA,EAAK,MAAA,EAAO,YAAA,EAAY,WAAA,EAAa,QAAA,kBAAAA,cAAA,CAAC,KAAA,EAAA,EAAK,QAAA,EAAA,CAAA,CAAE,MAAA,EAAO,CAAA,EAAM,CAAA;AAAA,sBACxFA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EAAc,IAAA,EAAK,MAAA,EAAO,YAAA,EAAY,UAAA,EAAY,QAAA,kBAAAA,cAAA,CAAC,KAAA,EAAA,EAAK,QAAA,EAAA,CAAA,CAAE,KAAA,EAAM,CAAA,EAAM;AAAA,KAAA,EAAA,EAH7E,CAIV,CACD;AAAA,GAAA,EACH,CAAA;AAEJ;AAmBO,SAAS,YAAA,CAAa;AAAA,EAC3B,MAAA;AAAA,EAAQ,QAAA;AAAA,EAAU,QAAA;AAAA,EAClB,WAAA;AAAA,EAAa,aAAA;AAAA,EACb;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,IAAUF,gBAAA,CAAA,QAAA,iBAAsB,IAAI,KAAK,CAAA;AAC3E,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,IAAUA,gBAAA,CAAA,QAAA,iBAAsB,IAAI,KAAK,CAAA;AAC7E,EAAA,MAAM,IAAIC,0BAAA,EAAU;AACpB,EAAA,MAAM,QAAA,GAAW,WAAA,IAAe,CAAA,CAAE,oBAAoB,CAAA;AACtD,EAAA,MAAM,QAAA,GAAW,aAAA,IAAiB,CAAA,CAAE,mBAAmB,CAAA;AAKvD,EAAA,MAAM,WAAA,GAAoBD,gBAAA,CAAA,OAAA;AAAA,IACxB,MAAM,IAAI,GAAA,CAAI,QAAA,CAAS,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,IACvC,CAAC,QAAQ;AAAA,GACX;AACA,EAAA,MAAM,IAAA,GAAaA,gBAAA,CAAA,OAAA;AAAA,IACjB,MAAM,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,IACjD,CAAC,QAAQ,WAAW;AAAA,GACtB;AACA,EAAA,MAAM,KAAA,GAAQ,QAAA;AAEd,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,MAAM,MAAA,GAAS,KAAK,MAAA,CAAO,CAAC,MAAM,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AACvD,IAAA,QAAA,CAAS,CAAC,GAAG,KAAA,EAAO,GAAG,MAAM,CAAC,CAAA;AAC9B,IAAA,cAAA,iBAAe,IAAI,KAAK,CAAA;AAAA,EAC1B,CAAA;AACA,EAAA,MAAM,WAAW,MAAM;AACrB,IAAA,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,aAAa,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAC,CAAA;AACrD,IAAA,eAAA,iBAAgB,IAAI,KAAK,CAAA;AAAA,EAC3B,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,GAAA,EAAkB,MAAA,EAAkC,EAAA,KAAe;AACtF,IAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,GAAG,CAAA;AACxB,IAAA,IAAI,KAAK,GAAA,CAAI,EAAE,CAAA,EAAG,IAAA,CAAK,OAAO,EAAE,CAAA;AAAA,SAAQ,IAAA,CAAK,IAAI,EAAE,CAAA;AACnD,IAAA,MAAA,CAAO,IAAI,CAAA;AAAA,EACb,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,KAAA,EAAwB,KAAA,EAAuB,SAAsB,UAAA,qBACzFI,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,oBAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,sBAC7CA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qBAAA,EAAuB,gBAAM,MAAA,EAAO;AAAA,KAAA,EACtD,CAAA;AAAA,oBACAA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,gBAAA,EAAiB,IAAA,EAAK,SAAA,EAAU,YAAA,EAAY,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA,EAC3F,QAAA,EAAA,KAAA,CAAM,WAAW,CAAA,mBAChBA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,iBAAA,EAAmB,QAAA,EAAA,CAAA,CAAE,gBAAgB,CAAA,EAAE,CAAA,GACnD,KAAA,CAAM,GAAA,CAAI,CAAC,EAAA,qBACbE,eAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QAEC,SAAA,EAAWE,mBAAA,CAAG,gBAAA,EAAkB,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA,IAAK,YAAA,EAAc,EAAA,CAAG,QAAA,IAAY,aAAa,CAAA;AAAA,QAChG,IAAA,EAAK,QAAA;AAAA,QACL,eAAA,EAAe,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA;AAAA,QAChC,OAAA,EAAS,MAAM,CAAC,EAAA,CAAG,YAAY,WAAA,CAAY,OAAA,EAAS,UAAA,EAAY,EAAA,CAAG,EAAE,CAAA;AAAA,QAErE,QAAA,EAAA;AAAA,0BAAAJ,cAAA,CAAC,UAAK,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,iBAAgB,EACtC,QAAA,kBAAAA,cAAA;AAAA,YAACK,yBAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA;AAAA,cAC1B,UAAU,EAAA,CAAG,QAAA;AAAA,cACb,UAAU,MAAM,WAAA,CAAY,OAAA,EAAS,UAAA,EAAY,GAAG,EAAE;AAAA;AAAA,WACxD,EACF,CAAA;AAAA,0BACAH,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,4BAAAF,cAAA,CAAC,KAAA,EAAA,EAAK,aAAG,KAAA,EAAM,CAAA;AAAA,YACd,GAAG,WAAA,oBAAeA,cAAA,CAAC,SAAI,SAAA,EAAU,qBAAA,EAAuB,aAAG,WAAA,EAAY;AAAA,WAAA,EAC1E;AAAA;AAAA,OAAA;AAAA,MAhBK,EAAA,CAAG;AAAA,KAkBX,CAAA,EACH;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,uCACG,KAAA,EAAA,EAAI,SAAA,EAAWI,mBAAA,CAAG,UAAA,EAAY,SAAS,CAAA,EACrC,QAAA,EAAA;AAAA,IAAA,YAAA,CAAa,QAAA,EAAU,IAAA,EAAM,WAAA,EAAa,cAAc,CAAA;AAAA,oBACzDF,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,cAAA,CAAC,YAAO,IAAA,EAAK,QAAA,EAAS,WAAU,0BAAA,EAA2B,QAAA,EAAU,YAAY,IAAA,KAAS,CAAA,EAAG,SAAS,SAAA,EAAW,YAAA,EAAY,EAAE,yBAAyB,CAAA,EACtJ,yCAACM,6BAAA,EAAA,EAAa,IAAA,EAAM,IAAI,CAAA,EAC1B,CAAA;AAAA,sBACAN,cAAA,CAAC,YAAO,IAAA,EAAK,QAAA,EAAS,WAAU,0BAAA,EAA2B,QAAA,EAAU,aAAa,IAAA,KAAS,CAAA,EAAG,SAAS,QAAA,EAAU,YAAA,EAAY,EAAE,yBAAyB,CAAA,EACtJ,yCAACO,4BAAA,EAAA,EAAY,IAAA,EAAM,IAAI,CAAA,EACzB;AAAA,KAAA,EACF,CAAA;AAAA,IACC,YAAA,CAAa,QAAA,EAAU,KAAA,EAAO,YAAA,EAAc,eAAe;AAAA,GAAA,EAC9D,CAAA;AAEJ;AA0CO,SAAS,YAAA,CAAa;AAAA,EAC3B,KAAA;AAAA,EAAO,QAAA;AAAA,EAAU,IAAA,GAAO,MAAA;AAAA,EAAQ,aAAA;AAAA,EAAe,QAAA;AAAA,EAC/C,QAAA;AAAA,EAAU,WAAA;AAAA,EAAa,SAAA;AAAA,EAAW;AACpC,CAAA,EAAsB;AACpB,EAAA,MAAM,IAAIR,0BAAA,EAAU;AACpB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAUD,0BAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,0BAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAUA,0BAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,0BAAwB,IAAI,CAAA;AAC5D,EAAA,MAAM,QAAA,GAAiBA,wBAAyB,IAAI,CAAA;AAEpD,EAAA,MAAM,YAAA,GAAqBA,wBAAO,KAAK,CAAA;AAEvC,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,IAAI,QAAA,EAAU;AACd,IAAA,QAAA,CAAS,KAAK,CAAA;AACd,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,EACjB,CAAA;AAEA,EAAMA,2BAAU,MAAM;AACpB,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AACxB,MAAA,QAAA,CAAS,SAAS,MAAA,EAAO;AAAA,IAC3B;AAAA,EACF,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,SAAS,YAAY;AACzB,IAAA,IAAI,OAAA,EAAS;AACb,IAAA,IAAI,UAAU,KAAA,EAAO;AAAE,MAAA,UAAA,CAAW,KAAK,CAAA;AAAG,MAAA,QAAA,CAAS,IAAI,CAAA;AAAG,MAAA;AAAA,IAAQ;AAClE,IAAA,MAAM,OAAA,GAAU,QAAA,GAAW,KAAK,CAAA,IAAK,IAAA;AACrC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,QAAA,CAAS,OAAO,CAAA;AAChB,MAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AACxB,MAAA;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,MAAM,SAAS,KAAK,CAAA;AACpB,MAAA,UAAA,CAAW,KAAK,CAAA;AAChB,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,IACf,CAAA,CAAA,MAAQ;AAEN,MAAA,QAAA,CAAS,CAAA,CAAE,sBAAsB,CAAC,CAAA;AAClC,MAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,IAC1B,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,SAAS,MAAM;AACnB,IAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AACvB,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,uBACEI,eAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAWE,mBAAA,CAAG,eAAA,EAAiB,QAAA,IAAY,eAAe,SAAS,CAAA;AAAA,QACnE,OAAA,EAAS,SAAA;AAAA,QACT,QAAA;AAAA,QACA,YAAA,EAAY,SAAA;AAAA,QAEZ,QAAA,EAAA;AAAA,0BAAAJ,cAAA,CAAC,MAAA,EAAA,EAAK,WAAU,sBAAA,EACb,QAAA,EAAA,aAAA,GAAgB,cAAc,KAAK,CAAA,GAAK,SAAS,WAAA,EACpD,CAAA;AAAA,yCACCQ,qBAAA,EAAA,EAAS,IAAA,EAAM,IAAI,SAAA,EAAU,qBAAA,EAAsB,eAAY,MAAA,EAAO;AAAA;AAAA;AAAA,KACzE;AAAA,EAEJ;AAEA,EAAA,uBACER,cAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,QAAA;AAAA,MACL,IAAA;AAAA,MACA,WAAWI,mBAAA,CAAG,OAAA,EAAS,wBAAwB,KAAA,IAAS,IAAA,IAAQ,cAAc,SAAS,CAAA;AAAA,MACvF,KAAA,EAAO,KAAA;AAAA,MACP,QAAA,EAAU,OAAA;AAAA,MACV,WAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MACZ,cAAA,EAAc,SAAS,IAAA,IAAQ,MAAA;AAAA,MAC/B,OAAO,KAAA,IAAS,MAAA;AAAA,MAChB,QAAA,EAAU,CAAC,CAAA,KAAM;AAAE,QAAA,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAG,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MAAG,CAAA;AAAA,MAC7D,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,QAAA,IAAI,CAAA,CAAE,QAAQ,OAAA,EAAS;AAAE,UAAA,CAAA,CAAE,cAAA,EAAe;AAAG,UAAA,KAAK,MAAA,EAAO;AAAA,QAAG,CAAA,MAAA,IACnD,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU;AAAE,UAAA,CAAA,CAAE,cAAA,EAAe;AAAG,UAAA,MAAA,EAAO;AAAA,QAAG;AAAA,MAC/D,CAAA;AAAA,MACA,QAAQ,MAAM;AACZ,QAAA,IAAI,aAAa,OAAA,EAAS;AAAE,UAAA,YAAA,CAAa,OAAA,GAAU,KAAA;AAAO,UAAA;AAAA,QAAQ;AAClE,QAAA,KAAK,MAAA,EAAO;AAAA,MACd;AAAA;AAAA,GACF;AAEJ","file":"chunk-4HHP3WT7.js","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { Modal } from './Overlay';\nimport { ChevronLeft, ChevronRight, Edit as EditIcon } from './Icons';\nimport { Checkbox } from './Form';\nimport { useLocale } from '../locale/LocaleProvider';\n\n// ---------- ConfirmDialog -----------------------------------------------\nexport interface ConfirmDialogProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void | Promise<void>;\n title: React.ReactNode;\n description?: React.ReactNode;\n confirmLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n /** 'danger' usa botón rojo. */\n tone?: 'default' | 'danger';\n /** Si true, deshabilita el confirm mientras se ejecuta. */\n loading?: boolean;\n}\n\nexport function ConfirmDialog({\n open, onClose, onConfirm, title, description,\n confirmLabel, cancelLabel,\n tone = 'default', loading,\n}: ConfirmDialogProps) {\n const [busy, setBusy] = React.useState(false);\n const isBusy = loading ?? busy;\n const t = useLocale();\n const confirmText = confirmLabel ?? t['common.confirm'];\n const cancelText = cancelLabel ?? t['common.cancel'];\n\n const handleConfirm = async () => {\n try {\n setBusy(true);\n await onConfirm();\n onClose();\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n size=\"sm\"\n title={title}\n footer={\n <>\n <button type=\"button\" className=\"btn btn--ghost btn--md\" onClick={onClose} disabled={isBusy}>\n {cancelText}\n </button>\n <button\n type=\"button\"\n className={cx('btn', tone === 'danger' ? 'btn--danger' : 'btn--primary', 'btn--md')}\n onClick={handleConfirm}\n disabled={isBusy}\n aria-busy={isBusy || undefined}\n >\n {isBusy ? <span className=\"spinner spinner--inverse\" aria-hidden=\"true\" /> : null}\n {confirmText}\n </button>\n </>\n }\n >\n {description && <p className=\"confirm__desc\">{description}</p>}\n </Modal>\n );\n}\n\n// ---------- DescriptionList (KeyValue editable) ------------------------\nexport interface DescriptionListItemProps {\n label: React.ReactNode;\n value: React.ReactNode;\n /** Si se pasa, el valor se vuelve editable inline. */\n onEdit?: () => void;\n editable?: boolean;\n}\n\nexport function DescriptionList({ children, className, ...rest }: React.HTMLAttributes<HTMLDListElement>) {\n return <dl className={cx('desc-list', className)} {...rest}>{children}</dl>;\n}\n\nexport function DescriptionListItem({ label, value, onEdit, editable }: DescriptionListItemProps) {\n const t = useLocale();\n return (\n <>\n <dt className=\"desc-list__label\">{label}</dt>\n <dd className=\"desc-list__value\">\n <span>{value}</span>\n {editable && onEdit && (\n <button type=\"button\" className=\"desc-list__edit\" onClick={onEdit}>\n {t['descList.edit']}\n </button>\n )}\n </dd>\n </>\n );\n}\n\n// ---------- DiffViewer (before / after) --------------------------------\nexport interface DiffEntry {\n field: React.ReactNode;\n before: React.ReactNode;\n after: React.ReactNode;\n}\n\nexport interface DiffViewerProps extends React.HTMLAttributes<HTMLDivElement> {\n entries: DiffEntry[];\n}\n\nexport function DiffViewer({ entries, className, ...rest }: DiffViewerProps) {\n const t = useLocale();\n // data-label feeds the mobile stacked layout's ::before pseudo-elements\n // so the \"Antes\" / \"Después\" labels remain i18n-able.\n const beforeLabel = typeof t['diff.before'] === 'string' ? t['diff.before'] : undefined;\n const afterLabel = typeof t['diff.after'] === 'string' ? t['diff.after'] : undefined;\n return (\n <div className={cx('diff', className)} role=\"table\" aria-label={t['diff.label']} {...rest}>\n <div className=\"diff__head\" role=\"row\">\n <div role=\"columnheader\">{t['diff.field']}</div>\n <div role=\"columnheader\">{t['diff.before']}</div>\n <div role=\"columnheader\">{t['diff.after']}</div>\n </div>\n {entries.map((e, i) => (\n <div key={i} className=\"diff__row\" role=\"row\">\n <div className=\"diff__field\" role=\"cell\">{e.field}</div>\n <div className=\"diff__before\" role=\"cell\" data-label={beforeLabel}><del>{e.before}</del></div>\n <div className=\"diff__after\" role=\"cell\" data-label={afterLabel}><ins>{e.after}</ins></div>\n </div>\n ))}\n </div>\n );\n}\n\n// ---------- TransferList (dual list select) ----------------------------\nexport interface TransferItem {\n id: string;\n label: React.ReactNode;\n description?: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface TransferListProps {\n source: TransferItem[];\n selected: TransferItem[];\n onChange: (selected: TransferItem[]) => void;\n sourceTitle?: React.ReactNode;\n selectedTitle?: React.ReactNode;\n className?: string;\n}\n\nexport function TransferList({\n source, selected, onChange,\n sourceTitle, selectedTitle,\n className,\n}: TransferListProps) {\n const [leftChecked, setLeftChecked] = React.useState<Set<string>>(new Set());\n const [rightChecked, setRightChecked] = React.useState<Set<string>>(new Set());\n const t = useLocale();\n const srcTitle = sourceTitle ?? t['transfer.available'];\n const selTitle = selectedTitle ?? t['transfer.assigned'];\n\n // Without memo, every checkbox click rebuilt selectedIds and re-filtered\n // `source` to compute `left`. At ~500 source items that's a measurable\n // O(n) hit per click.\n const selectedIds = React.useMemo(\n () => new Set(selected.map((s) => s.id)),\n [selected]\n );\n const left = React.useMemo(\n () => source.filter((s) => !selectedIds.has(s.id)),\n [source, selectedIds]\n );\n const right = selected;\n\n const moveRight = () => {\n const toMove = left.filter((i) => leftChecked.has(i.id));\n onChange([...right, ...toMove]);\n setLeftChecked(new Set());\n };\n const moveLeft = () => {\n onChange(right.filter((i) => !rightChecked.has(i.id)));\n setRightChecked(new Set());\n };\n\n const toggleCheck = (set: Set<string>, setSet: (s: Set<string>) => void, id: string) => {\n const next = new Set(set);\n if (next.has(id)) next.delete(id); else next.add(id);\n setSet(next);\n };\n\n const renderColumn = (title: React.ReactNode, items: TransferItem[], checked: Set<string>, setChecked: (s: Set<string>) => void) => (\n <div className=\"transfer__col\">\n <div className=\"transfer__col-head\">\n <span className=\"transfer__col-title\">{title}</span>\n <span className=\"transfer__col-count\">{items.length}</span>\n </div>\n <ul className=\"transfer__list\" role=\"listbox\" aria-label={typeof title === 'string' ? title : undefined}>\n {items.length === 0 ? (\n <li className=\"transfer__empty\">{t['transfer.empty']}</li>\n ) : items.map((it) => (\n <li\n key={it.id}\n className={cx('transfer__item', checked.has(it.id) && 'is-checked', it.disabled && 'is-disabled')}\n role=\"option\"\n aria-selected={checked.has(it.id)}\n onClick={() => !it.disabled && toggleCheck(checked, setChecked, it.id)}\n >\n <span onClick={(e) => e.stopPropagation()}>\n <Checkbox\n checked={checked.has(it.id)}\n disabled={it.disabled}\n onChange={() => toggleCheck(checked, setChecked, it.id)}\n />\n </span>\n <div className=\"transfer__item-body\">\n <div>{it.label}</div>\n {it.description && <div className=\"transfer__item-desc\">{it.description}</div>}\n </div>\n </li>\n ))}\n </ul>\n </div>\n );\n\n return (\n <div className={cx('transfer', className)}>\n {renderColumn(srcTitle, left, leftChecked, setLeftChecked)}\n <div className=\"transfer__controls\">\n <button type=\"button\" className=\"btn btn--outline btn--sm\" disabled={leftChecked.size === 0} onClick={moveRight} aria-label={t['transfer.assignSelected']}>\n <ChevronRight size={16} />\n </button>\n <button type=\"button\" className=\"btn btn--outline btn--sm\" disabled={rightChecked.size === 0} onClick={moveLeft} aria-label={t['transfer.removeSelected']}>\n <ChevronLeft size={16} />\n </button>\n </div>\n {renderColumn(selTitle, right, rightChecked, setRightChecked)}\n </div>\n );\n}\n\n// ---------- EditableCell ---------------------------------------------------\nexport interface EditableCellProps {\n /** Committed value (controlled — the consumer owns it). */\n value: string;\n /**\n * Called on commit (Enter or blur) with the edited raw value. May return\n * a promise: while it's pending the input is disabled; on rejection the\n * cell STAYS in edit mode with the invalid style, so the user's typing\n * is never lost to a failed PATCH. Not called when the value is\n * unchanged.\n */\n onCommit: (next: string) => void | Promise<void>;\n /** Input mode. `'number'` renders a numeric input. */\n type?: 'text' | 'number';\n /**\n * Display-mode formatter (e.g. `formatCurrency`) — editing always works\n * on the RAW `value`; only the resting presentation is formatted.\n */\n formatDisplay?: (value: string) => React.ReactNode;\n /**\n * Sync validation before commit. Return an error message to block the\n * commit (cell stays editing, invalid style, message via title/aria);\n * return `null` to allow it.\n */\n validate?: (next: string) => string | null;\n disabled?: boolean;\n placeholder?: string;\n /** Accessible name of the edit affordance (e.g. \"Editar precio de Taladro\"). */\n ariaLabel?: string;\n className?: string;\n}\n\n/**\n * Click-to-edit primitive for inline editing (Airtable/Notion semantics):\n * click or Enter to edit, Enter/blur commits, Escape cancels. Composable\n * anywhere — typically inside a `DataTable` cell via `accessor`. The kit\n * deliberately ships the CELL, not an editable-table subsystem: commit\n * orchestration (optimistic update, refetch, toast) stays in the consumer,\n * where the data layer lives.\n */\nexport function EditableCell({\n value, onCommit, type = 'text', formatDisplay, validate,\n disabled, placeholder, ariaLabel, className,\n}: EditableCellProps) {\n const t = useLocale();\n const [editing, setEditing] = React.useState(false);\n const [draft, setDraft] = React.useState(value);\n const [pending, setPending] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n // Distinguishes Escape-initiated blur from a committing blur.\n const cancelledRef = React.useRef(false);\n\n const startEdit = () => {\n if (disabled) return;\n setDraft(value);\n setError(null);\n setEditing(true);\n };\n\n React.useEffect(() => {\n if (editing) {\n inputRef.current?.focus();\n inputRef.current?.select();\n }\n }, [editing]);\n\n const commit = async () => {\n if (pending) return;\n if (draft === value) { setEditing(false); setError(null); return; }\n const invalid = validate?.(draft) ?? null;\n if (invalid) {\n setError(invalid);\n inputRef.current?.focus();\n return;\n }\n try {\n setPending(true);\n await onCommit(draft);\n setEditing(false);\n setError(null);\n } catch {\n // Keep the draft and the edit mode — the user decides to retry or Esc.\n setError(t['editable.commitError']);\n inputRef.current?.focus();\n } finally {\n setPending(false);\n }\n };\n\n const cancel = () => {\n cancelledRef.current = true;\n setEditing(false);\n setError(null);\n };\n\n if (!editing) {\n return (\n <button\n type=\"button\"\n className={cx('editable-cell', disabled && 'is-disabled', className)}\n onClick={startEdit}\n disabled={disabled}\n aria-label={ariaLabel}\n >\n <span className=\"editable-cell__value\">\n {formatDisplay ? formatDisplay(value) : (value || placeholder)}\n </span>\n <EditIcon size={12} className=\"editable-cell__icon\" aria-hidden=\"true\" />\n </button>\n );\n }\n\n return (\n <input\n ref={inputRef}\n type={type}\n className={cx('input', 'editable-cell__input', error != null && 'is-invalid', className)}\n value={draft}\n disabled={pending}\n placeholder={placeholder}\n aria-label={ariaLabel}\n aria-invalid={error != null || undefined}\n title={error ?? undefined}\n onChange={(e) => { setDraft(e.target.value); setError(null); }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') { e.preventDefault(); void commit(); }\n else if (e.key === 'Escape') { e.preventDefault(); cancel(); }\n }}\n onBlur={() => {\n if (cancelledRef.current) { cancelledRef.current = false; return; }\n void commit();\n }}\n />\n );\n}\n"]}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkCTOPKHEE_js = require('./chunk-CTOPKHEE.js');
|
|
5
|
+
var chunkC4AKMVDZ_js = require('./chunk-C4AKMVDZ.js');
|
|
6
|
+
var chunkPASF6T4H_js = require('./chunk-PASF6T4H.js');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
|
|
9
|
+
var SIGNED_PERCENT = (v) => {
|
|
10
|
+
const sign = v > 0 ? "+" : v < 0 ? "\u2212" : "";
|
|
11
|
+
return `${sign}${chunkCTOPKHEE_js.formatNumber(Math.abs(v), { maximumFractionDigits: 1 })}%`;
|
|
12
|
+
};
|
|
13
|
+
function DeltaBadge({
|
|
14
|
+
value,
|
|
15
|
+
format = SIGNED_PERCENT,
|
|
16
|
+
invert = false,
|
|
17
|
+
neutralThreshold = 0,
|
|
18
|
+
showIcon = true,
|
|
19
|
+
size = "md",
|
|
20
|
+
className,
|
|
21
|
+
...rest
|
|
22
|
+
}) {
|
|
23
|
+
const dir = value > neutralThreshold ? "up" : value < -neutralThreshold ? "down" : "flat";
|
|
24
|
+
const tone = dir === "flat" ? "flat" : dir === "up" ? invert ? "neg" : "pos" : invert ? "pos" : "neg";
|
|
25
|
+
const Icon = dir === "up" ? chunkC4AKMVDZ_js.ArrowUp : dir === "down" ? chunkC4AKMVDZ_js.ArrowDown : chunkC4AKMVDZ_js.Minus;
|
|
26
|
+
const verb = dir === "up" ? "subi\xF3" : dir === "down" ? "baj\xF3" : "sin cambio";
|
|
27
|
+
const text = format(value);
|
|
28
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29
|
+
"span",
|
|
30
|
+
{
|
|
31
|
+
className: chunkPASF6T4H_js.cx("delta-badge", `delta-badge--${tone}`, size === "sm" && "delta-badge--sm", className),
|
|
32
|
+
"aria-label": `${verb} ${text}`,
|
|
33
|
+
...rest,
|
|
34
|
+
children: [
|
|
35
|
+
showIcon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: size === "sm" ? 11 : 13, "aria-hidden": true }),
|
|
36
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "delta-badge__text", children: text })
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
function StatCard({
|
|
42
|
+
label,
|
|
43
|
+
value,
|
|
44
|
+
delta,
|
|
45
|
+
deltaFormat,
|
|
46
|
+
deltaInvert,
|
|
47
|
+
deltaNode,
|
|
48
|
+
caption,
|
|
49
|
+
icon,
|
|
50
|
+
accent,
|
|
51
|
+
chart,
|
|
52
|
+
className,
|
|
53
|
+
...rest
|
|
54
|
+
}) {
|
|
55
|
+
const deltaEl = deltaNode ?? (delta !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(DeltaBadge, { value: delta, format: deltaFormat, invert: deltaInvert, size: "sm" }) : null);
|
|
56
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
57
|
+
"div",
|
|
58
|
+
{
|
|
59
|
+
className: chunkPASF6T4H_js.cx("metric-card", accent && `metric-card--${accent}`, className),
|
|
60
|
+
"data-accent": accent,
|
|
61
|
+
...rest,
|
|
62
|
+
children: [
|
|
63
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "metric-card__head", children: [
|
|
64
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "metric-card__icon", "aria-hidden": true, children: icon }),
|
|
65
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "metric-card__label", children: label })
|
|
66
|
+
] }),
|
|
67
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "metric-card__value", children: value }),
|
|
68
|
+
(deltaEl || caption) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "metric-card__foot", children: [
|
|
69
|
+
deltaEl,
|
|
70
|
+
caption && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "metric-card__caption", children: caption })
|
|
71
|
+
] }),
|
|
72
|
+
chart && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "metric-card__chart", children: chart })
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
function meterTone(value, low, high, optimum) {
|
|
78
|
+
if (low === void 0 && high === void 0) return "pos";
|
|
79
|
+
const lo = low ?? -Infinity;
|
|
80
|
+
const hi = high ?? Infinity;
|
|
81
|
+
if (optimum === "high") return value >= hi ? "pos" : value >= lo ? "warn" : "neg";
|
|
82
|
+
if (optimum === "low") return value <= lo ? "pos" : value <= hi ? "warn" : "neg";
|
|
83
|
+
return value >= lo && value <= hi ? "pos" : "warn";
|
|
84
|
+
}
|
|
85
|
+
function Meter({
|
|
86
|
+
value,
|
|
87
|
+
min = 0,
|
|
88
|
+
max = 100,
|
|
89
|
+
low,
|
|
90
|
+
high,
|
|
91
|
+
optimum = "high",
|
|
92
|
+
label,
|
|
93
|
+
valueLabel,
|
|
94
|
+
showValue = true,
|
|
95
|
+
size = "md",
|
|
96
|
+
className,
|
|
97
|
+
...rest
|
|
98
|
+
}) {
|
|
99
|
+
const clamped = Math.min(Math.max(value, min), max);
|
|
100
|
+
const pct = max > min ? (clamped - min) / (max - min) * 100 : 0;
|
|
101
|
+
const tone = meterTone(value, low, high, optimum);
|
|
102
|
+
const hasThresholds = low !== void 0 || high !== void 0;
|
|
103
|
+
const caption = typeof valueLabel === "function" ? valueLabel(value, max) : valueLabel !== void 0 ? valueLabel : `${chunkCTOPKHEE_js.formatNumber(value)} / ${chunkCTOPKHEE_js.formatNumber(max)}`;
|
|
104
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkPASF6T4H_js.cx("meter", size === "sm" && "meter--sm", className), ...rest, children: [
|
|
105
|
+
(label || showValue) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "meter__head", children: [
|
|
106
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "meter__label", children: label }),
|
|
107
|
+
showValue && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "meter__value", children: caption })
|
|
108
|
+
] }),
|
|
109
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
110
|
+
"div",
|
|
111
|
+
{
|
|
112
|
+
className: "meter__track",
|
|
113
|
+
role: "meter",
|
|
114
|
+
"aria-valuenow": value,
|
|
115
|
+
"aria-valuemin": min,
|
|
116
|
+
"aria-valuemax": max,
|
|
117
|
+
"aria-label": typeof label === "string" ? label : void 0,
|
|
118
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
119
|
+
"div",
|
|
120
|
+
{
|
|
121
|
+
className: chunkPASF6T4H_js.cx("meter__fill", hasThresholds ? `meter__fill--${tone}` : "meter__fill--primary"),
|
|
122
|
+
style: { width: `${pct}%` }
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
] });
|
|
128
|
+
}
|
|
129
|
+
function Sparkbar({
|
|
130
|
+
data,
|
|
131
|
+
height = 32,
|
|
132
|
+
max,
|
|
133
|
+
color = "var(--color-primary)",
|
|
134
|
+
highlightLast = false,
|
|
135
|
+
gap = 2,
|
|
136
|
+
ariaLabel,
|
|
137
|
+
className,
|
|
138
|
+
style,
|
|
139
|
+
...rest
|
|
140
|
+
}) {
|
|
141
|
+
const ceiling = max ?? Math.max(1, ...data.map((d) => Number.isFinite(d) ? d : 0));
|
|
142
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
143
|
+
"div",
|
|
144
|
+
{
|
|
145
|
+
className: chunkPASF6T4H_js.cx("sparkbar", className),
|
|
146
|
+
role: "img",
|
|
147
|
+
"aria-label": ariaLabel,
|
|
148
|
+
style: { height, gap, ...style },
|
|
149
|
+
...rest,
|
|
150
|
+
children: data.map((d, i) => {
|
|
151
|
+
const isLast = highlightLast && i === data.length - 1;
|
|
152
|
+
const h = ceiling > 0 ? Math.max(2, Math.max(0, d) / ceiling * 100) : 2;
|
|
153
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
154
|
+
"span",
|
|
155
|
+
{
|
|
156
|
+
className: chunkPASF6T4H_js.cx("sparkbar__bar", isLast && "sparkbar__bar--last"),
|
|
157
|
+
style: { height: `${h}%`, background: isLast ? "var(--color-secondary)" : color }
|
|
158
|
+
},
|
|
159
|
+
i
|
|
160
|
+
);
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
var CAT_HUES = ["var(--cat-1)", "var(--cat-2)", "var(--cat-4)", "var(--cat-5)", "var(--cat-3)", "var(--cat-6)"];
|
|
166
|
+
function ProportionBar({
|
|
167
|
+
segments,
|
|
168
|
+
total,
|
|
169
|
+
showLegend = true,
|
|
170
|
+
showPercent = true,
|
|
171
|
+
height = 10,
|
|
172
|
+
ariaLabel,
|
|
173
|
+
className,
|
|
174
|
+
...rest
|
|
175
|
+
}) {
|
|
176
|
+
const sum = total ?? segments.reduce((a, s) => a + Math.max(0, s.value), 0);
|
|
177
|
+
const pctOf = (v) => sum > 0 ? Math.max(0, v) / sum * 100 : 0;
|
|
178
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkPASF6T4H_js.cx("proportion", className), ...rest, children: [
|
|
179
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "proportion__track", role: "img", "aria-label": ariaLabel, style: { height }, children: segments.map((s, i) => {
|
|
180
|
+
const pct = pctOf(s.value);
|
|
181
|
+
if (pct <= 0) return null;
|
|
182
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
183
|
+
"span",
|
|
184
|
+
{
|
|
185
|
+
className: "proportion__seg",
|
|
186
|
+
style: { width: `${pct}%`, background: s.color ?? CAT_HUES[i % CAT_HUES.length] },
|
|
187
|
+
title: `${s.label}: ${chunkCTOPKHEE_js.formatNumber(s.value)}`
|
|
188
|
+
},
|
|
189
|
+
s.label
|
|
190
|
+
);
|
|
191
|
+
}) }),
|
|
192
|
+
showLegend && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "proportion__legend", children: segments.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "proportion__legend-item", children: [
|
|
193
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "proportion__swatch", style: { background: s.color ?? CAT_HUES[i % CAT_HUES.length] } }),
|
|
194
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "proportion__legend-label", children: s.label }),
|
|
195
|
+
showPercent && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "proportion__legend-pct", children: [
|
|
196
|
+
chunkCTOPKHEE_js.formatNumber(pctOf(s.value), { maximumFractionDigits: 0 }),
|
|
197
|
+
"%"
|
|
198
|
+
] })
|
|
199
|
+
] }, s.label)) })
|
|
200
|
+
] });
|
|
201
|
+
}
|
|
202
|
+
function BulletChart({
|
|
203
|
+
value,
|
|
204
|
+
target,
|
|
205
|
+
min = 0,
|
|
206
|
+
max,
|
|
207
|
+
ranges = [],
|
|
208
|
+
label,
|
|
209
|
+
valueLabel,
|
|
210
|
+
tone = "primary",
|
|
211
|
+
height = 22,
|
|
212
|
+
ariaLabel,
|
|
213
|
+
className,
|
|
214
|
+
...rest
|
|
215
|
+
}) {
|
|
216
|
+
const scaleMax = max ?? Math.max(value, target ?? 0, ...ranges, 1);
|
|
217
|
+
const span = scaleMax - min || 1;
|
|
218
|
+
const toPct = (v) => Math.min(100, Math.max(0, (v - min) / span * 100));
|
|
219
|
+
const sortedRanges = [...ranges].sort((a, b) => a - b);
|
|
220
|
+
const bands = sortedRanges.map((r, i) => ({ from: i === 0 ? min : sortedRanges[i - 1], to: r, level: i }));
|
|
221
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkPASF6T4H_js.cx("bullet", className), ...rest, children: [
|
|
222
|
+
(label || valueLabel) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bullet__head", children: [
|
|
223
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bullet__label", children: label }),
|
|
224
|
+
valueLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bullet__value", children: valueLabel })
|
|
225
|
+
] }),
|
|
226
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
227
|
+
"div",
|
|
228
|
+
{
|
|
229
|
+
className: "bullet__track",
|
|
230
|
+
role: "img",
|
|
231
|
+
"aria-label": ariaLabel ?? (typeof label === "string" ? `${label}: ${value}${target !== void 0 ? ` de ${target}` : ""}` : void 0),
|
|
232
|
+
style: { height },
|
|
233
|
+
children: [
|
|
234
|
+
bands.map((b) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
235
|
+
"span",
|
|
236
|
+
{
|
|
237
|
+
className: "bullet__band",
|
|
238
|
+
style: { left: `${toPct(b.from)}%`, width: `${toPct(b.to) - toPct(b.from)}%`, opacity: 0.12 + b.level * 0.1 }
|
|
239
|
+
},
|
|
240
|
+
b.level
|
|
241
|
+
)),
|
|
242
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: chunkPASF6T4H_js.cx("bullet__measure", `bullet__measure--${tone}`), style: { width: `${toPct(value)}%` } }),
|
|
243
|
+
target !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bullet__target", style: { left: `${toPct(target)}%` }, "aria-hidden": true })
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
] });
|
|
248
|
+
}
|
|
249
|
+
var LEVELS = 4;
|
|
250
|
+
function CalendarHeatmap({
|
|
251
|
+
data,
|
|
252
|
+
rows = 7,
|
|
253
|
+
max,
|
|
254
|
+
color = "var(--color-primary)",
|
|
255
|
+
cellSize = 13,
|
|
256
|
+
gap = 3,
|
|
257
|
+
legend = true,
|
|
258
|
+
ariaLabel,
|
|
259
|
+
className,
|
|
260
|
+
style,
|
|
261
|
+
...rest
|
|
262
|
+
}) {
|
|
263
|
+
const ceiling = max ?? Math.max(1, ...data.map((d) => Number.isFinite(d.value) ? d.value : 0));
|
|
264
|
+
const bucket = (v) => {
|
|
265
|
+
if (v <= 0) return 0;
|
|
266
|
+
return Math.min(LEVELS, Math.ceil(v / ceiling * LEVELS));
|
|
267
|
+
};
|
|
268
|
+
const tint = (level) => level === 0 ? "var(--bg-muted)" : color;
|
|
269
|
+
const opacity = (level) => level === 0 ? 1 : 0.25 + level / LEVELS * 0.75;
|
|
270
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkPASF6T4H_js.cx("heatmap", className), ...rest, children: [
|
|
271
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
272
|
+
"div",
|
|
273
|
+
{
|
|
274
|
+
className: "heatmap__grid",
|
|
275
|
+
role: "img",
|
|
276
|
+
"aria-label": ariaLabel,
|
|
277
|
+
style: {
|
|
278
|
+
gridTemplateRows: `repeat(${rows}, ${cellSize}px)`,
|
|
279
|
+
gridAutoColumns: `${cellSize}px`,
|
|
280
|
+
gap,
|
|
281
|
+
...style
|
|
282
|
+
},
|
|
283
|
+
children: data.map((d, i) => {
|
|
284
|
+
const level = bucket(d.value);
|
|
285
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
286
|
+
"span",
|
|
287
|
+
{
|
|
288
|
+
className: "heatmap__cell",
|
|
289
|
+
style: { background: tint(level), opacity: opacity(level), borderRadius: "var(--radius-sm)" },
|
|
290
|
+
title: d.label != null ? String(d.label) : d.date ? `${d.date}: ${chunkCTOPKHEE_js.formatNumber(d.value)}` : chunkCTOPKHEE_js.formatNumber(d.value)
|
|
291
|
+
},
|
|
292
|
+
d.date ?? i
|
|
293
|
+
);
|
|
294
|
+
})
|
|
295
|
+
}
|
|
296
|
+
),
|
|
297
|
+
legend && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "heatmap__legend", children: [
|
|
298
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "heatmap__legend-text", children: "menos" }),
|
|
299
|
+
Array.from({ length: LEVELS + 1 }, (_, l) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "heatmap__cell heatmap__legend-cell", style: { background: tint(l), opacity: opacity(l), borderRadius: "var(--radius-sm)" } }, l)),
|
|
300
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "heatmap__legend-text", children: "m\xE1s" })
|
|
301
|
+
] })
|
|
302
|
+
] });
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
exports.BulletChart = BulletChart;
|
|
306
|
+
exports.CalendarHeatmap = CalendarHeatmap;
|
|
307
|
+
exports.DeltaBadge = DeltaBadge;
|
|
308
|
+
exports.Meter = Meter;
|
|
309
|
+
exports.ProportionBar = ProportionBar;
|
|
310
|
+
exports.Sparkbar = Sparkbar;
|
|
311
|
+
exports.StatCard = StatCard;
|
|
312
|
+
//# sourceMappingURL=chunk-BULIPFOG.js.map
|
|
313
|
+
//# sourceMappingURL=chunk-BULIPFOG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Metrics.tsx"],"names":["formatNumber","ArrowUp","ArrowDown","Minus","jsxs","cx","jsx"],"mappings":"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","file":"chunk-BULIPFOG.js","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { formatNumber } from '../utils/format';\nimport { ArrowUp, ArrowDown, Minus } from './Icons';\nimport type { CategoryAccent } from './Display';\n\n/**\n * Dashboard data-communication primitives. Everything here is CSS-only — no\n * recharts dependency — so consumers can drop dense micro-viz into cards and\n * table cells without paying for a chart library. The heavyweight charts\n * (Line/Area/Bar/Donut) still live in Charts.tsx behind the BYO-recharts seam.\n */\n\n// ---------- DeltaBadge --------------------------------------------------\n// A sign-driven variation pill: ▲ +12,4% (good) / ▼ −3,1% (bad) / – 0% (flat).\n// Pulls the trend logic that used to be locked inside Stat into a reusable\n// atom for table cells, cards, anywhere. `invert` flips the tone (not the\n// arrow) for \"higher is worse\" metrics like error rate or cost.\nexport type DeltaTone = 'pos' | 'neg' | 'flat';\n\nexport interface DeltaBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {\n /** The variation. Sign drives direction + tone; magnitude is formatted. */\n value: number;\n /** Full-label formatter (incl. sign). Default: signed percent, e.g. `+12,4%`. */\n format?: (value: number) => string;\n /** Higher-is-worse: an increase shows ▲ but in red (cost, error rate, churn). */\n invert?: boolean;\n /** |value| ≤ this renders flat/neutral. Default 0. */\n neutralThreshold?: number;\n /** Hide the directional arrow, keep the colored number. */\n showIcon?: boolean;\n size?: 'sm' | 'md';\n}\n\nconst SIGNED_PERCENT = (v: number): string => {\n const sign = v > 0 ? '+' : v < 0 ? '−' : '';\n return `${sign}${formatNumber(Math.abs(v), { maximumFractionDigits: 1 })}%`;\n};\n\nexport function DeltaBadge({\n value, format = SIGNED_PERCENT, invert = false, neutralThreshold = 0,\n showIcon = true, size = 'md', className, ...rest\n}: DeltaBadgeProps) {\n const dir: 'up' | 'down' | 'flat' =\n value > neutralThreshold ? 'up' : value < -neutralThreshold ? 'down' : 'flat';\n const tone: DeltaTone =\n dir === 'flat' ? 'flat' : dir === 'up' ? (invert ? 'neg' : 'pos') : (invert ? 'pos' : 'neg');\n const Icon = dir === 'up' ? ArrowUp : dir === 'down' ? ArrowDown : Minus;\n const verb = dir === 'up' ? 'subió' : dir === 'down' ? 'bajó' : 'sin cambio';\n const text = format(value);\n\n return (\n <span\n className={cx('delta-badge', `delta-badge--${tone}`, size === 'sm' && 'delta-badge--sm', className)}\n aria-label={`${verb} ${text}`}\n {...rest}\n >\n {showIcon && <Icon size={size === 'sm' ? 11 : 13} aria-hidden />}\n <span className=\"delta-badge__text\">{text}</span>\n </span>\n );\n}\n\n// ---------- StatCard ----------------------------------------------------\n// The flagship KPI atom: leading icon + label, a large tabular value, a\n// DeltaBadge + comparison caption, and an optional chart slot (Sparkline /\n// Sparkbar). A standalone surface (does not depend on Card) so it composes in\n// any grid. `accent` tints the left edge with a category hue.\nexport interface StatCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n label: React.ReactNode;\n value: React.ReactNode;\n /** Convenience: renders a DeltaBadge. Omit and pass `deltaNode` for full control. */\n delta?: number;\n deltaFormat?: (value: number) => string;\n deltaInvert?: boolean;\n /** Escape hatch when `delta` isn't enough (custom node in the delta slot). */\n deltaNode?: React.ReactNode;\n /** Caption next to the delta, e.g. \"vs. mes anterior\". */\n caption?: React.ReactNode;\n /** Small leading glyph rendered in a tinted chip. */\n icon?: React.ReactNode;\n /** Left-edge accent hue. */\n accent?: CategoryAccent;\n /** Micro-viz slot (Sparkline / Sparkbar / ProportionBar). */\n chart?: React.ReactNode;\n}\n\nexport function StatCard({\n label, value, delta, deltaFormat, deltaInvert, deltaNode, caption, icon, accent, chart,\n className, ...rest\n}: StatCardProps) {\n const deltaEl =\n deltaNode ??\n (delta !== undefined ? <DeltaBadge value={delta} format={deltaFormat} invert={deltaInvert} size=\"sm\" /> : null);\n\n return (\n <div\n className={cx('metric-card', accent && `metric-card--${accent}`, className)}\n data-accent={accent}\n {...rest}\n >\n <div className=\"metric-card__head\">\n {icon && <span className=\"metric-card__icon\" aria-hidden>{icon}</span>}\n <span className=\"metric-card__label\">{label}</span>\n </div>\n <div className=\"metric-card__value\">{value}</div>\n {(deltaEl || caption) && (\n <div className=\"metric-card__foot\">\n {deltaEl}\n {caption && <span className=\"metric-card__caption\">{caption}</span>}\n </div>\n )}\n {chart && <div className=\"metric-card__chart\">{chart}</div>}\n </div>\n );\n}\n\n// ---------- Meter -------------------------------------------------------\n// A value within a range, with optional qualitative thresholds that drive the\n// fill tone. Distinct from Progress: `role=\"meter\"` is a static measurement\n// (stock level, budget used, capacity), not a task advancing to 100%.\nexport type MeterOptimum = 'low' | 'high' | 'middle';\n\nexport interface MeterProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n value: number;\n min?: number;\n max?: number;\n /** Lower threshold boundary (for tone zones). */\n low?: number;\n /** Upper threshold boundary (for tone zones). */\n high?: number;\n /** Where \"good\" lives. Default `high` (more is better). */\n optimum?: MeterOptimum;\n label?: React.ReactNode;\n /** Value caption. String or formatter; default shows `value/max`. */\n valueLabel?: React.ReactNode | ((value: number, max: number) => React.ReactNode);\n showValue?: boolean;\n size?: 'sm' | 'md';\n}\n\nfunction meterTone(value: number, low: number | undefined, high: number | undefined, optimum: MeterOptimum): DeltaTone | 'warn' {\n if (low === undefined && high === undefined) return 'pos'; // no thresholds → neutral-positive (primary)\n const lo = low ?? -Infinity;\n const hi = high ?? Infinity;\n if (optimum === 'high') return value >= hi ? 'pos' : value >= lo ? 'warn' : 'neg';\n if (optimum === 'low') return value <= lo ? 'pos' : value <= hi ? 'warn' : 'neg';\n return value >= lo && value <= hi ? 'pos' : 'warn'; // middle\n}\n\nexport function Meter({\n value, min = 0, max = 100, low, high, optimum = 'high',\n label, valueLabel, showValue = true, size = 'md', className, ...rest\n}: MeterProps) {\n const clamped = Math.min(Math.max(value, min), max);\n const pct = max > min ? ((clamped - min) / (max - min)) * 100 : 0;\n const tone = meterTone(value, low, high, optimum);\n const hasThresholds = low !== undefined || high !== undefined;\n const caption =\n typeof valueLabel === 'function' ? valueLabel(value, max)\n : valueLabel !== undefined ? valueLabel\n : `${formatNumber(value)} / ${formatNumber(max)}`;\n\n return (\n <div className={cx('meter', size === 'sm' && 'meter--sm', className)} {...rest}>\n {(label || showValue) && (\n <div className=\"meter__head\">\n {label && <span className=\"meter__label\">{label}</span>}\n {showValue && <span className=\"meter__value\">{caption}</span>}\n </div>\n )}\n <div\n className=\"meter__track\"\n role=\"meter\"\n aria-valuenow={value}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-label={typeof label === 'string' ? label : undefined}\n >\n <div\n className={cx('meter__fill', hasThresholds ? `meter__fill--${tone}` : 'meter__fill--primary')}\n style={{ width: `${pct}%` }}\n />\n </div>\n </div>\n );\n}\n\n// ---------- Sparkbar ----------------------------------------------------\n// Inline mini bars, CSS-only. The bar counterpart to Sparkline — drop a\n// distribution into a table cell or StatCard without recharts.\nexport interface SparkbarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n data: number[];\n height?: number;\n /** Scale ceiling. Default: max of `data`. */\n max?: number;\n color?: string;\n /** Emphasize the most recent bar (full opacity + secondary hue). */\n highlightLast?: boolean;\n /** Gap between bars in px. Default 2. */\n gap?: number;\n ariaLabel?: string;\n}\n\nexport function Sparkbar({\n data, height = 32, max, color = 'var(--color-primary)', highlightLast = false,\n gap = 2, ariaLabel, className, style, ...rest\n}: SparkbarProps) {\n const ceiling = max ?? Math.max(1, ...data.map((d) => (Number.isFinite(d) ? d : 0)));\n return (\n <div\n className={cx('sparkbar', className)}\n role=\"img\"\n aria-label={ariaLabel}\n style={{ height, gap, ...style }}\n {...rest}\n >\n {data.map((d, i) => {\n const isLast = highlightLast && i === data.length - 1;\n const h = ceiling > 0 ? Math.max(2, (Math.max(0, d) / ceiling) * 100) : 2;\n return (\n <span\n key={i}\n className={cx('sparkbar__bar', isLast && 'sparkbar__bar--last')}\n style={{ height: `${h}%`, background: isLast ? 'var(--color-secondary)' : color }}\n />\n );\n })}\n </div>\n );\n}\n\n// ---------- ProportionBar -----------------------------------------------\n// A single 100%-stacked bar for an inline category breakdown (paid / pending /\n// overdue) — the lightweight alternative to a donut when you just need shares.\nexport interface ProportionSegment {\n label: string;\n value: number;\n color?: string;\n}\n\nexport interface ProportionBarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n segments: ProportionSegment[];\n /** Denominator override (e.g. show partial fill against a known total). */\n total?: number;\n showLegend?: boolean;\n showPercent?: boolean;\n height?: number;\n ariaLabel?: string;\n}\n\nconst CAT_HUES = ['var(--cat-1)', 'var(--cat-2)', 'var(--cat-4)', 'var(--cat-5)', 'var(--cat-3)', 'var(--cat-6)'];\n\nexport function ProportionBar({\n segments, total, showLegend = true, showPercent = true, height = 10,\n ariaLabel, className, ...rest\n}: ProportionBarProps) {\n const sum = total ?? segments.reduce((a, s) => a + Math.max(0, s.value), 0);\n const pctOf = (v: number) => (sum > 0 ? (Math.max(0, v) / sum) * 100 : 0);\n\n return (\n <div className={cx('proportion', className)} {...rest}>\n <div className=\"proportion__track\" role=\"img\" aria-label={ariaLabel} style={{ height }}>\n {segments.map((s, i) => {\n const pct = pctOf(s.value);\n if (pct <= 0) return null;\n return (\n <span\n key={s.label}\n className=\"proportion__seg\"\n style={{ width: `${pct}%`, background: s.color ?? CAT_HUES[i % CAT_HUES.length] }}\n title={`${s.label}: ${formatNumber(s.value)}`}\n />\n );\n })}\n </div>\n {showLegend && (\n <ul className=\"proportion__legend\">\n {segments.map((s, i) => (\n <li key={s.label} className=\"proportion__legend-item\">\n <span className=\"proportion__swatch\" style={{ background: s.color ?? CAT_HUES[i % CAT_HUES.length] }} />\n <span className=\"proportion__legend-label\">{s.label}</span>\n {showPercent && <span className=\"proportion__legend-pct\">{formatNumber(pctOf(s.value), { maximumFractionDigits: 0 })}%</span>}\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n\n// ---------- BulletChart -------------------------------------------------\n// Stephen Few's bullet graph (2006): a compact actual-vs-target bar over\n// qualitative ranges. Communicates more per pixel than a gauge — built for\n// dense KPI rows. CSS-only.\nexport type BulletTone = 'primary' | 'success' | 'warning' | 'danger';\n\nexport interface BulletChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n value: number;\n /** Comparative marker (the vertical tick). */\n target?: number;\n min?: number;\n /** Scale end. Default: max of value/target/ranges. */\n max?: number;\n /** Qualitative range boundaries (ascending). Shaded light→dark behind the bar. */\n ranges?: number[];\n label?: React.ReactNode;\n valueLabel?: React.ReactNode;\n tone?: BulletTone;\n height?: number;\n ariaLabel?: string;\n}\n\nexport function BulletChart({\n value, target, min = 0, max, ranges = [], label, valueLabel, tone = 'primary',\n height = 22, ariaLabel, className, ...rest\n}: BulletChartProps) {\n const scaleMax = max ?? Math.max(value, target ?? 0, ...ranges, 1);\n const span = scaleMax - min || 1;\n const toPct = (v: number) => Math.min(100, Math.max(0, ((v - min) / span) * 100));\n // Build cumulative band stops so each qualitative band has increasing tint.\n const sortedRanges = [...ranges].sort((a, b) => a - b);\n const bands = sortedRanges.map((r, i) => ({ from: i === 0 ? min : sortedRanges[i - 1], to: r, level: i }));\n\n return (\n <div className={cx('bullet', className)} {...rest}>\n {(label || valueLabel) && (\n <div className=\"bullet__head\">\n {label && <span className=\"bullet__label\">{label}</span>}\n {valueLabel && <span className=\"bullet__value\">{valueLabel}</span>}\n </div>\n )}\n <div\n className=\"bullet__track\"\n role=\"img\"\n aria-label={ariaLabel ?? (typeof label === 'string' ? `${label}: ${value}${target !== undefined ? ` de ${target}` : ''}` : undefined)}\n style={{ height }}\n >\n {bands.map((b) => (\n <span\n key={b.level}\n className=\"bullet__band\"\n style={{ left: `${toPct(b.from)}%`, width: `${toPct(b.to) - toPct(b.from)}%`, opacity: 0.12 + b.level * 0.1 }}\n />\n ))}\n <span className={cx('bullet__measure', `bullet__measure--${tone}`)} style={{ width: `${toPct(value)}%` }} />\n {target !== undefined && <span className=\"bullet__target\" style={{ left: `${toPct(target)}%` }} aria-hidden />}\n </div>\n </div>\n );\n}\n\n// ---------- CalendarHeatmap ---------------------------------------------\n// An intensity grid (GitHub-contributions style): cells tinted by value into\n// discrete buckets. Column-major fill (each column = a week, rows = weekdays).\nexport interface HeatmapCell {\n /** Optional key/date for accessibility + keys. */\n date?: string;\n label?: React.ReactNode;\n value: number;\n}\n\nexport interface CalendarHeatmapProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n data: HeatmapCell[];\n /** Rows in the grid (column-major flow). Default 7 (weekdays). */\n rows?: number;\n /** Intensity ceiling. Default: max of `data`. */\n max?: number;\n /** Base hue tinted by intensity. Default primary. */\n color?: string;\n cellSize?: number;\n gap?: number;\n legend?: boolean;\n ariaLabel?: string;\n}\n\nconst LEVELS = 4; // intensity buckets above zero\n\nexport function CalendarHeatmap({\n data, rows = 7, max, color = 'var(--color-primary)', cellSize = 13, gap = 3,\n legend = true, ariaLabel, className, style, ...rest\n}: CalendarHeatmapProps) {\n const ceiling = max ?? Math.max(1, ...data.map((d) => (Number.isFinite(d.value) ? d.value : 0)));\n const bucket = (v: number): number => {\n if (v <= 0) return 0;\n return Math.min(LEVELS, Math.ceil((v / ceiling) * LEVELS));\n };\n // opacity ramp per bucket so the base hue reads light→saturated.\n const tint = (level: number) => (level === 0 ? 'var(--bg-muted)' : color);\n const opacity = (level: number) => (level === 0 ? 1 : 0.25 + (level / LEVELS) * 0.75);\n\n return (\n <div className={cx('heatmap', className)} {...rest}>\n <div\n className=\"heatmap__grid\"\n role=\"img\"\n aria-label={ariaLabel}\n style={{\n gridTemplateRows: `repeat(${rows}, ${cellSize}px)`,\n gridAutoColumns: `${cellSize}px`,\n gap,\n ...style,\n }}\n >\n {data.map((d, i) => {\n const level = bucket(d.value);\n return (\n <span\n key={d.date ?? i}\n className=\"heatmap__cell\"\n style={{ background: tint(level), opacity: opacity(level), borderRadius: 'var(--radius-sm)' }}\n title={d.label != null ? String(d.label) : d.date ? `${d.date}: ${formatNumber(d.value)}` : formatNumber(d.value)}\n />\n );\n })}\n </div>\n {legend && (\n <div className=\"heatmap__legend\">\n <span className=\"heatmap__legend-text\">menos</span>\n {Array.from({ length: LEVELS + 1 }, (_, l) => (\n <span key={l} className=\"heatmap__cell heatmap__legend-cell\" style={{ background: tint(l), opacity: opacity(l), borderRadius: 'var(--radius-sm)' }} />\n ))}\n <span className=\"heatmap__legend-text\">más</span>\n </div>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var chunk55P5FA5Q_js = require('./chunk-55P5FA5Q.js');
|
|
4
5
|
var chunkD2H4VZVL_js = require('./chunk-D2H4VZVL.js');
|
|
5
6
|
var chunkFL4ZCWUF_js = require('./chunk-FL4ZCWUF.js');
|
|
6
7
|
var chunkNPXEZCTA_js = require('./chunk-NPXEZCTA.js');
|
|
7
|
-
var chunk55P5FA5Q_js = require('./chunk-55P5FA5Q.js');
|
|
8
8
|
var chunkA42WMR4M_js = require('./chunk-A42WMR4M.js');
|
|
9
9
|
var chunkC4AKMVDZ_js = require('./chunk-C4AKMVDZ.js');
|
|
10
10
|
var chunkPASF6T4H_js = require('./chunk-PASF6T4H.js');
|
|
@@ -146,5 +146,5 @@ function Drawer({
|
|
|
146
146
|
|
|
147
147
|
exports.Drawer = Drawer;
|
|
148
148
|
exports.Modal = Modal;
|
|
149
|
-
//# sourceMappingURL=chunk-
|
|
150
|
-
//# sourceMappingURL=chunk-
|
|
149
|
+
//# sourceMappingURL=chunk-DLDTUVHR.js.map
|
|
150
|
+
//# sourceMappingURL=chunk-DLDTUVHR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Overlay.tsx"],"names":["React","useLocale","useDelayedUnmount","useEscape","useFocusTrap","useScrollLock","createPortal","jsx","cx","jsxs","X"],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/components/Overlay.tsx"],"names":["React","useLocale","useDelayedUnmount","useEscape","useFocusTrap","useScrollLock","createPortal","jsx","cx","jsxs","X"],"mappings":"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","file":"chunk-DLDTUVHR.js","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { cx } from '../utils/cx';\nimport { X } from './Icons';\nimport { useLocale } from '../locale/LocaleProvider';\nimport { useDelayedUnmount } from '../hooks/useDelayedUnmount';\nimport { useFocusTrap, useEscape, useScrollLock } from '../hooks';\n\n// Exit animation duration in ms. Must match `--duration-exit` and the\n// `is-closing` keyframes in src/styles/index.css (`.modal-backdrop`,\n// `.drawer-backdrop`).\nconst EXIT_MS = 150;\n\nexport interface OverlayProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n size?: 'sm' | 'md' | 'lg';\n closeOnBackdrop?: boolean;\n closeOnEsc?: boolean;\n className?: string;\n}\n\nexport function Modal({\n open, onClose, title, children, footer, size = 'md',\n closeOnBackdrop = true, closeOnEsc = true, className,\n}: OverlayProps) {\n const ref = React.useRef<HTMLDivElement>(null);\n // True only when the press both started AND ended on the backdrop itself.\n // Fixes: press inside (e.g. text-selecting in an input) released over the\n // backdrop must NOT dismiss.\n const downOnBackdrop = React.useRef(false);\n const titleId = React.useId();\n const t = useLocale();\n // useDelayedUnmount keeps the DOM mounted during exit animation. The\n // a11y/scroll-lock hooks still consume `open` (the user's intent), not\n // `mounted` — we don't want to trap focus or block scroll while\n // animating out.\n const { mounted, closing } = useDelayedUnmount(open, EXIT_MS);\n useEscape(open, onClose, closeOnEsc);\n useFocusTrap(ref, open);\n useScrollLock(open);\n if (!mounted || typeof document === 'undefined') return null;\n return createPortal(\n <div\n className={cx('modal-backdrop', closing && 'is-closing')}\n onMouseDown={(e) => { downOnBackdrop.current = e.target === e.currentTarget; }}\n onClick={(e) => {\n if (closeOnBackdrop && downOnBackdrop.current && e.target === e.currentTarget) onClose();\n downOnBackdrop.current = false;\n }}\n >\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n className={cx('modal', `modal--${size}`, closing && 'is-closing', className)}\n >\n {title && (\n <div className=\"modal__header\">\n <div id={titleId} className=\"modal__title\">{title}</div>\n <button type=\"button\" className=\"modal__close\" onClick={onClose} aria-label={t['modal.close']}><X size={18} /></button>\n </div>\n )}\n <div className=\"modal__body\">{children}</div>\n {footer && <div className=\"modal__footer\">{footer}</div>}\n </div>\n </div>,\n document.body\n );\n}\n\nexport interface DrawerProps extends OverlayProps {\n side?: 'left' | 'right';\n}\n\nexport function Drawer({\n open, onClose, title, children, footer, side = 'right',\n closeOnBackdrop = true, closeOnEsc = true, className,\n}: DrawerProps) {\n const ref = React.useRef<HTMLDivElement>(null);\n // True only when the press both started AND ended on the backdrop itself.\n // Fixes: press inside (e.g. text-selecting in an input) released over the\n // backdrop must NOT dismiss.\n const downOnBackdrop = React.useRef(false);\n const titleId = React.useId();\n const t = useLocale();\n const { mounted, closing } = useDelayedUnmount(open, EXIT_MS);\n useEscape(open, onClose, closeOnEsc);\n useFocusTrap(ref, open);\n useScrollLock(open);\n if (!mounted || typeof document === 'undefined') return null;\n return createPortal(\n <div\n className={cx('drawer-backdrop', closing && 'is-closing')}\n onMouseDown={(e) => { downOnBackdrop.current = e.target === e.currentTarget; }}\n onClick={(e) => {\n if (closeOnBackdrop && downOnBackdrop.current && e.target === e.currentTarget) onClose();\n downOnBackdrop.current = false;\n }}\n >\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n className={cx('drawer', `drawer--${side}`, closing && 'is-closing', className)}\n >\n {title && (\n <div className=\"drawer__header\">\n <div id={titleId} className=\"drawer__title\">{title}</div>\n <button type=\"button\" className=\"drawer__close\" onClick={onClose} aria-label={t['drawer.close']}><X size={18} /></button>\n </div>\n )}\n <div className=\"drawer__body\">{children}</div>\n {footer && <div className=\"drawer__footer\">{footer}</div>}\n </div>\n </div>,\n document.body\n );\n}\n"]}
|