gridsmith-ui 0.12.0 → 0.14.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-HL3KYWOK.js → chunk-JSQPVRHQ.js} +81 -64
- package/dist/chunk-JSQPVRHQ.js.map +1 -0
- package/dist/{chunk-YO7JVPXK.js → chunk-TKVTZWBN.js} +3 -2
- package/dist/chunk-TKVTZWBN.js.map +1 -0
- package/dist/data-grid.js +3 -3
- package/dist/data-grid.js.map +1 -1
- package/dist/index.d.ts +64 -16
- package/dist/index.js +87 -36
- package/dist/index.js.map +1 -1
- package/dist/resizable.js +2 -2
- package/dist/roots.css +8 -0
- package/package.json +1 -1
- package/dist/chunk-HL3KYWOK.js.map +0 -1
- package/dist/chunk-YO7JVPXK.js.map +0 -1
package/dist/data-grid.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/components/DataGrid.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAqCA,SAAS,SAAA,CAAU,EAAE,QAAA,EAAU,KAAA,EAAM,EAA2C;AAC9E,EAAA,MAAM,EAAE,GAAA,EAAK,WAAA,KAAgB,eAAA,CAAgB,EAAE,OAAO,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,KAAA,KAAU,CAAA,GAAI,UAAA,GAAa,cAAc,KAAK,CAAA,CAAA;AACjE,EAAA,MAAM,IAAA,uBAAQ,MAAA,EAAA,EAAK,GAAA,EAAU,WAAW,EAAA,CAAG,UAAA,EAAY,OAAO,CAAA,EAAI,QAAA,EAAS,CAAA;AAC3E,EAAA,IAAI,CAAC,aAAa,OAAO,IAAA;AACzB,EAAA,uBAAO,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAA,EAAS,QAAA,EAAW,QAAA,EAAA,IAAA,EAAK,CAAA;AAC3C;AAcO,SAAS,QAAA,CAAY;AAAA,EAC1B,IAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA,GAAW,EAAA;AAAA,EACX,QAAA,GAAW,KAAA;AAAA,EACX,UAAA;AAAA,EACA,gBAAA,EAAkB,oBAAA;AAAA,EAClB;AACF,CAAA,EAAqB;AAEnB,EAAA,MAAM,cAAc,mBAAA,EAAoB;AACxC,EAAA,MAAM,gBAAA,GAAkC,oBAAA,IAAwB,WAAA,CAAY,sBAAA,IAA0B,IAAA;AACtG,EAAA,MAAM,QAAA,GAAW,cAAc,gBAAgB,CAAA;AAC/C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,QAAA,CAAuB,EAAE,CAAA;AACvD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAA8C,IAAI,CAAA;AAClF,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,EAAE,CAAA;AAG7C,EAAA,MAAM,UAAA,GAAa,QAAQ,MAAM,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,aAAA,IAAiB,CAAA,GAAI,OAAO,CAAA,CAAE,WAAW,IAAI,EAAA,CAAG,CAAA,CAAE,OAAO,OAAO,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AACzI,EAAA,MAAM,aAAA,GAAgB,OAAA;AAAA,IACpB,MAAM,gBAAA,CAAiB,IAAA,EAAmC,UAAU,CAAA;AAAA,IACpE,CAAC,MAAM,UAAU;AAAA,GACnB;AACA,EAAA,MAAM,MAAA,GAAS,WAAA;AAAA,IACb,CAAC,KAAA,EAAe,IAAA,KAAyC,MAAM,IAAA,IAAQ,aAAA,CAAc,IAAI,KAAK,CAAA;AAAA,IAC9F,CAAC,aAAa;AAAA,GAChB;AAEA,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AACjC,IAAA,IAAI,CAAC,UAAU,OAAO,OAAA;AACtB,IAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,MAAS;AAAA,MAC3B,GAAG,GAAA;AAAA,MACH,IAAA,EAAM,CAAC,IAAA,KAAkC;AACvC,QAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,KAAA;AACxB,QAAA,MAAM,KAAA,GAAQ,KAAK,MAAA,CAAO,EAAA;AAC1B,QAAA,MAAM,SAAA,GAAY,QAAA,EAAU,GAAA,KAAQ,MAAA,IAAU,UAAU,GAAA,KAAQ,KAAA;AAEhE,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,uBACE,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAS,IAAA;AAAA,cACT,SAAA,EAAW,EAAA;AAAA,gBACT,oEAAA;AAAA,gBACA;AAAA,eACF;AAAA,cACA,KAAA,EAAO,SAAA;AAAA,cACP,UAAU,CAAC,CAAA,KAAM,YAAA,CAAa,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,cAC5C,QAAQ,MAAM;AACZ,gBAAA,UAAA,GAAa,MAAA,EAAQ,OAAO,SAAS,CAAA;AACrC,gBAAA,WAAA,CAAY,IAAI,CAAA;AAAA,cAClB,CAAA;AAAA,cACA,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,gBAAA,IAAI,CAAA,CAAE,QAAQ,OAAA,EAAS;AACrB,kBAAA,UAAA,GAAa,MAAA,EAAQ,OAAO,SAAS,CAAA;AACrC,kBAAA,WAAA,CAAY,IAAI,CAAA;AAAA,gBAClB,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU;AAC7B,kBAAA,WAAA,CAAY,IAAI,CAAA;AAAA,gBAClB;AAAA,cACF;AAAA;AAAA,WACF;AAAA,QAEJ;AAEA,QAAA,MAAM,QAAA,GAAW,OAAO,GAAA,CAAI,IAAA,KAAS,UAAA,GAAa,IAAI,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA,CAAK,QAAA,EAAS;AACjF,QAAA,uBACE,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,eAAe,MAAM;AACnB,cAAA,WAAA,CAAY,EAAE,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,OAAO,CAAA;AACvC,cAAA,YAAA,CAAa,MAAA,CAAO,IAAA,CAAK,QAAA,EAAS,IAAK,EAAE,CAAC,CAAA;AAAA,YAC5C,CAAA;AAAA,YACA,SAAA,EAAU,gBAAA;AAAA,YAET,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,MAEJ;AAAA,KACF,CAAE,CAAA;AAAA,EACJ,GAAG,CAAC,OAAA,EAAS,UAAU,QAAA,EAAU,SAAA,EAAW,UAAU,CAAC,CAAA;AAMvD,EAAA,MAAM,QAAQ,aAAA,CAAc;AAAA,IAC1B,IAAA;AAAA,IACA,OAAA,EAAS,YAAA;AAAA,IACT,KAAA,EAAO,EAAE,OAAA,EAAQ;AAAA,IACjB,eAAA,EAAiB,UAAA;AAAA,IACjB,iBAAiB,eAAA,EAAgB;AAAA,IACjC,mBAAmB,iBAAA,EAAkB;AAAA,IACrC,uBAAuB,qBAAA,EAAsB;AAAA,IAC7C,YAAA,EAAc,EAAE,UAAA,EAAY,EAAE,UAAS;AAAE,GAC1C,CAAA;AAED,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,IAAA,KAAiB,KAAA,CAAM,YAAA,CAAa,IAAI,CAAA;AAAA,IACzC,CAAC,KAAK;AAAA,GACR;AAEA,EAAA,MAAM,SAAA,GAAY,MAAM,YAAA,EAAa;AACrC,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,SAAA;AAEhD,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EAC1C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,KAAA,EAAO,IAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACZ,QAAA,EAAA,KAAA,CAAM,WAAA,EAAY,CAAE,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,qBAC7B,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAW,EAAA;AAAA,YACT,yEAAA;AAAA,YACA,yDAAA;AAAA,YACA;AAAA,WACF;AAAA,UAEC,QAAA,EAAA,GAAA,CAAI,iBAAgB,CAAE,GAAA,CAAI,CAAC,IAAA,qBAC1B,IAAA,CAAC,KAAA,EAAA,EAAkB,SAAA,EAAU,uCAAA,EAC3B,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uFAAA,EACb,QAAA,EAAA,OAAO,KAAK,MAAA,CAAO,SAAA,CAAU,MAAA,KAAW,QAAA,GACrC,KAAK,MAAA,CAAO,SAAA,CAAU,MAAA,GACtB,IAAA,CAAK,OAAO,EAAA,EAClB,CAAA;AAAA,4BACA,GAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAO,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,IAAA,EAAM,IAAA,CAAK,UAAA,EAAY,CAAA,EAAG;AAAA,WAAA,EAAA,EANrE,IAAA,CAAK,EAOf,CACD;AAAA,SAAA;AAAA,QAhBI,GAAA,CAAI;AAAA,OAkBZ,GACH,CAAA,EACA,CAAA;AAAA,MAEC,SAAA,GAAY,CAAA,oBACX,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,6BAAA,EAA8B,QAAA,EAAA;AAAA,UAAA,OAAA;AAAA,UACtC,WAAA,GAAc,CAAA;AAAA,UAAE,MAAA;AAAA,UAAK;AAAA,SAAA,EAC7B,CAAA;AAAA,wBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,QAAA,EAAA,EAAS,OAAA,EAAS,MAAM,gBAAA,CAAiB,WAAA,GAAc,CAAC,CAAA,EAAG,QAAA,EAAU,WAAA,KAAgB,CAAA,EAAG,KAAA,EAAM,MAAA,EAAO,CAAA;AAAA,0BACtG,GAAA,CAAC,QAAA,EAAA,EAAS,OAAA,EAAS,MAAM,gBAAA,CAAiB,WAAA,GAAc,CAAC,CAAA,EAAG,QAAA,EAAU,WAAA,IAAe,SAAA,GAAY,CAAA,EAAG,OAAM,MAAA,EAAO;AAAA,SAAA,EACnH;AAAA,OAAA,EACF;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AAEA,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EAC1C,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,oDAAA;AAAA,UACA,yEAAA;AAAA,UACA,gCAAA;AAAA,UACA;AAAA,SACF;AAAA,QAEA,QAAA,kBAAA,IAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,gBAAA,EACf,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,WAAM,SAAA,EAAU,yBAAA,EACd,QAAA,EAAA,KAAA,CAAM,eAAA,GAAkB,GAAA,CAAI,CAAC,EAAA,qBAC5B,GAAA,CAAC,QAAe,SAAA,EAAU,4EAAA,EACvB,aAAG,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,KAAW;AAC1B,YAAA,MAAM,OAAA,GAAU,MAAA,CAAO,MAAA,CAAO,UAAA,EAAW;AACzC,YAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,WAAA,EAAY;AACzC,YAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,SAAA,CAAU,IAAA;AACrC,YAAA,MAAM,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,IAAI,IAAI,CAAA;AAChD,YAAA,MAAM,WAAA,GAAc,IAAA,EAAM,KAAA,KAAU,UAAA,KAAe,WAAW,OAAA,GAAU,MAAA,CAAA;AACxE,YAAA,MAAM,UAAU,UAAA,KAAe,QAAA,IAAY,UAAA,KAAe,MAAA,KAAW,CAAC,IAAA,EAAM,QAAA;AAC5E,YAAA,uBACE,GAAA;AAAA,cAAC,IAAA;AAAA,cAAA;AAAA,gBAEC,SAAA,EAAW,EAAA;AAAA,kBACT,kFAAA;AAAA,kBACA,WAAA,KAAgB,OAAA,GAAU,YAAA,GAAe,WAAA,KAAgB,WAAW,aAAA,GAAgB,WAAA;AAAA,kBACpF,MAAA,IAAU,wBAAA;AAAA,kBACV,iCAAA;AAAA,kBACA,OAAA,IAAW;AAAA,iBACb;AAAA,gBACA,OAAO,IAAA,EAAM,QAAA,IAAY,IAAA,EAAM,KAAA,IAAS,MAAM,QAAA,GAAW,EAAE,QAAA,EAAU,IAAA,EAAM,UAAU,KAAA,EAAO,IAAA,EAAM,OAAO,QAAA,EAAU,IAAA,EAAM,UAAS,GAAI,MAAA;AAAA,gBACtI,OAAA,EAAS,OAAA,GAAU,MAAA,CAAO,MAAA,CAAO,yBAAwB,GAAI,MAAA;AAAA,gBAE7D,QAAA,kBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,4BAAA,EAA8B,WAAA,KAAgB,OAAA,IAAW,aAAA,EAAe,WAAA,KAAgB,QAAA,IAAY,gBAAgB,CAAA,EACrI,QAAA,EAAA;AAAA,kBAAA,UAAA,CAAW,OAAO,MAAA,CAAO,SAAA,CAAU,MAAA,EAAQ,MAAA,CAAO,YAAY,CAAA;AAAA,kBAC9D,OAAA,oBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sCAAA,EACd,QAAA,EAAA;AAAA,oCAAA,GAAA;AAAA,sBAAC,IAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAK,YAAA;AAAA,wBACL,IAAA,EAAM,EAAA;AAAA,wBACN,SAAA,EAAW,MAAA,KAAW,KAAA,GAAQ,iCAAA,GAAoC;AAAA;AAAA,qBACpE;AAAA,oCACA,GAAA;AAAA,sBAAC,IAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAK,cAAA;AAAA,wBACL,IAAA,EAAM,EAAA;AAAA,wBACN,SAAA,EAAW,MAAA,KAAW,MAAA,GAAS,iCAAA,GAAoC;AAAA;AAAA;AACrE,mBAAA,EACF;AAAA,iBAAA,EAEJ;AAAA,eAAA;AAAA,cA3BK,MAAA,CAAO;AAAA,aA4Bd;AAAA,UAEJ,CAAC,CAAA,EAAA,EAxCM,EAAA,CAAG,EAyCZ,CACD,CAAA,EACH,CAAA;AAAA,0BACA,GAAA,CAAC,WACE,QAAA,EAAA,KAAA,CAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,qBAC7B,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cAEC,SAAA,EAAW,EAAA;AAAA,gBACT,4FAAA;AAAA,gBACA;AAAA,eACF;AAAA,cAEC,QAAA,EAAA,GAAA,CAAI,eAAA,EAAgB,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS;AACnC,gBAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,IAAA;AACnC,gBAAA,MAAM,UAAA,GAAa,MAAM,QAAA,KAAa,IAAA,GAAO,IAAI,IAAA,EAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,KAAA,GAAQ,CAAA;AACxF,gBAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,IAAI,IAAI,CAAA;AACxC,gBAAA,MAAM,QAAA,GAAW,WAAW,IAAA,CAAK,MAAA,CAAO,UAAU,IAAA,EAAM,IAAA,CAAK,YAAY,CAAA;AAEzE,gBAAA,MAAM,UAAU,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,MAAA,KAAW,CAAC,IAAA,EAAM,QAAA;AAChE,gBAAA,IAAI,KAAA;AACJ,gBAAA,IAAI,aAAa,CAAA,EAAG;AAClB,kBAAA,KAAA,mBAAQ,GAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAO,UAAA,EAAa,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,gBAClD,CAAA,MAAA,IAAW,SAAS,OAAA,EAAS;AAC3B,kBAAA,KAAA,mBACE,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDAAA,EAAkD,OAAO,OAAO,IAAA,CAAK,QAAA,EAAS,KAAM,QAAA,GAAW,IAAA,CAAK,QAAA,EAAS,GAAc,QACxI,QAAA,EAAA,QAAA,EACH,CAAA;AAAA,gBAEJ,CAAA,MAAO;AACL,kBAAA,KAAA,GAAQ,QAAA;AAAA,gBACV;AAEA,gBAAA,MAAM,KAAA,GAAQ,IAAA,EAAM,KAAA,KAAU,IAAA,KAAS,WAAW,OAAA,GAAU,MAAA,CAAA;AAC5D,gBAAA,MAAM,KAAA,GAAQ,KAAK,QAAA,EAAS;AAC5B,gBAAA,IAAI,KAAA,KAAU,MAAA,IAAU,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACvH,kBAAA,KAAA,mBAAQ,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,mBAAA,EAAqB,UAAU,QAAA,GAAW,gBAAA,GAAmB,aAAa,CAAA,EAAI,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,gBACjH;AAEA,gBAAA,uBACE,GAAA;AAAA,kBAAC,IAAA;AAAA,kBAAA;AAAA,oBAEC,SAAA,EAAW,EAAA;AAAA,sBACT,+CAAA;AAAA,sBACA,UAAU,OAAA,IAAW,YAAA;AAAA,sBACrB,UAAU,QAAA,IAAY,aAAA;AAAA,sBACtB,MAAA,IAAU;AAAA,qBACZ;AAAA,oBACA,OAAO,IAAA,EAAM,QAAA,IAAY,IAAA,EAAM,KAAA,IAAS,MAAM,QAAA,GAAW,EAAE,QAAA,EAAU,IAAA,EAAM,UAAU,KAAA,EAAO,IAAA,EAAM,OAAO,QAAA,EAAU,IAAA,EAAM,UAAS,GAAI,MAAA;AAAA,oBAErI,QAAA,EAAA;AAAA,mBAAA;AAAA,kBATI,IAAA,CAAK;AAAA,iBAUZ;AAAA,cAEJ,CAAC;AAAA,aAAA;AAAA,YA9CI,GAAA,CAAI;AAAA,WAgDZ,CAAA,EACH;AAAA,SAAA,EACF;AAAA;AAAA,KACF;AAAA,IAEC,SAAA,GAAY,CAAA,oBACX,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,6BAAA,EAA8B,QAAA,EAAA;AAAA,QAAA,OAAA;AAAA,QACtC,WAAA,GAAc,CAAA;AAAA,QAAE,MAAA;AAAA,QAAK;AAAA,OAAA,EAC7B,CAAA;AAAA,sBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,MAAM,gBAAA,CAAiB,CAAC,CAAA;AAAA,YACjC,UAAU,WAAA,KAAgB,CAAA;AAAA,YAC1B,KAAA,EAAM;AAAA;AAAA,SACR;AAAA,wBACA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,MAAM,gBAAA,CAAiB,WAAA,GAAc,CAAC,CAAA;AAAA,YAC/C,UAAU,WAAA,KAAgB,CAAA;AAAA,YAC1B,KAAA,EAAM;AAAA;AAAA,SACR;AAAA,QACC,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,CAAC,CAAA,EAAE,EAAG,CAAC,CAAA,EAAG,CAAA,KAAM;AACxD,UAAA,IAAI,IAAA;AACJ,UAAA,IAAI,aAAa,CAAA,EAAG;AAClB,YAAA,IAAA,GAAO,CAAA;AAAA,UACT,CAAA,MAAA,IAAW,cAAc,CAAA,EAAG;AAC1B,YAAA,IAAA,GAAO,CAAA;AAAA,UACT,CAAA,MAAA,IAAW,WAAA,GAAc,SAAA,GAAY,CAAA,EAAG;AACtC,YAAA,IAAA,GAAO,YAAY,CAAA,GAAI,CAAA;AAAA,UACzB,CAAA,MAAO;AACL,YAAA,IAAA,GAAO,cAAc,CAAA,GAAI,CAAA;AAAA,UAC3B;AACA,UAAA,uBACE,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,OAAA,EAAS,MAAM,gBAAA,CAAiB,IAAI,CAAA;AAAA,cACpC,QAAQ,IAAA,KAAS,WAAA;AAAA,cACjB,KAAA,EAAO,MAAA,CAAO,IAAA,GAAO,CAAC;AAAA,aAAA;AAAA,YAHjB;AAAA,WAIP;AAAA,QAEJ,CAAC,CAAA;AAAA,wBACD,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,MAAM,gBAAA,CAAiB,WAAA,GAAc,CAAC,CAAA;AAAA,YAC/C,QAAA,EAAU,eAAe,SAAA,GAAY,CAAA;AAAA,YACrC,KAAA,EAAM;AAAA;AAAA,SACR;AAAA,wBACA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,MAAM,gBAAA,CAAiB,SAAA,GAAY,CAAC,CAAA;AAAA,YAC7C,QAAA,EAAU,eAAe,SAAA,GAAY,CAAA;AAAA,YACrC,KAAA,EAAM;AAAA;AAAA;AACR,OAAA,EACF;AAAA,KAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAEA,SAAS,QAAA,CAAS;AAAA,EAChB,OAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,uBACE,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,OAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,4EAAA;AAAA,QACA,wEAAA;AAAA,QACA,0EAAA;AAAA,QACA,uDAAA;AAAA,QACA,SACI,gEAAA,GACA;AAAA,OACN;AAAA,MAEC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ","file":"data-grid.js","sourcesContent":["import { useState, useCallback, useMemo, type ReactNode } from \"react\";\nimport { useShellPreferences } from \"../lib/preferences\";\nimport {\n useReactTable,\n getCoreRowModel,\n getSortedRowModel,\n getPaginationRowModel,\n flexRender,\n type CellContext,\n type ColumnDef,\n type SortingState,\n} from \"@tanstack/react-table\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\nimport { Tooltip } from \"./Tooltip\";\nimport { useTextOverflow } from \"../lib/use-text-overflow\";\nimport { useBreakpoint, type BreakpointKey } from \"../lib/use-breakpoint\";\nimport { inferColumnKinds, type ColumnKind } from \"../lib/table-utils\";\nimport { CardValue } from \"../lib/card-cell\";\nimport { TableCardCtx } from \"../lib/surface-context\";\n\n/** Column meta for opt-in truncation. Set on ColumnDef.meta. */\nexport interface DataGridColumnMeta {\n /** true = single-line, or { lines: N } for multi-line clamp. */\n truncate?: boolean | { lines: number };\n /** CSS max-width for the column. */\n maxWidth?: string;\n /** CSS width for the column — sibling grids that share a column set line up when their columns carry the same widths (round 14). */\n width?: string;\n /** CSS min-width for the column. */\n minWidth?: string;\n /** Explicit column kind. When omitted the DataGrid infers it from data values. */\n kind?: ColumnKind;\n /** Horizontal alignment of the header and the cells; a block element (a Checkbox, a Button) is laid out with flex so it follows too (round 14). Default: numbers right, everything else left. */\n align?: \"left\" | \"center\" | \"right\";\n}\n\nfunction TruncCell({ children, lines }: { children: ReactNode; lines: number }) {\n const { ref, isTruncated } = useTextOverflow({ lines });\n const clampClass = lines === 1 ? \"truncate\" : `line-clamp-${lines}`;\n const cell = <span ref={ref} className={cn(clampClass, \"block\")}>{children}</span>;\n if (!isTruncated) return cell;\n return <Tooltip content={children}>{cell}</Tooltip>;\n}\n\nexport interface DataGridProps<T> {\n data: T[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- public API: columns may carry any value type\n columns: ColumnDef<T, any>[];\n pageSize?: number;\n editable?: boolean;\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void;\n /** Breakpoint at which the grid switches to card layout. Defaults to \"md\" (768px). */\n mobileBreakpoint?: BreakpointKey;\n className?: string;\n}\n\nexport function DataGrid<T>({\n data,\n columns,\n pageSize = 10,\n editable = false,\n onCellEdit,\n mobileBreakpoint: mobileBreakpointProp,\n className,\n}: DataGridProps<T>) {\n // Sprint 25.6 (B9): responsive.tableToCardsBreakpoint reaches the table through the shell; a prop wins; md outside any shell.\n const preferences = useShellPreferences();\n const mobileBreakpoint: BreakpointKey = mobileBreakpointProp ?? preferences.tableToCardsBreakpoint ?? \"md\";\n const isMobile = useBreakpoint(mobileBreakpoint);\n const [sorting, setSorting] = useState<SortingState>([]);\n const [editCell, setEditCell] = useState<{ row: number; col: string } | null>(null);\n const [editValue, setEditValue] = useState(\"\");\n\n /* ── Column kind inference ─────────────────────────────────────────── */\n const columnKeys = useMemo(() => columns.map((c) => c.id ?? (\"accessorKey\" in c ? String(c.accessorKey) : \"\")).filter(Boolean), [columns]);\n const inferredKinds = useMemo(\n () => inferColumnKinds(data as Record<string, unknown>[], columnKeys),\n [data, columnKeys],\n );\n const kindOf = useCallback(\n (colId: string, meta: DataGridColumnMeta | undefined) => meta?.kind ?? inferredKinds.get(colId),\n [inferredKinds],\n );\n\n const tableColumns = useMemo(() => {\n if (!editable) return columns;\n return columns.map((col) => ({\n ...col,\n cell: (info: CellContext<T, unknown>) => {\n const rowIdx = info.row.index;\n const colId = info.column.id;\n const isEditing = editCell?.row === rowIdx && editCell?.col === colId;\n\n if (isEditing) {\n return (\n <input\n autoFocus\n className={cn(\n \"w-full h-full bg-transparent text-sm text-[var(--ds-text-primary)]\",\n \"outline-none border-none px-0\",\n )}\n value={editValue}\n onChange={(e) => setEditValue(e.target.value)}\n onBlur={() => {\n onCellEdit?.(rowIdx, colId, editValue);\n setEditCell(null);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n onCellEdit?.(rowIdx, colId, editValue);\n setEditCell(null);\n } else if (e.key === \"Escape\") {\n setEditCell(null);\n }\n }}\n />\n );\n }\n\n const rendered = typeof col.cell === \"function\" ? col.cell(info) : info.getValue();\n return (\n <span\n onDoubleClick={() => {\n setEditCell({ row: rowIdx, col: colId });\n setEditValue(String(info.getValue() ?? \"\"));\n }}\n className=\"cursor-default\"\n >\n {rendered as React.ReactNode}\n </span>\n );\n },\n }));\n }, [columns, editable, editCell, editValue, onCellEdit]);\n\n // TanStack Table returns functions the React Compiler cannot memoise; the\n // compiler would skip this component, which is fine — the project does not\n // use it. The note is informational, not a defect.\n // eslint-disable-next-line react-hooks/incompatible-library -- TanStack Table is not compiler-compatible\n const table = useReactTable({\n data,\n columns: tableColumns,\n state: { sorting },\n onSortingChange: setSorting,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n initialState: { pagination: { pageSize } },\n });\n\n const handlePageChange = useCallback(\n (page: number) => table.setPageIndex(page),\n [table],\n );\n\n const pageCount = table.getPageCount();\n const currentPage = table.getState().pagination.pageIndex;\n\n if (isMobile) {\n return (\n <div className={cn(\"space-y-ds-3\", className)}>\n <TableCardCtx value={true}>\n <div className=\"flex flex-col gap-ds-3\">\n {table.getRowModel().rows.map((row) => (\n <div\n key={row.id}\n className={cn(\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]\",\n \"p-ds-4 space-y-ds-3\",\n )}\n >\n {row.getVisibleCells().map((cell) => (\n <div key={cell.id} className=\"flex justify-between gap-ds-2 text-sm\">\n <span className=\"shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider\">\n {typeof cell.column.columnDef.header === \"string\"\n ? cell.column.columnDef.header\n : cell.column.id}\n </span>\n <CardValue value={flexRender(cell.column.columnDef.cell, cell.getContext())} />\n </div>\n ))}\n </div>\n ))}\n </div>\n </TableCardCtx>\n\n {pageCount > 1 && (\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-[var(--ds-text-muted)]\">\n Page {currentPage + 1} of {pageCount}\n </span>\n <div className=\"flex items-center gap-ds-1\">\n <PagerBtn onClick={() => handlePageChange(currentPage - 1)} disabled={currentPage === 0} label=\"Prev\" />\n <PagerBtn onClick={() => handlePageChange(currentPage + 1)} disabled={currentPage >= pageCount - 1} label=\"Next\" />\n </div>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div className={cn(\"space-y-ds-3\", className)}>\n <div\n className={cn(\n \"w-full overflow-auto rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"shadow-[var(--ds-shadow-card)]\",\n \"bg-[var(--ds-bg-surface)]\",\n )}\n >\n <table className=\"w-full text-sm\">\n <thead className=\"bg-[var(--ds-bg-muted)]\">\n {table.getHeaderGroups().map((hg) => (\n <tr key={hg.id} className=\"border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]\">\n {hg.headers.map((header) => {\n const canSort = header.column.getCanSort();\n const sorted = header.column.getIsSorted();\n const meta = header.column.columnDef.meta as DataGridColumnMeta | undefined;\n const headerKind = kindOf(header.column.id, meta);\n const headerAlign = meta?.align ?? (headerKind === \"number\" ? \"right\" : \"left\");\n const shrink = (headerKind === \"number\" || headerKind === \"date\") && !meta?.maxWidth;\n return (\n <th\n key={header.id}\n className={cn(\n \"px-ds-4 py-ds-3 text-xs font-[var(--ds-weight-heading)] uppercase tracking-wider\",\n headerAlign === \"right\" ? \"text-right\" : headerAlign === \"center\" ? \"text-center\" : \"text-left\",\n shrink && \"w-px whitespace-nowrap\",\n \"text-[var(--ds-text-secondary)]\",\n canSort && \"cursor-pointer select-none hover:text-[var(--ds-text-primary)]\",\n )}\n style={meta?.maxWidth || meta?.width || meta?.minWidth ? { maxWidth: meta?.maxWidth, width: meta?.width, minWidth: meta?.minWidth } : undefined}\n onClick={canSort ? header.column.getToggleSortingHandler() : undefined}\n >\n <span className={cn(\"flex items-center gap-ds-1\", headerAlign === \"right\" && \"justify-end\", headerAlign === \"center\" && \"justify-center\")}>\n {flexRender(header.column.columnDef.header, header.getContext())}\n {canSort && (\n <span className=\"inline-flex flex-col -space-y-ds-1.5\">\n <Icon\n name=\"chevron-up\"\n size={10}\n className={sorted === \"asc\" ? \"text-[var(--ds-accent-primary)]\" : \"opacity-30\"}\n />\n <Icon\n name=\"chevron-down\"\n size={10}\n className={sorted === \"desc\" ? \"text-[var(--ds-accent-primary)]\" : \"opacity-30\"}\n />\n </span>\n )}\n </span>\n </th>\n );\n })}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n className={cn(\n \"border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] last:border-b-0\",\n \"hover:bg-[var(--ds-bg-muted)] transition-colors\",\n )}\n >\n {row.getVisibleCells().map((cell) => {\n const meta = cell.column.columnDef.meta as DataGridColumnMeta | undefined;\n const truncLines = meta?.truncate === true ? 1 : meta?.truncate ? meta.truncate.lines : 0;\n const kind = kindOf(cell.column.id, meta);\n const rendered = flexRender(cell.column.columnDef.cell, cell.getContext());\n\n const shrink = (kind === \"number\" || kind === \"date\") && !meta?.maxWidth;\n let inner: ReactNode;\n if (truncLines > 0) {\n inner = <TruncCell lines={truncLines}>{rendered}</TruncCell>;\n } else if (kind === \"email\") {\n inner = (\n <span className=\"max-w-[40ch] truncate inline-block align-bottom\" title={typeof cell.getValue() === \"string\" ? cell.getValue() as string : undefined}>\n {rendered}\n </span>\n );\n } else {\n inner = rendered;\n }\n // Round 14 (50.2): a centred or right-aligned column lays a block element out with flex — text-align moves inline content only.\n const align = meta?.align ?? (kind === \"number\" ? \"right\" : \"left\");\n const value = cell.getValue();\n if (align !== \"left\" && typeof value !== \"string\" && typeof value !== \"number\" && value !== null && value !== undefined) {\n inner = <div className={cn(\"flex items-center\", align === \"center\" ? \"justify-center\" : \"justify-end\")}>{inner}</div>;\n }\n\n return (\n <td\n key={cell.id}\n className={cn(\n \"px-ds-4 py-ds-3 text-[var(--ds-text-primary)]\",\n align === \"right\" && \"text-right\",\n align === \"center\" && \"text-center\",\n shrink && \"w-px whitespace-nowrap\",\n )}\n style={meta?.maxWidth || meta?.width || meta?.minWidth ? { maxWidth: meta?.maxWidth, width: meta?.width, minWidth: meta?.minWidth } : undefined}\n >\n {inner}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {pageCount > 1 && (\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-[var(--ds-text-muted)]\">\n Page {currentPage + 1} of {pageCount}\n </span>\n <div className=\"flex items-center gap-ds-1\">\n <PagerBtn\n onClick={() => handlePageChange(0)}\n disabled={currentPage === 0}\n label=\"First\"\n />\n <PagerBtn\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={currentPage === 0}\n label=\"Prev\"\n />\n {Array.from({ length: Math.min(pageCount, 5) }, (_, i) => {\n let page: number;\n if (pageCount <= 5) {\n page = i;\n } else if (currentPage < 3) {\n page = i;\n } else if (currentPage > pageCount - 4) {\n page = pageCount - 5 + i;\n } else {\n page = currentPage - 2 + i;\n }\n return (\n <PagerBtn\n key={page}\n onClick={() => handlePageChange(page)}\n active={page === currentPage}\n label={String(page + 1)}\n />\n );\n })}\n <PagerBtn\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={currentPage >= pageCount - 1}\n label=\"Next\"\n />\n <PagerBtn\n onClick={() => handlePageChange(pageCount - 1)}\n disabled={currentPage >= pageCount - 1}\n label=\"Last\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction PagerBtn({\n onClick,\n disabled,\n active,\n label,\n}: {\n onClick: () => void;\n disabled?: boolean;\n active?: boolean;\n label: string;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className={cn(\n \"h-8 min-w-[32px] px-ds-2 text-xs font-medium rounded-[var(--ds-radius-sm)]\",\n \"transition-colors duration-[var(--ds-transition-speed)] cursor-pointer\",\n \"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]\",\n \"disabled:opacity-disabled disabled:cursor-not-allowed\",\n active\n ? \"bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]\"\n : \"text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\",\n )}\n >\n {label}\n </button>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/components/DataGrid.tsx"],"names":[],"mappings":"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","file":"data-grid.js","sourcesContent":["import { useState, useCallback, useMemo, type ReactNode } from \"react\";\nimport { useShellPreferences } from \"../lib/preferences\";\nimport {\n useReactTable,\n getCoreRowModel,\n getSortedRowModel,\n getPaginationRowModel,\n flexRender,\n type CellContext,\n type ColumnDef,\n type SortingState,\n} from \"@tanstack/react-table\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\nimport { Tooltip } from \"./Tooltip\";\nimport { useTextOverflow } from \"../lib/use-text-overflow\";\nimport { useBreakpoint, type BreakpointKey } from \"../lib/use-breakpoint\";\nimport { inferColumnKinds, type ColumnKind } from \"../lib/table-utils\";\nimport { CardValue } from \"../lib/card-cell\";\nimport { TableCardCtx } from \"../lib/surface-context\";\n\n/** Column meta for opt-in truncation. Set on ColumnDef.meta. */\nexport interface DataGridColumnMeta {\n /** true = single-line, or { lines: N } for multi-line clamp. */\n truncate?: boolean | { lines: number };\n /** CSS max-width for the column. */\n maxWidth?: string;\n /** CSS width for the column — sibling grids that share a column set line up when their columns carry the same widths (round 14). */\n width?: string;\n /** CSS min-width for the column. */\n minWidth?: string;\n /** Explicit column kind. When omitted the DataGrid infers it from data values. */\n kind?: ColumnKind;\n /** Horizontal alignment of the header and the cells; a block element (a Checkbox, a Button) is laid out with flex so it follows too (round 14). Default: numbers right, everything else left. */\n align?: \"left\" | \"center\" | \"right\";\n}\n\nfunction TruncCell({ children, lines }: { children: ReactNode; lines: number }) {\n const { ref, isTruncated } = useTextOverflow({ lines });\n const clampClass = lines === 1 ? \"truncate\" : `line-clamp-${lines}`;\n const cell = <span ref={ref} className={cn(clampClass, \"block\")}>{children}</span>;\n if (!isTruncated) return cell;\n return <Tooltip content={children}>{cell}</Tooltip>;\n}\n\nexport interface DataGridProps<T> {\n data: T[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- public API: columns may carry any value type\n columns: ColumnDef<T, any>[];\n pageSize?: number;\n editable?: boolean;\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void;\n /** Breakpoint at which the grid switches to card layout. Defaults to \"md\" (768px). */\n mobileBreakpoint?: BreakpointKey;\n className?: string;\n}\n\nexport function DataGrid<T>({\n data,\n columns,\n pageSize = 10,\n editable = false,\n onCellEdit,\n mobileBreakpoint: mobileBreakpointProp,\n className,\n}: DataGridProps<T>) {\n // Sprint 25.6 (B9): responsive.tableToCardsBreakpoint reaches the table through the shell; a prop wins; md outside any shell.\n const preferences = useShellPreferences();\n const mobileBreakpoint: BreakpointKey = mobileBreakpointProp ?? preferences.tableToCardsBreakpoint ?? \"md\";\n const isMobile = useBreakpoint(mobileBreakpoint);\n const [sorting, setSorting] = useState<SortingState>([]);\n const [editCell, setEditCell] = useState<{ row: number; col: string } | null>(null);\n const [editValue, setEditValue] = useState(\"\");\n\n /* ── Column kind inference ─────────────────────────────────────────── */\n const columnKeys = useMemo(() => columns.map((c) => c.id ?? (\"accessorKey\" in c ? String(c.accessorKey) : \"\")).filter(Boolean), [columns]);\n const inferredKinds = useMemo(\n () => inferColumnKinds(data as Record<string, unknown>[], columnKeys),\n [data, columnKeys],\n );\n const kindOf = useCallback(\n (colId: string, meta: DataGridColumnMeta | undefined) => meta?.kind ?? inferredKinds.get(colId),\n [inferredKinds],\n );\n\n const tableColumns = useMemo(() => {\n if (!editable) return columns;\n return columns.map((col) => ({\n ...col,\n cell: (info: CellContext<T, unknown>) => {\n const rowIdx = info.row.index;\n const colId = info.column.id;\n const isEditing = editCell?.row === rowIdx && editCell?.col === colId;\n\n if (isEditing) {\n return (\n <input\n autoFocus\n className={cn(\n \"w-full h-full bg-transparent text-sm text-[var(--ds-text-primary)]\",\n \"outline-none border-none px-0\",\n )}\n value={editValue}\n onChange={(e) => setEditValue(e.target.value)}\n onBlur={() => {\n onCellEdit?.(rowIdx, colId, editValue);\n setEditCell(null);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n onCellEdit?.(rowIdx, colId, editValue);\n setEditCell(null);\n } else if (e.key === \"Escape\") {\n setEditCell(null);\n }\n }}\n />\n );\n }\n\n const rendered = typeof col.cell === \"function\" ? col.cell(info) : info.getValue();\n return (\n <span\n onDoubleClick={() => {\n setEditCell({ row: rowIdx, col: colId });\n setEditValue(String(info.getValue() ?? \"\"));\n }}\n className=\"cursor-default\"\n >\n {rendered as React.ReactNode}\n </span>\n );\n },\n }));\n }, [columns, editable, editCell, editValue, onCellEdit]);\n\n // TanStack Table returns functions the React Compiler cannot memoise; the\n // compiler would skip this component, which is fine — the project does not\n // use it. The note is informational, not a defect.\n // eslint-disable-next-line react-hooks/incompatible-library -- TanStack Table is not compiler-compatible\n const table = useReactTable({\n data,\n columns: tableColumns,\n state: { sorting },\n onSortingChange: setSorting,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n initialState: { pagination: { pageSize } },\n });\n\n const handlePageChange = useCallback(\n (page: number) => table.setPageIndex(page),\n [table],\n );\n\n const pageCount = table.getPageCount();\n const currentPage = table.getState().pagination.pageIndex;\n\n if (isMobile) {\n return (\n <div data-ds-list=\"\" className={cn(\"space-y-ds-3\", className)}>\n <TableCardCtx value={true}>\n <div className=\"flex flex-col gap-ds-3\">\n {table.getRowModel().rows.map((row) => (\n <div\n key={row.id}\n className={cn(\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]\",\n \"p-ds-4 space-y-ds-3\",\n )}\n >\n {row.getVisibleCells().map((cell) => (\n <div key={cell.id} className=\"flex justify-between gap-ds-2 text-sm\">\n <span className=\"shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider\">\n {typeof cell.column.columnDef.header === \"string\"\n ? cell.column.columnDef.header\n : cell.column.id}\n </span>\n <CardValue value={flexRender(cell.column.columnDef.cell, cell.getContext())} />\n </div>\n ))}\n </div>\n ))}\n </div>\n </TableCardCtx>\n\n {pageCount > 1 && (\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-[var(--ds-text-muted)]\">\n Page {currentPage + 1} of {pageCount}\n </span>\n <div className=\"flex items-center gap-ds-1\">\n <PagerBtn onClick={() => handlePageChange(currentPage - 1)} disabled={currentPage === 0} label=\"Prev\" />\n <PagerBtn onClick={() => handlePageChange(currentPage + 1)} disabled={currentPage >= pageCount - 1} label=\"Next\" />\n </div>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div data-ds-list=\"\" className={cn(\"space-y-ds-3\", className)}>\n <div\n className={cn(\n \"w-full overflow-auto rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"shadow-[var(--ds-shadow-card)]\",\n \"bg-[var(--ds-bg-surface)]\",\n )}\n >\n <table className=\"w-full text-sm\">\n <thead className=\"bg-[var(--ds-bg-muted)]\">\n {table.getHeaderGroups().map((hg) => (\n <tr key={hg.id} className=\"border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]\">\n {hg.headers.map((header) => {\n const canSort = header.column.getCanSort();\n const sorted = header.column.getIsSorted();\n const meta = header.column.columnDef.meta as DataGridColumnMeta | undefined;\n const headerKind = kindOf(header.column.id, meta);\n const headerAlign = meta?.align ?? (headerKind === \"number\" ? \"right\" : \"left\");\n const shrink = (headerKind === \"number\" || headerKind === \"date\") && !meta?.maxWidth;\n return (\n <th\n key={header.id}\n className={cn(\n \"px-ds-4 py-ds-3 text-xs font-[var(--ds-weight-heading)] uppercase tracking-wider\",\n headerAlign === \"right\" ? \"text-right\" : headerAlign === \"center\" ? \"text-center\" : \"text-left\",\n shrink && \"w-px whitespace-nowrap\",\n \"text-[var(--ds-text-secondary)]\",\n canSort && \"cursor-pointer select-none hover:text-[var(--ds-text-primary)]\",\n )}\n style={meta?.maxWidth || meta?.width || meta?.minWidth ? { maxWidth: meta?.maxWidth, width: meta?.width, minWidth: meta?.minWidth } : undefined}\n onClick={canSort ? header.column.getToggleSortingHandler() : undefined}\n >\n <span className={cn(\"flex items-center gap-ds-1\", headerAlign === \"right\" && \"justify-end\", headerAlign === \"center\" && \"justify-center\")}>\n {flexRender(header.column.columnDef.header, header.getContext())}\n {canSort && (\n <span className=\"inline-flex flex-col -space-y-ds-1.5\">\n <Icon\n name=\"chevron-up\"\n size={10}\n className={sorted === \"asc\" ? \"text-[var(--ds-accent-primary)]\" : \"opacity-30\"}\n />\n <Icon\n name=\"chevron-down\"\n size={10}\n className={sorted === \"desc\" ? \"text-[var(--ds-accent-primary)]\" : \"opacity-30\"}\n />\n </span>\n )}\n </span>\n </th>\n );\n })}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n className={cn(\n \"border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] last:border-b-0\",\n \"hover:bg-[var(--ds-bg-muted)] transition-colors\",\n )}\n >\n {row.getVisibleCells().map((cell) => {\n const meta = cell.column.columnDef.meta as DataGridColumnMeta | undefined;\n const truncLines = meta?.truncate === true ? 1 : meta?.truncate ? meta.truncate.lines : 0;\n const kind = kindOf(cell.column.id, meta);\n const rendered = flexRender(cell.column.columnDef.cell, cell.getContext());\n\n const shrink = (kind === \"number\" || kind === \"date\") && !meta?.maxWidth;\n let inner: ReactNode;\n if (truncLines > 0) {\n inner = <TruncCell lines={truncLines}>{rendered}</TruncCell>;\n } else if (kind === \"email\") {\n inner = (\n <span className=\"max-w-[40ch] truncate inline-block align-bottom\" title={typeof cell.getValue() === \"string\" ? cell.getValue() as string : undefined}>\n {rendered}\n </span>\n );\n } else {\n inner = rendered;\n }\n // Round 14 (50.2): a centred or right-aligned column lays a block element out with flex — text-align moves inline content only.\n const align = meta?.align ?? (kind === \"number\" ? \"right\" : \"left\");\n const value = cell.getValue();\n if (align !== \"left\" && typeof value !== \"string\" && typeof value !== \"number\" && value !== null && value !== undefined) {\n inner = <div className={cn(\"flex items-center\", align === \"center\" ? \"justify-center\" : \"justify-end\")}>{inner}</div>;\n }\n\n return (\n <td\n key={cell.id}\n className={cn(\n \"px-ds-4 py-ds-3 text-[var(--ds-text-primary)]\",\n align === \"right\" && \"text-right\",\n align === \"center\" && \"text-center\",\n shrink && \"w-px whitespace-nowrap\",\n )}\n style={meta?.maxWidth || meta?.width || meta?.minWidth ? { maxWidth: meta?.maxWidth, width: meta?.width, minWidth: meta?.minWidth } : undefined}\n >\n {inner}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {pageCount > 1 && (\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-[var(--ds-text-muted)]\">\n Page {currentPage + 1} of {pageCount}\n </span>\n <div className=\"flex items-center gap-ds-1\">\n <PagerBtn\n onClick={() => handlePageChange(0)}\n disabled={currentPage === 0}\n label=\"First\"\n />\n <PagerBtn\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={currentPage === 0}\n label=\"Prev\"\n />\n {Array.from({ length: Math.min(pageCount, 5) }, (_, i) => {\n let page: number;\n if (pageCount <= 5) {\n page = i;\n } else if (currentPage < 3) {\n page = i;\n } else if (currentPage > pageCount - 4) {\n page = pageCount - 5 + i;\n } else {\n page = currentPage - 2 + i;\n }\n return (\n <PagerBtn\n key={page}\n onClick={() => handlePageChange(page)}\n active={page === currentPage}\n label={String(page + 1)}\n />\n );\n })}\n <PagerBtn\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={currentPage >= pageCount - 1}\n label=\"Next\"\n />\n <PagerBtn\n onClick={() => handlePageChange(pageCount - 1)}\n disabled={currentPage >= pageCount - 1}\n label=\"Last\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction PagerBtn({\n onClick,\n disabled,\n active,\n label,\n}: {\n onClick: () => void;\n disabled?: boolean;\n active?: boolean;\n label: string;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className={cn(\n \"h-8 min-w-[32px] px-ds-2 text-xs font-medium rounded-[var(--ds-radius-sm)]\",\n \"transition-colors duration-[var(--ds-transition-speed)] cursor-pointer\",\n \"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]\",\n \"disabled:opacity-disabled disabled:cursor-not-allowed\",\n active\n ? \"bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]\"\n : \"text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\",\n )}\n >\n {label}\n </button>\n );\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -434,10 +434,10 @@ interface FormWrapperProps {
|
|
|
434
434
|
actions?: ReactNode;
|
|
435
435
|
actionsAlign?: "start" | "end";
|
|
436
436
|
/**
|
|
437
|
-
* Renders a secondary Cancel before the actions. Inside a Drawer,
|
|
438
|
-
* unsaved-changes check — the question Escape and the close control ask while the form is dirty —
|
|
439
|
-
*
|
|
440
|
-
* question (round 21
|
|
437
|
+
* Renders a secondary Cancel before the actions. Inside a Drawer, a Dialog, or a Sheet given `dirty`, it closes the
|
|
438
|
+
* overlay through its unsaved-changes check — the question Escape and the close control ask while the form is dirty —
|
|
439
|
+
* and then this function runs, unless it is the overlay's own onClose; it does not run when the user keeps editing.
|
|
440
|
+
* Anywhere else this function runs. Never hand-wire a Cancel to the overlay's close: it skips the question (round 21).
|
|
441
441
|
*/
|
|
442
442
|
onCancel?: () => void;
|
|
443
443
|
/** The Cancel button's label (default "Cancel"). */
|
|
@@ -864,12 +864,15 @@ interface TableToolbarProps {
|
|
|
864
864
|
* The list is paged: pass the `usePagination` result and the count says which rows are showing — "Showing 51–100 of
|
|
865
865
|
* 200 events" — instead of a bare total the table does not show (round 21, the owner's call); one page reads
|
|
866
866
|
* "12 events". Under tabs that carry the counts, pass the pager alone (no resultCount): the line then shows only the
|
|
867
|
-
* range, and only while the list spans pages — the tabs already say how many (gs:count-duplicated-by-tabs).
|
|
867
|
+
* range, and only while the list spans pages — the tabs already say how many (gs:count-duplicated-by-tabs). A list that
|
|
868
|
+
* grows (load more, loading on scroll) reads "Showing 40 of 120 members" until every row is shown (round 22).
|
|
868
869
|
*/
|
|
869
870
|
pagination?: {
|
|
870
871
|
page: number;
|
|
871
872
|
pageSize: number;
|
|
872
873
|
totalItems?: number;
|
|
874
|
+
style?: "pagination" | "load-more" | "infinite-scroll";
|
|
875
|
+
shown?: number;
|
|
873
876
|
};
|
|
874
877
|
/** Utility actions on the right — an overflow DropdownMenu, an export button. Primary actions belong in the PageHeader. */
|
|
875
878
|
actions?: ReactNode;
|
|
@@ -892,6 +895,7 @@ interface TimelineItem {
|
|
|
892
895
|
title: string;
|
|
893
896
|
description?: string;
|
|
894
897
|
timestamp?: string;
|
|
898
|
+
/** Takes the dot's place — the actor's Avatar (size="sm") on an activity feed, or an Icon. `variant` colours the dot only. */
|
|
895
899
|
icon?: ReactNode;
|
|
896
900
|
variant?: "default" | "success" | "warning" | "error";
|
|
897
901
|
}
|
|
@@ -1478,9 +1482,21 @@ interface PaginationProps {
|
|
|
1478
1482
|
pageSize?: number;
|
|
1479
1483
|
pageSizeOptions?: number[];
|
|
1480
1484
|
onPageSizeChange?: (size: number) => void;
|
|
1485
|
+
/**
|
|
1486
|
+
* How the list shows more (round 22): page numbers, a Load more button, or loading as the user scrolls (with the
|
|
1487
|
+
* button kept for keyboard users). `usePagination` passes the project's dataDisplay.paginationStyle here in
|
|
1488
|
+
* `pager.props`, so `<Pagination {...pager.props} />` follows the project's style with nothing written on the page.
|
|
1489
|
+
*/
|
|
1490
|
+
mode?: "pagination" | "load-more" | "infinite-scroll";
|
|
1491
|
+
/** Rows left to load (load-more and infinite-scroll). */
|
|
1492
|
+
hasMore?: boolean;
|
|
1493
|
+
/** Load the next rows (load-more and infinite-scroll). */
|
|
1494
|
+
onLoadMore?: () => void;
|
|
1495
|
+
/** The Load more button's label (default "Load more"). */
|
|
1496
|
+
loadMoreLabel?: string;
|
|
1481
1497
|
className?: string;
|
|
1482
1498
|
}
|
|
1483
|
-
declare function Pagination(
|
|
1499
|
+
declare function Pagination(props: PaginationProps): react_jsx_runtime.JSX.Element;
|
|
1484
1500
|
|
|
1485
1501
|
interface Step {
|
|
1486
1502
|
label: string;
|
|
@@ -1953,6 +1969,14 @@ interface SheetProps {
|
|
|
1953
1969
|
footer?: ReactNode;
|
|
1954
1970
|
/** A strip between the content and the footer (the Drawer's unsaved-changes question). */
|
|
1955
1971
|
confirm?: ReactNode;
|
|
1972
|
+
/**
|
|
1973
|
+
* The content has unsaved changes: every close path — Escape, the backdrop, dragging it down, the close control and a
|
|
1974
|
+
* FormWrapper's Cancel — asks before discarding them, inside the sheet, as a Drawer and a Dialog do (the review of
|
|
1975
|
+
* 23 September: a sheet holding a form threw it away with no question).
|
|
1976
|
+
*/
|
|
1977
|
+
dirty?: boolean;
|
|
1978
|
+
/** Runs when the user discards unsaved changes, before onClose (reset the form here). */
|
|
1979
|
+
onDiscard?: () => void;
|
|
1956
1980
|
/** Heights the sheet snaps to, as fractions of the viewport (or container). Default [0.5, 0.92]. */
|
|
1957
1981
|
snapPoints?: number[];
|
|
1958
1982
|
/** Render inside this element (absolute positioning, no body scroll lock) instead of document.body. */
|
|
@@ -1966,7 +1990,7 @@ interface SheetProps {
|
|
|
1966
1990
|
/** id of the element that names the dialog when no title is rendered. */
|
|
1967
1991
|
labelledBy?: string;
|
|
1968
1992
|
}
|
|
1969
|
-
declare function Sheet({ open, onClose, title, children, footer, confirm, snapPoints, container, flush, keepMounted, id, labelledBy }: SheetProps): react.ReactPortal | null;
|
|
1993
|
+
declare function Sheet({ open, onClose: onCloseProp, title, children, footer, confirm, dirty, onDiscard, snapPoints, container, flush, keepMounted, id, labelledBy }: SheetProps): react.ReactPortal | null;
|
|
1970
1994
|
|
|
1971
1995
|
interface Notification {
|
|
1972
1996
|
id: string;
|
|
@@ -2165,6 +2189,8 @@ type PreferenceBreakpoint = "sm" | "md" | "lg";
|
|
|
2165
2189
|
type PreferenceEmptyStyle = "illustration-cta" | "text-cta" | "redirect";
|
|
2166
2190
|
type PreferenceLoadingStyle = "skeleton" | "spinner" | "progress-bar";
|
|
2167
2191
|
type PreferenceDestructiveMode = "dialog" | "undo";
|
|
2192
|
+
/** dataDisplay.paginationStyle — how a long list shows more: page numbers, a Load more button, or loading as the user scrolls. */
|
|
2193
|
+
type PreferencePaginationStyle = "pagination" | "load-more" | "infinite-scroll";
|
|
2168
2194
|
interface AppShellPreferences {
|
|
2169
2195
|
/** forms.validationTiming — when a field first shows its error. */
|
|
2170
2196
|
validationTiming?: PreferenceValidationTiming;
|
|
@@ -2175,6 +2201,8 @@ interface AppShellPreferences {
|
|
|
2175
2201
|
};
|
|
2176
2202
|
/** dataDisplay.itemsPerPage — the page size of a paged or load-more list. */
|
|
2177
2203
|
itemsPerPage?: number;
|
|
2204
|
+
/** dataDisplay.paginationStyle — page numbers, a Load more button, or loading on scroll; usePagination and Pagination follow it (round 22). */
|
|
2205
|
+
paginationStyle?: PreferencePaginationStyle;
|
|
2178
2206
|
/** responsive.tableToCardsBreakpoint — below this width a Table becomes stacked cards. */
|
|
2179
2207
|
tableToCardsBreakpoint?: PreferenceBreakpoint;
|
|
2180
2208
|
/** emptyStates.emptyStyle — illustration with an action, text with an action, or redirect to creation. */
|
|
@@ -2199,6 +2227,7 @@ interface ResolvedPreferences {
|
|
|
2199
2227
|
placement: "auto" | "inline";
|
|
2200
2228
|
};
|
|
2201
2229
|
itemsPerPage: number;
|
|
2230
|
+
paginationStyle: PreferencePaginationStyle;
|
|
2202
2231
|
tableToCardsBreakpoint: PreferenceBreakpoint;
|
|
2203
2232
|
emptyStyle: PreferenceEmptyStyle;
|
|
2204
2233
|
loadingStyle: PreferenceLoadingStyle;
|
|
@@ -2320,12 +2349,14 @@ interface AppShellProps {
|
|
|
2320
2349
|
declare const AppShell: react.ForwardRefExoticComponent<AppShellProps & react.RefAttributes<HTMLDivElement>>;
|
|
2321
2350
|
|
|
2322
2351
|
/**
|
|
2323
|
-
* A
|
|
2324
|
-
*
|
|
2325
|
-
*
|
|
2352
|
+
* A long list in one hook (round 21; all three list styles since round 22). The page size and the list style are the
|
|
2353
|
+
* project's `dataDisplay.itemsPerPage` and `dataDisplay.paginationStyle`, read from the shell, so a mid-build
|
|
2354
|
+
* `update_rule` on either reaches every list with no page edited. The page gets what to show, the props for
|
|
2355
|
+
* `<Pagination>` — page numbers, a Load more button or loading on scroll, whichever the project's style is — and the
|
|
2356
|
+
* numbers the count line needs ("Showing 51–100 of 200 events", or "Showing 40 of 120 members" while a list grows).
|
|
2326
2357
|
*
|
|
2327
|
-
* Run 58
|
|
2328
|
-
*
|
|
2358
|
+
* Run 58 hand-wrote the paging; runs 59 and 60 hand-wrote load-more and scroll loading — an IntersectionObserver, a
|
|
2359
|
+
* visible count and a page size copied in as a constant, twice in one app — because the library had no way to.
|
|
2329
2360
|
*
|
|
2330
2361
|
* const pager = usePagination(sortedEvents, { resetOn: [sortKey, sortDir] })
|
|
2331
2362
|
* <TableToolbar resultCount={sortedEvents.length} resultNoun={["event", "events"]} pagination={pager} />
|
|
@@ -2333,25 +2364,36 @@ declare const AppShell: react.ForwardRefExoticComponent<AppShellProps & react.Re
|
|
|
2333
2364
|
* <Pagination {...pager.props} />
|
|
2334
2365
|
*/
|
|
2335
2366
|
interface Pager<T> {
|
|
2336
|
-
/**
|
|
2367
|
+
/** The list style this list follows: the project's, unless `style` was passed. */
|
|
2368
|
+
style: PreferencePaginationStyle;
|
|
2369
|
+
/** What to show: the current page's rows, or every row loaded so far on a list that grows. */
|
|
2337
2370
|
items: T[];
|
|
2338
|
-
/** The current page, from 1. */
|
|
2371
|
+
/** The current page, from 1; on a growing list, how many pages are loaded. */
|
|
2339
2372
|
page: number;
|
|
2340
2373
|
pageSize: number;
|
|
2341
2374
|
totalItems: number;
|
|
2342
2375
|
totalPages: number;
|
|
2343
|
-
/** The first and last
|
|
2376
|
+
/** The first and last row numbers on screen, from 1 ("Showing 51–100"); [0, 0] for an empty list. */
|
|
2344
2377
|
range: [number, number];
|
|
2378
|
+
/** How many rows are on screen. */
|
|
2379
|
+
shown: number;
|
|
2380
|
+
/** Rows left to show: a next page, or more to load. */
|
|
2381
|
+
hasMore: boolean;
|
|
2382
|
+
/** The next page, or the next `pageSize` rows on a growing list. */
|
|
2383
|
+
loadMore: () => void;
|
|
2345
2384
|
setPage: (page: number) => void;
|
|
2346
2385
|
/** A page-size selector's choice; it wins over the project's page size and starts again at page 1. */
|
|
2347
2386
|
setPageSize: (size: number) => void;
|
|
2348
|
-
/** Spread onto <Pagination
|
|
2387
|
+
/** Spread onto <Pagination>: it renders page numbers, a Load more button or the scroll trigger, as `style` says. */
|
|
2349
2388
|
props: {
|
|
2350
2389
|
currentPage: number;
|
|
2351
2390
|
totalPages: number;
|
|
2352
2391
|
onPageChange: (page: number) => void;
|
|
2353
2392
|
pageSize: number;
|
|
2354
2393
|
onPageSizeChange: (size: number) => void;
|
|
2394
|
+
mode: PreferencePaginationStyle;
|
|
2395
|
+
hasMore: boolean;
|
|
2396
|
+
onLoadMore: () => void;
|
|
2355
2397
|
};
|
|
2356
2398
|
}
|
|
2357
2399
|
interface PaginationOptions {
|
|
@@ -2359,6 +2401,12 @@ interface PaginationOptions {
|
|
|
2359
2401
|
pageSize?: number;
|
|
2360
2402
|
/** Values that start the list again at page 1 when they change — the sort column and direction, a search query. */
|
|
2361
2403
|
resetOn?: unknown;
|
|
2404
|
+
/**
|
|
2405
|
+
* A list style for this list only, over the project's. Leave it out: the project's style is the rule. Passing one that
|
|
2406
|
+
* differs is overriding a rule in force — ask the user first, and put `// @gridsmith-override
|
|
2407
|
+
* dataDisplay.paginationStyle: <their reason>` above the call.
|
|
2408
|
+
*/
|
|
2409
|
+
style?: PreferencePaginationStyle;
|
|
2362
2410
|
}
|
|
2363
2411
|
declare function usePagination<T>(list: readonly T[], options?: PaginationOptions): Pager<T>;
|
|
2364
2412
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useAppShell, ControlSizeContext, Button, Spinner, OverlayCloseCtx, DrawerFooterCtx, useCompact, useElementWidth, Sheet, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, useDirtyGuard, DiscardConfirm, defaultMaxWidth } from './chunk-
|
|
2
|
-
export { AppShell, Button, ButtonSizeContext, ControlSizeContext, Drawer, Sheet, SkipLink, Spinner, useAppShell } from './chunk-
|
|
1
|
+
import { useAppShell, ControlSizeContext, Button, Spinner, OverlayCloseCtx, DrawerFooterCtx, useCompact, useElementWidth, Sheet, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, useDirtyGuard, DiscardConfirm, defaultMaxWidth } from './chunk-JSQPVRHQ.js';
|
|
2
|
+
export { AppShell, Button, ButtonSizeContext, ControlSizeContext, Drawer, Sheet, SkipLink, Spinner, useAppShell } from './chunk-JSQPVRHQ.js';
|
|
3
3
|
import { Skeleton } from './chunk-M3AARGLI.js';
|
|
4
4
|
export { Skeleton } from './chunk-M3AARGLI.js';
|
|
5
5
|
import { useOverlayLayer, useCloseOnFocusOut, focusInitial, rovingTabStop, OVERLAY_CLOSE_ATTR, useNonModalDialog, useFocusTrap } from './chunk-NHQCMOAN.js';
|
|
@@ -8,8 +8,8 @@ export { CodeBlock, Divider, Link } from './chunk-QJBCZ7BR.js';
|
|
|
8
8
|
import { Badge } from './chunk-U2JT37GJ.js';
|
|
9
9
|
export { Badge } from './chunk-U2JT37GJ.js';
|
|
10
10
|
import { inferColumnKinds, CardValue } from './chunk-CR2KF73R.js';
|
|
11
|
-
import { SplitPaneCtx, useShellPreferences, TableCardCtx, PREFERENCE_HOUSE_DEFAULTS, preferenceActionKey } from './chunk-
|
|
12
|
-
export { PreferencesContext, preferenceActionKey, usePreferences } from './chunk-
|
|
11
|
+
import { SplitPaneCtx, useShellPreferences, TableCardCtx, PREFERENCE_HOUSE_DEFAULTS, preferenceActionKey } from './chunk-TKVTZWBN.js';
|
|
12
|
+
export { PreferencesContext, preferenceActionKey, usePreferences } from './chunk-TKVTZWBN.js';
|
|
13
13
|
import { useBreakpoint } from './chunk-CRQ6KCRD.js';
|
|
14
14
|
export { BreakpointWidthProvider, useBreakpoint } from './chunk-CRQ6KCRD.js';
|
|
15
15
|
import { useTextOverflow, Tooltip, usePosition } from './chunk-IYD6ZDM2.js';
|
|
@@ -3866,7 +3866,7 @@ function FormWrapper({ onSubmit, validationMode: validationModeProp, children, a
|
|
|
3866
3866
|
const overlayClose = useContext(OverlayCloseCtx);
|
|
3867
3867
|
const actions = useMemo(() => {
|
|
3868
3868
|
if (!onCancel) return actionsProp;
|
|
3869
|
-
const cancel = /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", onClick: () =>
|
|
3869
|
+
const cancel = /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", onClick: () => overlayClose ? overlayClose(onCancel) : onCancel(), children: cancelLabel }, "gs-form-cancel");
|
|
3870
3870
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3871
3871
|
cancel,
|
|
3872
3872
|
actionsProp
|
|
@@ -5268,12 +5268,12 @@ function Table({
|
|
|
5268
5268
|
const isMobile = useBreakpoint(mobileBreakpoint);
|
|
5269
5269
|
if (isMobile) {
|
|
5270
5270
|
if (loading) {
|
|
5271
|
-
return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center justify-center py-ds-10", className), children: /* @__PURE__ */ jsx(Spinner, { label: "Loading table data" }) });
|
|
5271
|
+
return /* @__PURE__ */ jsx("div", { ref, "data-ds-list": "", className: cn("flex items-center justify-center py-ds-10", className), children: /* @__PURE__ */ jsx(Spinner, { label: "Loading table data" }) });
|
|
5272
5272
|
}
|
|
5273
5273
|
if (data.length === 0 && emptyState) {
|
|
5274
|
-
return /* @__PURE__ */ jsx("div", { ref, className: cn("py-ds-10 text-center text-sm text-[var(--ds-text-muted)]", className), children: emptyState });
|
|
5274
|
+
return /* @__PURE__ */ jsx("div", { ref, "data-ds-list": "", className: cn("py-ds-10 text-center text-sm text-[var(--ds-text-muted)]", className), children: emptyState });
|
|
5275
5275
|
}
|
|
5276
|
-
return /* @__PURE__ */ jsx(TableCardCtx, { value: true, children: /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-ds-3 overflow-y-auto", className), children: sortedWithIndices.map(({ row, originalIdx }, i) => {
|
|
5276
|
+
return /* @__PURE__ */ jsx(TableCardCtx, { value: true, children: /* @__PURE__ */ jsx("div", { ref, "data-ds-list": "", className: cn("flex flex-col gap-ds-3 overflow-y-auto", className), children: sortedWithIndices.map(({ row, originalIdx }, i) => {
|
|
5277
5277
|
const isSelected = selectedSet.has(originalIdx);
|
|
5278
5278
|
return /* @__PURE__ */ jsxs(
|
|
5279
5279
|
"div",
|
|
@@ -5311,6 +5311,7 @@ function Table({
|
|
|
5311
5311
|
"div",
|
|
5312
5312
|
{
|
|
5313
5313
|
ref,
|
|
5314
|
+
"data-ds-list": "",
|
|
5314
5315
|
className: cn(
|
|
5315
5316
|
"w-full overflow-x-auto",
|
|
5316
5317
|
"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
|
|
@@ -7328,9 +7329,11 @@ function TableToolbar({
|
|
|
7328
7329
|
const searchFills = inPane || !primaryFilter && !filters && !actions;
|
|
7329
7330
|
const hasControls = !!(search || primaryFilter || filters || actions);
|
|
7330
7331
|
const noun = (n) => n === 1 ? resultNoun[0] : resultNoun[1];
|
|
7331
|
-
const total =
|
|
7332
|
+
const total = pagination?.totalItems ?? resultCount;
|
|
7333
|
+
const grows = !!pagination?.style && pagination.style !== "pagination";
|
|
7334
|
+
const shown = grows ? Math.min(pagination.shown ?? pagination.page * pagination.pageSize, total ?? Infinity) : 0;
|
|
7332
7335
|
const paged = total !== void 0 && !!pagination && pagination.pageSize > 0 && total > pagination.pageSize;
|
|
7333
|
-
const countText = total === void 0 ? null : paged ? `Showing ${Math.min((pagination.page - 1) * pagination.pageSize + 1, total)}\u2013${Math.min(pagination.page * pagination.pageSize, total)} of ${total} ${noun(total)}` : resultCount !== void 0 ? `${
|
|
7336
|
+
const countText = total === void 0 ? null : grows ? shown < total ? `Showing ${shown} of ${total} ${noun(total)}` : resultCount !== void 0 ? `${total} ${noun(total)}` : null : paged ? `Showing ${Math.min((pagination.page - 1) * pagination.pageSize + 1, total)}\u2013${Math.min(pagination.page * pagination.pageSize, total)} of ${total} ${noun(total)}` : resultCount !== void 0 ? `${total} ${noun(total)}` : null;
|
|
7334
7337
|
if (!hasControls && countText === null && !hasChips) return null;
|
|
7335
7338
|
return /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-ds-3 min-w-0 mb-ds-3 last:mb-0", className), "data-table-toolbar": "", children: [
|
|
7336
7339
|
hasControls && /* @__PURE__ */ jsxs("div", { ref: rowRef, className: "flex items-center gap-ds-2 flex-wrap", children: [
|
|
@@ -7393,6 +7396,22 @@ function TableToolbar({
|
|
|
7393
7396
|
] })
|
|
7394
7397
|
] }) });
|
|
7395
7398
|
}
|
|
7399
|
+
var ICON_TEXT_OFFSET = "calc((2rem - 1.25rem) / 2)";
|
|
7400
|
+
function Marker({ item, vertical }) {
|
|
7401
|
+
if (item.icon) {
|
|
7402
|
+
return /* @__PURE__ */ jsx("div", { "data-timeline-icon": "", className: "shrink-0 w-8 h-8 flex items-center justify-center *:max-w-8 *:max-h-8", children: item.icon });
|
|
7403
|
+
}
|
|
7404
|
+
return /* @__PURE__ */ jsx(
|
|
7405
|
+
"div",
|
|
7406
|
+
{
|
|
7407
|
+
className: cn(
|
|
7408
|
+
"shrink-0 w-3 h-3 rounded-[var(--ds-radius-full)]",
|
|
7409
|
+
vertical && "mt-ds-1",
|
|
7410
|
+
dotVariant[item.variant ?? "default"]
|
|
7411
|
+
)
|
|
7412
|
+
}
|
|
7413
|
+
);
|
|
7414
|
+
}
|
|
7396
7415
|
var dotVariant = {
|
|
7397
7416
|
default: "bg-[var(--ds-accent-primary)] shadow-[0_0_0_3px_var(--ds-accent-primary)]/20",
|
|
7398
7417
|
success: "bg-[var(--ds-status-success)] shadow-[0_0_0_3px_var(--ds-status-success)]/20",
|
|
@@ -7441,15 +7460,7 @@ function HorizontalLayout({ items, minItemWidth, className }) {
|
|
|
7441
7460
|
)
|
|
7442
7461
|
}
|
|
7443
7462
|
),
|
|
7444
|
-
/* @__PURE__ */ jsx(
|
|
7445
|
-
"div",
|
|
7446
|
-
{
|
|
7447
|
-
className: cn(
|
|
7448
|
-
"shrink-0 w-3 h-3 rounded-[var(--ds-radius-full)]",
|
|
7449
|
-
dotVariant[item.variant ?? "default"]
|
|
7450
|
-
)
|
|
7451
|
-
}
|
|
7452
|
-
),
|
|
7463
|
+
/* @__PURE__ */ jsx(Marker, { item, vertical: false }),
|
|
7453
7464
|
/* @__PURE__ */ jsx(
|
|
7454
7465
|
"div",
|
|
7455
7466
|
{
|
|
@@ -7471,18 +7482,10 @@ function HorizontalLayout({ items, minItemWidth, className }) {
|
|
|
7471
7482
|
function VerticalLayout({ items, className }) {
|
|
7472
7483
|
return /* @__PURE__ */ jsx("div", { className: cn("relative", className), children: items.map((item, i) => /* @__PURE__ */ jsxs("div", { className: "flex gap-ds-4", children: [
|
|
7473
7484
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
|
|
7474
|
-
/* @__PURE__ */ jsx(
|
|
7475
|
-
"div",
|
|
7476
|
-
{
|
|
7477
|
-
className: cn(
|
|
7478
|
-
"shrink-0 w-3 h-3 rounded-[var(--ds-radius-full)] mt-ds-1",
|
|
7479
|
-
dotVariant[item.variant ?? "default"]
|
|
7480
|
-
)
|
|
7481
|
-
}
|
|
7482
|
-
),
|
|
7485
|
+
/* @__PURE__ */ jsx(Marker, { item, vertical: true }),
|
|
7483
7486
|
i < items.length - 1 && /* @__PURE__ */ jsx("div", { className: "w-[2px] flex-1 bg-[var(--ds-border-subtle)] my-ds-1" })
|
|
7484
7487
|
] }),
|
|
7485
|
-
/* @__PURE__ */ jsxs("div", { className: cn("pb-ds-6", i === items.length - 1 && "pb-0"), children: [
|
|
7488
|
+
/* @__PURE__ */ jsxs("div", { className: cn("pb-ds-6 min-w-0", i === items.length - 1 && "pb-0"), style: item.icon ? { paddingTop: ICON_TEXT_OFFSET } : void 0, children: [
|
|
7486
7489
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: item.title }),
|
|
7487
7490
|
item.description && /* @__PURE__ */ jsx(ExpandableDescription, { children: item.description }),
|
|
7488
7491
|
item.timestamp && /* @__PURE__ */ jsx("p", { className: "text-2xs text-[var(--ds-text-muted)] mt-ds-0.5 tabular-nums", children: item.timestamp })
|
|
@@ -7499,7 +7502,7 @@ function Timeline({ items, orientation = "vertical", minItemWidth = 200, classNa
|
|
|
7499
7502
|
}, [ref]);
|
|
7500
7503
|
const fits = width === 0 || width >= items.length * minItemWidth;
|
|
7501
7504
|
const horizontal = orientation === "horizontal" || orientation === "responsive" && fits;
|
|
7502
|
-
return /* @__PURE__ */ jsx("div", { ref: setRefs, "data-timeline-orientation": horizontal ? "horizontal" : "vertical", className, children: horizontal ? /* @__PURE__ */ jsx(HorizontalLayout, { items, minItemWidth }) : /* @__PURE__ */ jsx(VerticalLayout, { items }) });
|
|
7505
|
+
return /* @__PURE__ */ jsx("div", { ref: setRefs, "data-ds-list": "", "data-timeline-orientation": horizontal ? "horizontal" : "vertical", className, children: horizontal ? /* @__PURE__ */ jsx(HorizontalLayout, { items, minItemWidth }) : /* @__PURE__ */ jsx(VerticalLayout, { items }) });
|
|
7503
7506
|
}
|
|
7504
7507
|
var CollapsibleContext = createContext(null);
|
|
7505
7508
|
function useCollapsible() {
|
|
@@ -8766,6 +8769,7 @@ var StackedList = forwardRef(function StackedList2({
|
|
|
8766
8769
|
"ul",
|
|
8767
8770
|
{
|
|
8768
8771
|
ref,
|
|
8772
|
+
"data-ds-list": "",
|
|
8769
8773
|
className: cn(
|
|
8770
8774
|
divided && "divide-y-[length:var(--ds-border-width)] divide-[var(--ds-border-subtle)]",
|
|
8771
8775
|
className
|
|
@@ -9847,11 +9851,50 @@ function Popover({ open, onOpenChange, trigger, children, side = "bottom", align
|
|
|
9847
9851
|
)
|
|
9848
9852
|
] });
|
|
9849
9853
|
}
|
|
9850
|
-
function Pagination(
|
|
9854
|
+
function Pagination(props) {
|
|
9855
|
+
if ((props.mode === "load-more" || props.mode === "infinite-scroll") && props.onLoadMore) return /* @__PURE__ */ jsx(LoadMore, { ...props, onLoadMore: props.onLoadMore, scroll: props.mode === "infinite-scroll" });
|
|
9856
|
+
return /* @__PURE__ */ jsx(PageNumbers, { ...props });
|
|
9857
|
+
}
|
|
9858
|
+
function contentTop(el) {
|
|
9859
|
+
let top = el.getBoundingClientRect().top + window.scrollY;
|
|
9860
|
+
for (let n = el.parentElement; n && n !== document.documentElement; n = n.parentElement) top += n.scrollTop;
|
|
9861
|
+
return top;
|
|
9862
|
+
}
|
|
9863
|
+
function LoadMore({ hasMore, onLoadMore, loadMoreLabel, currentPage, scroll, className }) {
|
|
9864
|
+
const marker = useRef(null);
|
|
9865
|
+
const load = useLatest(onLoadMore);
|
|
9866
|
+
const loadedAt = useRef(null);
|
|
9867
|
+
useEffect(() => {
|
|
9868
|
+
const el = marker.current;
|
|
9869
|
+
if (!scroll || !hasMore || !el || typeof IntersectionObserver === "undefined") return;
|
|
9870
|
+
const observer = new IntersectionObserver((entries) => {
|
|
9871
|
+
if (!entries.some((e) => e.isIntersecting)) return;
|
|
9872
|
+
const at = contentTop(el);
|
|
9873
|
+
if (loadedAt.current !== null && Math.abs(at - loadedAt.current) < 1) return;
|
|
9874
|
+
loadedAt.current = at;
|
|
9875
|
+
load.current();
|
|
9876
|
+
}, { rootMargin: "200px 0px" });
|
|
9877
|
+
observer.observe(el);
|
|
9878
|
+
const rearm = () => {
|
|
9879
|
+
loadedAt.current = null;
|
|
9880
|
+
};
|
|
9881
|
+
window.addEventListener("scroll", rearm, { capture: true, passive: true });
|
|
9882
|
+
return () => {
|
|
9883
|
+
observer.disconnect();
|
|
9884
|
+
window.removeEventListener("scroll", rearm, { capture: true });
|
|
9885
|
+
};
|
|
9886
|
+
}, [scroll, hasMore, currentPage, load]);
|
|
9887
|
+
if (!hasMore) return null;
|
|
9888
|
+
return /* @__PURE__ */ jsxs("div", { "data-ds-pager": "", "data-pagination-mode": scroll ? "infinite-scroll" : "load-more", className: cn("flex flex-col items-center", className), children: [
|
|
9889
|
+
scroll && /* @__PURE__ */ jsx("div", { ref: marker, "data-load-more-trigger": "", "aria-hidden": "true", className: "h-px w-full" }),
|
|
9890
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onLoadMore, children: loadMoreLabel ?? "Load more" })
|
|
9891
|
+
] });
|
|
9892
|
+
}
|
|
9893
|
+
function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSizeProp, pageSizeOptions, onPageSizeChange, className }) {
|
|
9851
9894
|
const pages = buildPageRange(currentPage, totalPages);
|
|
9852
9895
|
const preferences = useShellPreferences();
|
|
9853
9896
|
const pageSize = pageSizeProp ?? preferences.itemsPerPage;
|
|
9854
|
-
return /* @__PURE__ */ jsxs("nav", { "aria-label": "Pagination", className: cn("flex flex-wrap items-center gap-ds-3", className), children: [
|
|
9897
|
+
return /* @__PURE__ */ jsxs("nav", { "aria-label": "Pagination", "data-ds-pager": "", className: cn("flex flex-wrap items-center gap-ds-3", className), children: [
|
|
9855
9898
|
pageSizeOptions && pageSize != null && onPageSizeChange && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
|
|
9856
9899
|
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--ds-text-muted)] whitespace-nowrap", children: "Rows per page" }),
|
|
9857
9900
|
/* @__PURE__ */ jsx(
|
|
@@ -14108,6 +14151,7 @@ function signature(list, resetOn) {
|
|
|
14108
14151
|
}
|
|
14109
14152
|
function usePagination(list, options = {}) {
|
|
14110
14153
|
const shell = useShellPreferences();
|
|
14154
|
+
const style = options.style ?? shell.paginationStyle ?? PREFERENCE_HOUSE_DEFAULTS.paginationStyle;
|
|
14111
14155
|
const [chosenSize, setChosenSize] = useState(null);
|
|
14112
14156
|
const pageSize = Math.max(1, Math.floor(chosenSize ?? options.pageSize ?? shell.itemsPerPage ?? PREFERENCE_HOUSE_DEFAULTS.itemsPerPage));
|
|
14113
14157
|
const [page, setPageState] = useState(1);
|
|
@@ -14120,24 +14164,31 @@ function usePagination(list, options = {}) {
|
|
|
14120
14164
|
const totalItems = list.length;
|
|
14121
14165
|
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
14122
14166
|
const current = Math.min(Math.max(1, seen !== sig ? 1 : page), totalPages);
|
|
14123
|
-
const
|
|
14124
|
-
const
|
|
14125
|
-
const
|
|
14167
|
+
const grows = style !== "pagination";
|
|
14168
|
+
const start = grows ? 0 : (current - 1) * pageSize;
|
|
14169
|
+
const items = list.slice(start, current * pageSize);
|
|
14170
|
+
const range = items.length === 0 ? [0, 0] : [start + 1, start + items.length];
|
|
14171
|
+
const hasMore = current < totalPages;
|
|
14126
14172
|
const setPage = (next) => setPageState(Math.min(Math.max(1, Math.floor(next)), totalPages));
|
|
14173
|
+
const loadMore = () => setPageState((p) => Math.min(p + 1, totalPages));
|
|
14127
14174
|
const setPageSize = (size) => {
|
|
14128
14175
|
setChosenSize(Math.max(1, Math.floor(size)));
|
|
14129
14176
|
setPageState(1);
|
|
14130
14177
|
};
|
|
14131
14178
|
return {
|
|
14179
|
+
style,
|
|
14132
14180
|
items,
|
|
14133
14181
|
page: current,
|
|
14134
14182
|
pageSize,
|
|
14135
14183
|
totalItems,
|
|
14136
14184
|
totalPages,
|
|
14137
14185
|
range,
|
|
14186
|
+
shown: items.length,
|
|
14187
|
+
hasMore,
|
|
14188
|
+
loadMore,
|
|
14138
14189
|
setPage,
|
|
14139
14190
|
setPageSize,
|
|
14140
|
-
props: { currentPage: current, totalPages, onPageChange: setPage, pageSize, onPageSizeChange: setPageSize }
|
|
14191
|
+
props: { currentPage: current, totalPages, onPageChange: setPage, pageSize, onPageSizeChange: setPageSize, mode: style, hasMore, onLoadMore: loadMore }
|
|
14141
14192
|
};
|
|
14142
14193
|
}
|
|
14143
14194
|
function useDestructiveAction(options) {
|