@pk-design/react-tailwind 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- :root{--ui-primary:#2563eb;--ui-primary-hover:#1d4ed8;--ui-primary-ring:#2563eb;--ui-primary-light:#eff6ff;--ui-primary-text:#1d4ed8;--ui-primary-disabled:#93c5fd;--ui-danger:#dc2626;--ui-danger-hover:#b91c1c;--ui-danger-ring:#dc2626;--ui-danger-light:#fef2f2;--ui-danger-text:#991b1b;--ui-danger-disabled:#fca5a5;--ui-success:#16a34a;--ui-success-ring:#16a34a;--ui-success-light:#f0fdf4;--ui-success-text:#15803d;--ui-warning:#d97706;--ui-warning-ring:#d97706;--ui-warning-light:#fffbeb;--ui-warning-text:#92400e;--ui-info:#2563eb;--ui-info-ring:#2563eb;--ui-info-light:#eff6ff;--ui-info-text:#1d4ed8;--ui-success-ring-subtle:rgba(22,163,74,.2);--ui-danger-ring-subtle:rgba(220,38,38,.2);--ui-warning-ring-subtle:rgba(217,119,6,.2);--ui-info-ring-subtle:rgba(37,99,235,.2);--ui-secondary-ring-subtle:hsla(220,9%,46%,.2);--ui-focus-ring:#2563eb;--ui-text:#111827;--ui-text-muted:#6b7280;--ui-text-danger:#ef4444;--ui-radius-sm:0.25rem;--ui-radius:0.375rem;--ui-radius-md:0.5rem;--ui-radius-lg:0.75rem;--ui-radius-xl:1rem;--ui-radius-full:9999px}.dark{--ui-primary:#3b82f6;--ui-primary-hover:#2563eb;--ui-primary-ring:#3b82f6;--ui-primary-light:#1e3a8a;--ui-primary-text:#93c5fd;--ui-primary-disabled:#1e40af;--ui-danger:#ef4444;--ui-danger-hover:#dc2626;--ui-danger-ring:#ef4444;--ui-danger-light:#7f1d1d;--ui-danger-text:#fca5a5;--ui-danger-disabled:#991b1b;--ui-success:#22c55e;--ui-success-ring:#22c55e;--ui-success-light:#14532d;--ui-success-text:#86efac;--ui-warning:#f59e0b;--ui-warning-ring:#f59e0b;--ui-warning-light:#78350f;--ui-warning-text:#fcd34d;--ui-info:#3b82f6;--ui-info-ring:#3b82f6;--ui-info-light:#1e3a8a;--ui-info-text:#93c5fd;--ui-success-ring-subtle:rgba(34,197,94,.2);--ui-danger-ring-subtle:rgba(239,68,68,.2);--ui-warning-ring-subtle:rgba(245,158,11,.2);--ui-info-ring-subtle:rgba(59,130,246,.2);--ui-secondary-ring-subtle:rgba(156,163,175,.2);--ui-focus-ring:#3b82f6;--ui-text:#f3f4f6;--ui-text-muted:#9ca3af;--ui-text-danger:#f87171}.spinner{-webkit-animation:rotate 2s linear infinite;animation:rotate 2s linear infinite}.spinner .path{-webkit-animation:dash 1.5s ease-in-out infinite;animation:dash 1.5s ease-in-out infinite}@-webkit-keyframes rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}
1
+ :root{--ui-primary:#2563eb;--ui-primary-hover:#1d4ed8;--ui-primary-ring:#2563eb;--ui-primary-light:#eff6ff;--ui-primary-text:#1d4ed8;--ui-primary-disabled:#93c5fd;--ui-danger:#dc2626;--ui-danger-hover:#b91c1c;--ui-danger-ring:#dc2626;--ui-danger-light:#fef2f2;--ui-danger-text:#991b1b;--ui-danger-disabled:#fca5a5;--ui-success:#16a34a;--ui-success-ring:#16a34a;--ui-success-light:#f0fdf4;--ui-success-text:#15803d;--ui-warning:#d97706;--ui-warning-ring:#d97706;--ui-warning-light:#fffbeb;--ui-warning-text:#92400e;--ui-info:#2563eb;--ui-info-ring:#2563eb;--ui-info-light:#eff6ff;--ui-info-text:#1d4ed8;--ui-success-ring-subtle:rgba(22,163,74,.2);--ui-danger-ring-subtle:rgba(220,38,38,.2);--ui-warning-ring-subtle:rgba(217,119,6,.2);--ui-info-ring-subtle:rgba(37,99,235,.2);--ui-secondary-ring-subtle:hsla(220,9%,46%,.2);--ui-focus-ring:#2563eb;--ui-text:#111827;--ui-text-muted:#6b7280;--ui-text-danger:#ef4444;--ui-border:#e5e7eb;--ui-border-muted:#f3f4f6;--ui-radius-sm:0.25rem;--ui-radius:0.375rem;--ui-radius-md:0.5rem;--ui-radius-lg:0.75rem;--ui-radius-xl:1rem;--ui-radius-full:9999px}.dark{--ui-primary:#3b82f6;--ui-primary-hover:#2563eb;--ui-primary-ring:#3b82f6;--ui-primary-light:#1e3a8a;--ui-primary-text:#93c5fd;--ui-primary-disabled:#1e40af;--ui-danger:#ef4444;--ui-danger-hover:#dc2626;--ui-danger-ring:#ef4444;--ui-danger-light:#7f1d1d;--ui-danger-text:#fca5a5;--ui-danger-disabled:#991b1b;--ui-success:#22c55e;--ui-success-ring:#22c55e;--ui-success-light:#14532d;--ui-success-text:#86efac;--ui-warning:#f59e0b;--ui-warning-ring:#f59e0b;--ui-warning-light:#78350f;--ui-warning-text:#fcd34d;--ui-info:#3b82f6;--ui-info-ring:#3b82f6;--ui-info-light:#1e3a8a;--ui-info-text:#93c5fd;--ui-success-ring-subtle:rgba(34,197,94,.2);--ui-danger-ring-subtle:rgba(239,68,68,.2);--ui-warning-ring-subtle:rgba(245,158,11,.2);--ui-info-ring-subtle:rgba(59,130,246,.2);--ui-secondary-ring-subtle:rgba(156,163,175,.2);--ui-focus-ring:#3b82f6;--ui-text:#f3f4f6;--ui-text-muted:#9ca3af;--ui-text-danger:#f87171;--ui-border:#374151;--ui-border-muted:#374151}.spinner{-webkit-animation:rotate 2s linear infinite;animation:rotate 2s linear infinite}.spinner .path{-webkit-animation:dash 1.5s ease-in-out infinite;animation:dash 1.5s ease-in-out infinite}@-webkit-keyframes rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}
2
2
  /*# sourceMappingURL=react-tailwind.css.map */
@@ -1 +1 @@
1
- {"version":3,"sources":["tokens.css","loader.css"],"names":[],"mappings":"AAgBA,MAEE,oBAAqB,CACrB,0BAA2B,CAC3B,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAC1B,6BAA8B,CAG9B,mBAAoB,CACpB,yBAA0B,CAC1B,wBAAyB,CACzB,yBAA0B,CAC1B,wBAAyB,CACzB,4BAA6B,CAG7B,oBAAqB,CACrB,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAG1B,oBAAqB,CACrB,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAG1B,iBAAkB,CAClB,sBAAuB,CACvB,uBAAwB,CACxB,sBAAuB,CAGvB,2CAAgD,CAChD,0CAA+C,CAC/C,2CAAgD,CAChD,wCAA6C,CAC7C,8CAAoD,CAGpD,uBAAwB,CAGxB,iBAAkB,CAClB,uBAAwB,CACxB,wBAAyB,CAGzB,sBAAuB,CACvB,oBAAqB,CACrB,qBAAsB,CACtB,sBAAuB,CACvB,mBAAoB,CACpB,uBACF,CAGA,MACE,oBAAqB,CACrB,0BAA2B,CAC3B,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAC1B,6BAA8B,CAE9B,mBAAoB,CACpB,yBAA0B,CAC1B,wBAAyB,CACzB,yBAA0B,CAC1B,wBAAyB,CACzB,4BAA6B,CAE7B,oBAAqB,CACrB,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAE1B,oBAAqB,CACrB,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAE1B,iBAAkB,CAClB,sBAAuB,CACvB,uBAAwB,CACxB,sBAAuB,CAEvB,2CAAgD,CAChD,0CAA+C,CAC/C,4CAAiD,CACjD,yCAA8C,CAC9C,+CAAoD,CAEpD,uBAAwB,CAExB,iBAAkB,CAClB,uBAAwB,CACxB,wBACF,CCpHA,SACE,2CAA4C,CAC5C,mCACF,CACA,eACE,gDAAiD,CACjD,wCACF,CAEA,0BACE,GACE,+BAAiC,CACjC,uBACF,CACF,CAEA,kBACE,GACE,+BAAiC,CACjC,uBACF,CACF,CACA,wBACE,GACE,sBAAwB,CACxB,mBACF,CACA,IACE,uBAAyB,CACzB,qBACF,CACA,GACE,uBAAyB,CACzB,sBACF,CACF,CACA,gBACE,GACE,sBAAwB,CACxB,mBACF,CACA,IACE,uBAAyB,CACzB,qBACF,CACA,GACE,uBAAyB,CACzB,sBACF,CACF","file":"react-tailwind.css","sourcesContent":["/*\n * Design tokens for @pk-design/react-tailwind.\n *\n * Override any variable in your app's CSS to rebrand the entire library:\n *\n * :root {\n * --ui-primary: #7c3aed;\n * --ui-primary-hover: #6d28d9;\n * --ui-primary-ring: #7c3aed;\n * --ui-primary-light: #f5f3ff;\n * --ui-primary-text: #5b21b6;\n * --ui-primary-disabled:#c4b5fd;\n * }\n */\n\n/* ─── Light mode ────────────────────────────────────────────────────────────── */\n:root {\n /* Primary (blue-600 family) */\n --ui-primary: #2563eb;\n --ui-primary-hover: #1d4ed8;\n --ui-primary-ring: #2563eb;\n --ui-primary-light: #eff6ff;\n --ui-primary-text: #1d4ed8;\n --ui-primary-disabled: #93c5fd;\n\n /* Danger (red-600 family) */\n --ui-danger: #dc2626;\n --ui-danger-hover: #b91c1c;\n --ui-danger-ring: #dc2626;\n --ui-danger-light: #fef2f2;\n --ui-danger-text: #991b1b;\n --ui-danger-disabled: #fca5a5;\n\n /* Success (green-600 family) */\n --ui-success: #16a34a;\n --ui-success-ring: #16a34a;\n --ui-success-light: #f0fdf4;\n --ui-success-text: #15803d;\n\n /* Warning (amber-600 family) */\n --ui-warning: #d97706;\n --ui-warning-ring: #d97706;\n --ui-warning-light: #fffbeb;\n --ui-warning-text: #92400e;\n\n /* Info (same as primary by default) */\n --ui-info: #2563eb;\n --ui-info-ring: #2563eb;\n --ui-info-light: #eff6ff;\n --ui-info-text: #1d4ed8;\n\n /* Badge / Alert ring colors (with opacity pre-baked) */\n --ui-success-ring-subtle: rgba(22, 163, 74, 0.2);\n --ui-danger-ring-subtle: rgba(220, 38, 38, 0.2);\n --ui-warning-ring-subtle: rgba(217, 119, 6, 0.2);\n --ui-info-ring-subtle: rgba(37, 99, 235, 0.2);\n --ui-secondary-ring-subtle: rgba(107, 114, 128, 0.2);\n\n /* Global focus ring */\n --ui-focus-ring: #2563eb;\n\n /* Neutral text (used by BodyText, TextContent, HeadingText) */\n --ui-text: #111827; /* gray-900 */\n --ui-text-muted: #6b7280; /* gray-500 */\n --ui-text-danger: #ef4444; /* red-500 */\n\n /* Border radius scale */\n --ui-radius-sm: 0.25rem;\n --ui-radius: 0.375rem;\n --ui-radius-md: 0.5rem;\n --ui-radius-lg: 0.75rem;\n --ui-radius-xl: 1rem;\n --ui-radius-full: 9999px;\n}\n\n/* ─── Dark mode overrides ───────────────────────────────────────────────────── */\n.dark {\n --ui-primary: #3b82f6;\n --ui-primary-hover: #2563eb;\n --ui-primary-ring: #3b82f6;\n --ui-primary-light: #1e3a8a;\n --ui-primary-text: #93c5fd;\n --ui-primary-disabled: #1e40af;\n\n --ui-danger: #ef4444;\n --ui-danger-hover: #dc2626;\n --ui-danger-ring: #ef4444;\n --ui-danger-light: #7f1d1d;\n --ui-danger-text: #fca5a5;\n --ui-danger-disabled: #991b1b;\n\n --ui-success: #22c55e;\n --ui-success-ring: #22c55e;\n --ui-success-light: #14532d;\n --ui-success-text: #86efac;\n\n --ui-warning: #f59e0b;\n --ui-warning-ring: #f59e0b;\n --ui-warning-light: #78350f;\n --ui-warning-text: #fcd34d;\n\n --ui-info: #3b82f6;\n --ui-info-ring: #3b82f6;\n --ui-info-light: #1e3a8a;\n --ui-info-text: #93c5fd;\n\n --ui-success-ring-subtle: rgba(34, 197, 94, 0.2);\n --ui-danger-ring-subtle: rgba(239, 68, 68, 0.2);\n --ui-warning-ring-subtle: rgba(245, 158, 11, 0.2);\n --ui-info-ring-subtle: rgba(59, 130, 246, 0.2);\n --ui-secondary-ring-subtle: rgba(156, 163, 175, 0.2);\n\n --ui-focus-ring: #3b82f6;\n\n --ui-text: #f3f4f6; /* gray-100 */\n --ui-text-muted: #9ca3af; /* gray-400 */\n --ui-text-danger: #f87171; /* red-400 */\n}\n","/* SVG spinner icon animation */\n.spinner {\n -webkit-animation: rotate 2s linear infinite;\n animation: rotate 2s linear infinite;\n}\n.spinner .path {\n -webkit-animation: dash 1.5s ease-in-out infinite;\n animation: dash 1.5s ease-in-out infinite;\n}\n\n@-webkit-keyframes rotate {\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes rotate {\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes dash {\n 0% {\n stroke-dasharray: 1, 150;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 90, 150;\n stroke-dashoffset: -35;\n }\n 100% {\n stroke-dasharray: 90, 150;\n stroke-dashoffset: -124;\n }\n}\n@keyframes dash {\n 0% {\n stroke-dasharray: 1, 150;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 90, 150;\n stroke-dashoffset: -35;\n }\n 100% {\n stroke-dasharray: 90, 150;\n stroke-dashoffset: -124;\n }\n}\n"]}
1
+ {"version":3,"sources":["tokens.css","loader.css"],"names":[],"mappings":"AAgBA,MAEE,oBAAqB,CACrB,0BAA2B,CAC3B,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAC1B,6BAA8B,CAG9B,mBAAoB,CACpB,yBAA0B,CAC1B,wBAAyB,CACzB,yBAA0B,CAC1B,wBAAyB,CACzB,4BAA6B,CAG7B,oBAAqB,CACrB,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAG1B,oBAAqB,CACrB,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAG1B,iBAAkB,CAClB,sBAAuB,CACvB,uBAAwB,CACxB,sBAAuB,CAGvB,2CAAgD,CAChD,0CAA+C,CAC/C,2CAAgD,CAChD,wCAA6C,CAC7C,8CAAoD,CAGpD,uBAAwB,CAGxB,iBAAkB,CAClB,uBAAwB,CACxB,wBAAyB,CAGzB,mBAAoB,CACpB,yBAA0B,CAG1B,sBAAuB,CACvB,oBAAqB,CACrB,qBAAsB,CACtB,sBAAuB,CACvB,mBAAoB,CACpB,uBACF,CAGA,MACE,oBAAqB,CACrB,0BAA2B,CAC3B,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAC1B,6BAA8B,CAE9B,mBAAoB,CACpB,yBAA0B,CAC1B,wBAAyB,CACzB,yBAA0B,CAC1B,wBAAyB,CACzB,4BAA6B,CAE7B,oBAAqB,CACrB,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAE1B,oBAAqB,CACrB,yBAA0B,CAC1B,0BAA2B,CAC3B,yBAA0B,CAE1B,iBAAkB,CAClB,sBAAuB,CACvB,uBAAwB,CACxB,sBAAuB,CAEvB,2CAAgD,CAChD,0CAA+C,CAC/C,4CAAiD,CACjD,yCAA8C,CAC9C,+CAAoD,CAEpD,uBAAwB,CAExB,iBAAkB,CAClB,uBAAwB,CACxB,wBAAyB,CAEzB,mBAAoB,CACpB,yBACF,CC3HA,SACE,2CAA4C,CAC5C,mCACF,CACA,eACE,gDAAiD,CACjD,wCACF,CAEA,0BACE,GACE,+BAAiC,CACjC,uBACF,CACF,CAEA,kBACE,GACE,+BAAiC,CACjC,uBACF,CACF,CACA,wBACE,GACE,sBAAwB,CACxB,mBACF,CACA,IACE,uBAAyB,CACzB,qBACF,CACA,GACE,uBAAyB,CACzB,sBACF,CACF,CACA,gBACE,GACE,sBAAwB,CACxB,mBACF,CACA,IACE,uBAAyB,CACzB,qBACF,CACA,GACE,uBAAyB,CACzB,sBACF,CACF","file":"react-tailwind.css","sourcesContent":["/*\n * Design tokens for @pk-design/react-tailwind.\n *\n * Override any variable in your app's CSS to rebrand the entire library:\n *\n * :root {\n * --ui-primary: #7c3aed;\n * --ui-primary-hover: #6d28d9;\n * --ui-primary-ring: #7c3aed;\n * --ui-primary-light: #f5f3ff;\n * --ui-primary-text: #5b21b6;\n * --ui-primary-disabled:#c4b5fd;\n * }\n */\n\n/* ─── Light mode ────────────────────────────────────────────────────────────── */\n:root {\n /* Primary (blue-600 family) */\n --ui-primary: #2563eb;\n --ui-primary-hover: #1d4ed8;\n --ui-primary-ring: #2563eb;\n --ui-primary-light: #eff6ff;\n --ui-primary-text: #1d4ed8;\n --ui-primary-disabled: #93c5fd;\n\n /* Danger (red-600 family) */\n --ui-danger: #dc2626;\n --ui-danger-hover: #b91c1c;\n --ui-danger-ring: #dc2626;\n --ui-danger-light: #fef2f2;\n --ui-danger-text: #991b1b;\n --ui-danger-disabled: #fca5a5;\n\n /* Success (green-600 family) */\n --ui-success: #16a34a;\n --ui-success-ring: #16a34a;\n --ui-success-light: #f0fdf4;\n --ui-success-text: #15803d;\n\n /* Warning (amber-600 family) */\n --ui-warning: #d97706;\n --ui-warning-ring: #d97706;\n --ui-warning-light: #fffbeb;\n --ui-warning-text: #92400e;\n\n /* Info (same as primary by default) */\n --ui-info: #2563eb;\n --ui-info-ring: #2563eb;\n --ui-info-light: #eff6ff;\n --ui-info-text: #1d4ed8;\n\n /* Badge / Alert ring colors (with opacity pre-baked) */\n --ui-success-ring-subtle: rgba(22, 163, 74, 0.2);\n --ui-danger-ring-subtle: rgba(220, 38, 38, 0.2);\n --ui-warning-ring-subtle: rgba(217, 119, 6, 0.2);\n --ui-info-ring-subtle: rgba(37, 99, 235, 0.2);\n --ui-secondary-ring-subtle: rgba(107, 114, 128, 0.2);\n\n /* Global focus ring */\n --ui-focus-ring: #2563eb;\n\n /* Neutral text (used by BodyText, TextContent, HeadingText) */\n --ui-text: #111827; /* gray-900 */\n --ui-text-muted: #6b7280; /* gray-500 */\n --ui-text-danger: #ef4444; /* red-500 */\n\n /* Neutral structural borders (containers, dividers — not interactive form controls) */\n --ui-border: #e5e7eb; /* gray-200 */\n --ui-border-muted: #f3f4f6; /* gray-100 */\n\n /* Border radius scale */\n --ui-radius-sm: 0.25rem;\n --ui-radius: 0.375rem;\n --ui-radius-md: 0.5rem;\n --ui-radius-lg: 0.75rem;\n --ui-radius-xl: 1rem;\n --ui-radius-full: 9999px;\n}\n\n/* ─── Dark mode overrides ───────────────────────────────────────────────────── */\n.dark {\n --ui-primary: #3b82f6;\n --ui-primary-hover: #2563eb;\n --ui-primary-ring: #3b82f6;\n --ui-primary-light: #1e3a8a;\n --ui-primary-text: #93c5fd;\n --ui-primary-disabled: #1e40af;\n\n --ui-danger: #ef4444;\n --ui-danger-hover: #dc2626;\n --ui-danger-ring: #ef4444;\n --ui-danger-light: #7f1d1d;\n --ui-danger-text: #fca5a5;\n --ui-danger-disabled: #991b1b;\n\n --ui-success: #22c55e;\n --ui-success-ring: #22c55e;\n --ui-success-light: #14532d;\n --ui-success-text: #86efac;\n\n --ui-warning: #f59e0b;\n --ui-warning-ring: #f59e0b;\n --ui-warning-light: #78350f;\n --ui-warning-text: #fcd34d;\n\n --ui-info: #3b82f6;\n --ui-info-ring: #3b82f6;\n --ui-info-light: #1e3a8a;\n --ui-info-text: #93c5fd;\n\n --ui-success-ring-subtle: rgba(34, 197, 94, 0.2);\n --ui-danger-ring-subtle: rgba(239, 68, 68, 0.2);\n --ui-warning-ring-subtle: rgba(245, 158, 11, 0.2);\n --ui-info-ring-subtle: rgba(59, 130, 246, 0.2);\n --ui-secondary-ring-subtle: rgba(156, 163, 175, 0.2);\n\n --ui-focus-ring: #3b82f6;\n\n --ui-text: #f3f4f6; /* gray-100 */\n --ui-text-muted: #9ca3af; /* gray-400 */\n --ui-text-danger: #f87171; /* red-400 */\n\n --ui-border: #374151; /* gray-700 */\n --ui-border-muted: #374151; /* gray-700 */\n}\n","/* SVG spinner icon animation */\n.spinner {\n -webkit-animation: rotate 2s linear infinite;\n animation: rotate 2s linear infinite;\n}\n.spinner .path {\n -webkit-animation: dash 1.5s ease-in-out infinite;\n animation: dash 1.5s ease-in-out infinite;\n}\n\n@-webkit-keyframes rotate {\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes rotate {\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes dash {\n 0% {\n stroke-dasharray: 1, 150;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 90, 150;\n stroke-dashoffset: -35;\n }\n 100% {\n stroke-dasharray: 90, 150;\n stroke-dashoffset: -124;\n }\n}\n@keyframes dash {\n 0% {\n stroke-dasharray: 1, 150;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 90, 150;\n stroke-dashoffset: -35;\n }\n 100% {\n stroke-dasharray: 90, 150;\n stroke-dashoffset: -124;\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { useId, useMemo, useState, forwardRef, Children, isValidElement, cloneElement, useRef, useEffect, Fragment as Fragment$1, useCallback, useImperativeHandle, createContext, useContext } from 'react';
3
+ import React__default, { useId, useMemo, useState, forwardRef, Children, isValidElement, cloneElement, useCallback, useRef, useEffect, Fragment as Fragment$1, useImperativeHandle, createContext, useContext } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { Dialog, DialogBackdrop, DialogPanel, DialogTitle, Menu, MenuButton, MenuItems, MenuItem, RadioGroup as RadioGroup$1, Radio as Radio$1, Combobox, ComboboxInput, ComboboxButton, ComboboxOptions, ComboboxOption, TabGroup, TabList, Tab, TabPanels, TabPanel, Transition } from '@headlessui/react';
6
6
  import { FixedSizeList } from 'react-window';
@@ -530,7 +530,7 @@ const Card = forwardRef(({ as, ...props }, ref) => {
530
530
  const Component = as || 'div';
531
531
  // Extract className safely from rest
532
532
  const { className, ...cleanRest } = rest;
533
- const classes = buildClassName(BASE_CARD_CLASS, zeroPadding ? '' : compact ? 'p-2' : 'p-6', hoverable && 'transition-background duration-200 hover:bg-gray-100 dark:hover:bg-gray-800', bordered && 'border border-gray-200 dark:border-gray-800', className);
533
+ const classes = buildClassName(BASE_CARD_CLASS, zeroPadding ? '' : compact ? 'p-2' : 'p-6', hoverable && 'transition-background duration-200 hover:bg-gray-100 dark:hover:bg-gray-800', bordered && 'border border-[var(--ui-border)]', className);
534
534
  return jsx(Component, { ref: ref, className: classes, ...cleanRest });
535
535
  });
536
536
  Card.displayName = 'Card';
@@ -603,7 +603,7 @@ const TableRowLoader = ({ colSize, rowSize }) => (jsx(Fragment, { children: Arra
603
603
  /* ----------------------------------------------
604
604
  * Table
605
605
  * ---------------------------------------------- */
606
- const Table = ({ children, layout = 'auto', className = '', caption, }) => (jsxs("table", { className: buildClassName('border-collapse w-full divide-y divide-gray-200 dark:divide-gray-700', TABLE_LAYOUT[layout], className), children: [caption && (jsx("caption", { className: "mb-2 text-sm text-left text-gray-500 dark:text-gray-400", children: caption })), children] }));
606
+ const Table = ({ children, layout = 'auto', className = '', caption, }) => (jsxs("table", { className: buildClassName('border-collapse w-full divide-y divide-[var(--ui-border)]', TABLE_LAYOUT[layout], className), children: [caption && (jsx("caption", { className: "mb-2 text-sm text-left text-gray-500 dark:text-gray-400", children: caption })), children] }));
607
607
  /* ----------------------------------------------
608
608
  * Head
609
609
  * ---------------------------------------------- */
@@ -611,7 +611,7 @@ const TableHead = ({ children, className = '' }) => (jsx("thead", { className: b
611
611
  /* ----------------------------------------------
612
612
  * Body
613
613
  * ---------------------------------------------- */
614
- const TableBody = ({ children, loading, colSize = 1, rowSize = 5, className, }) => (jsx("tbody", { className: buildClassName('text-sm text-gray-700 dark:text-white divide-y divide-gray-200 dark:divide-gray-700', className), children: loading ? jsx(TableRowLoader, { colSize: colSize, rowSize: rowSize }) : children }));
614
+ const TableBody = ({ children, loading, colSize = 1, rowSize = 5, className, }) => (jsx("tbody", { className: buildClassName('text-sm text-gray-700 dark:text-white divide-y divide-[var(--ui-border)]', className), children: loading ? jsx(TableRowLoader, { colSize: colSize, rowSize: rowSize }) : children }));
615
615
  /* ----------------------------------------------
616
616
  * Foot
617
617
  * ---------------------------------------------- */
@@ -619,7 +619,7 @@ const TableFoot = ({ children }) => (jsx("tfoot", { children: jsx("tr", { childr
619
619
  /* ----------------------------------------------
620
620
  * Rows
621
621
  * ---------------------------------------------- */
622
- const TableRow = ({ children, hoverable = false, className, ...props }) => (jsx("tr", { ...props, className: buildClassName('last:border-b border-gray-200 dark:border-gray-700', hoverable && 'group', className), children: children }));
622
+ const TableRow = ({ children, hoverable = false, className, ...props }) => (jsx("tr", { ...props, className: buildClassName('last:border-b border-[var(--ui-border)]', hoverable && 'group', className), children: children }));
623
623
  /* ----------------------------------------------
624
624
  * Cells
625
625
  * ---------------------------------------------- */
@@ -770,6 +770,48 @@ const updateSortQuery = (sortQuery, name, type = 'string') => {
770
770
  }
771
771
  return updated;
772
772
  };
773
+ /**
774
+ * Shared row-selection state/behaviour used by DataTable and VirtualizedDataTable.
775
+ * Supports controlled (`selectedRowKeys`) and uncontrolled (`defaultSelectedRowKeys`) usage.
776
+ */
777
+ const useRowSelection = ({ items, getKey, selectedRowKeys, defaultSelectedRowKeys = [], onSelectionChange, isRowSelectable, }) => {
778
+ const [internalKeys, setInternalKeys] = useState(defaultSelectedRowKeys);
779
+ const isControlled = selectedRowKeys !== undefined;
780
+ const keys = isControlled ? selectedRowKeys : internalKeys;
781
+ const keySet = useMemo(() => new Set(keys), [keys]);
782
+ const selectableEntries = useMemo(() => items
783
+ .map((item, idx) => ({ item, key: getKey(item, idx) }))
784
+ .filter(({ item }) => !isRowSelectable || isRowSelectable(item)), [items, getKey, isRowSelectable]);
785
+ const emit = useCallback((nextKeys) => {
786
+ if (!isControlled)
787
+ setInternalKeys(nextKeys);
788
+ const nextKeySet = new Set(nextKeys);
789
+ const nextItems = items.filter((item, idx) => nextKeySet.has(getKey(item, idx)));
790
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(nextKeys, nextItems);
791
+ }, [isControlled, items, getKey, onSelectionChange]);
792
+ const toggleRow = useCallback((key) => {
793
+ emit(keySet.has(key) ? keys.filter((k) => k !== key) : [...keys, key]);
794
+ }, [keys, keySet, emit]);
795
+ const allSelected = selectableEntries.length > 0 && selectableEntries.every(({ key }) => keySet.has(key));
796
+ const someSelected = !allSelected && selectableEntries.some(({ key }) => keySet.has(key));
797
+ const toggleAll = useCallback(() => {
798
+ const selectableKeySet = new Set(selectableEntries.map(({ key }) => key));
799
+ if (allSelected) {
800
+ emit(keys.filter((k) => !selectableKeySet.has(k)));
801
+ }
802
+ else {
803
+ emit(Array.from(new Set([...keys, ...selectableKeySet])));
804
+ }
805
+ }, [allSelected, selectableEntries, keys, emit]);
806
+ return {
807
+ selectedKeys: keys,
808
+ isSelected: (key) => keySet.has(key),
809
+ toggleRow,
810
+ toggleAll,
811
+ allSelected,
812
+ someSelected,
813
+ };
814
+ };
773
815
 
774
816
  var _path$7;
775
817
  function _extends$7() { return _extends$7 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$7.apply(null, arguments); }
@@ -903,7 +945,7 @@ const autoSortItems = (items, column, sort) => {
903
945
  return 0;
904
946
  });
905
947
  };
906
- function DataTable({ items, columns, sorting = {}, onSort, loading, pagination, setPagination = () => { }, emptyMessage = 'No data found', containerClass = '', wrapperClass = '', tableClass = '', headClass = '', footerRow, rowKey = 'id', onRowClick, rowClass, density = 'default', striped = false, layout = 'auto', }) {
948
+ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination, setPagination = () => { }, emptyMessage = 'No data found', containerClass = '', wrapperClass = '', tableClass = '', headClass = '', footerRow, rowKey = 'id', onRowClick, rowClass, density = 'default', striped = false, layout = 'auto', selectable = false, selectedRowKeys, defaultSelectedRowKeys, onSelectionChange, isRowSelectable, }) {
907
949
  const internalSorting = useRef({});
908
950
  const [sortedItems, setSortedItems] = useState(items);
909
951
  useEffect(() => {
@@ -938,17 +980,33 @@ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination,
938
980
  return column.cellClass(item);
939
981
  return column.cellClass;
940
982
  };
983
+ const { isSelected, toggleRow, toggleAll, allSelected, someSelected } = useRowSelection({
984
+ items: sortedItems,
985
+ getKey,
986
+ selectedRowKeys,
987
+ defaultSelectedRowKeys,
988
+ onSelectionChange,
989
+ isRowSelectable,
990
+ });
941
991
  const densityCellClass = DENSITY_CELL_CLASS$2[density];
942
- return (jsxs("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: [jsx("div", { className: buildClassName('overflow-x-auto overflow-y-hidden rounded-lg border border-gray-200 dark:border-gray-800', wrapperClass, pagination && 'rounded-b-none border-b-0'), children: jsxs(Table, { className: buildClassName('relative w-full max-w-full h-fit', tableClass), layout: layout, children: [jsx(TableHead, { className: headClass, children: columns.map((column) => (jsx(TableHeaderCell, { align: column.headerAlign, style: { width: column.width || 'auto' }, className: buildClassName('bg-gray-50 dark:bg-gray-800', densityCellClass, column.sticky === 'left' &&
943
- 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
944
- 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', column.headerClass), children: jsxs(TextContent, { role: column.sortable ? 'button' : undefined, className: buildClassName('group', column.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(column), children: [jsx(TextContent, { className: "shrink-0", children: column.label }), column.sortable ? getSortIcon(sorting[column.name]) : null] }) }, column.name))) }), jsx(TableBody, { loading: loading, colSize: columns.length, rowSize: (pagination === null || pagination === void 0 ? void 0 : pagination.limit) || 5, children: !loading && sortedItems.length === 0 ? (jsx(EmptyTableRow, { colSpan: columns.length, children: emptyMessage })) : (sortedItems.map((item, idx) => (jsx(TableRow, { className: buildClassName('group', onRowClick && 'cursor-pointer', striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', getRowClass(item, idx)), onClick: onRowClick ? () => onRowClick(item, idx) : undefined, children: columns.map((column) => {
945
- var _a;
946
- return (jsx(TableCell, { align: column.align, className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', column.sticky === 'left' &&
947
- 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
948
- 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', getCellClass(column, item)), children: column.render
949
- ? column.render(item)
950
- : ((_a = get(item, column.name)) !== null && _a !== void 0 ? _a : 'Not set') }, column.name));
951
- }) }, getKey(item, idx))))) }), footerRow && jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsx(Pagination, { ...pagination, className: "rounded-b-lg border border-t-0 border-gray-200 dark:border-gray-800", onChange: setPagination }))] }));
992
+ const colSize = columns.length + (selectable ? 1 : 0);
993
+ return (jsxs("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: [jsx("div", { className: buildClassName('overflow-x-auto overflow-y-hidden rounded-lg border border-[var(--ui-border)]', wrapperClass, pagination && 'rounded-b-none border-b-0'), children: jsxs(Table, { className: buildClassName('relative w-full max-w-full h-fit', tableClass), layout: layout, children: [jsxs(TableHead, { className: headClass, children: [selectable && (jsx(TableHeaderCell, { className: buildClassName('bg-gray-50 dark:bg-gray-800 w-px', densityCellClass), children: jsx(Checkbox, { "aria-label": "Select all rows", checked: allSelected, ref: (el) => {
994
+ if (el)
995
+ el.indeterminate = someSelected;
996
+ }, onChange: toggleAll }) })), columns.map((column) => (jsx(TableHeaderCell, { align: column.headerAlign, style: { width: column.width || 'auto' }, className: buildClassName('bg-gray-50 dark:bg-gray-800', densityCellClass, column.sticky === 'left' &&
997
+ 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
998
+ 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', column.headerClass), children: jsxs(TextContent, { role: column.sortable ? 'button' : undefined, className: buildClassName('group', column.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(column), children: [jsx(TextContent, { className: "shrink-0", children: column.label }), column.sortable ? getSortIcon(sorting[column.name]) : null] }) }, column.name)))] }), jsx(TableBody, { loading: loading, colSize: colSize, rowSize: (pagination === null || pagination === void 0 ? void 0 : pagination.limit) || 5, children: !loading && sortedItems.length === 0 ? (jsx(EmptyTableRow, { colSpan: colSize, children: emptyMessage })) : (sortedItems.map((item, idx) => {
999
+ const key = getKey(item, idx);
1000
+ const rowSelectable = !isRowSelectable || isRowSelectable(item);
1001
+ return (jsxs(TableRow, { className: buildClassName('group', onRowClick && 'cursor-pointer', striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', getRowClass(item, idx)), onClick: onRowClick ? () => onRowClick(item, idx) : undefined, children: [selectable && (jsx(TableCell, { className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40'), children: jsx("span", { onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { "aria-label": "Select row", checked: isSelected(key), disabled: !rowSelectable, onChange: () => toggleRow(key) }) }) })), columns.map((column) => {
1002
+ var _a;
1003
+ return (jsx(TableCell, { align: column.align, className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40', column.sticky === 'left' &&
1004
+ 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]', column.sticky === 'right' &&
1005
+ 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]', getCellClass(column, item)), children: column.render
1006
+ ? column.render(item)
1007
+ : ((_a = get(item, column.name)) !== null && _a !== void 0 ? _a : 'Not set') }, column.name));
1008
+ })] }, key));
1009
+ })) }), footerRow && jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsx(Pagination, { ...pagination, className: "rounded-b-lg border border-t-0 border-[var(--ui-border)]", onChange: setPagination }))] }));
952
1010
  }
953
1011
  DataTable.displayName = 'DataTable';
954
1012
 
@@ -966,10 +1024,10 @@ const HeadingText = {
966
1024
  };
967
1025
 
968
1026
  const DetailedInformation = forwardRef((props, ref) => {
969
- const { className, title, subTitle, details, compact = false, divider = true, titleClass, detailsClass, ...divProps } = props;
1027
+ const { className, title, subTitle, details, compact = false, divider = true, titleClass, detailsClass, bordered = false, ...divProps } = props;
970
1028
  const hasTitles = title || subTitle;
971
1029
  const filteredDetails = details.filter((detail) => !detail.hidden);
972
- return (jsxs("div", { className: buildClassName('p-2 md:p-4', compact ? 'md:p-2' : '', className), ref: ref, ...divProps, children: [hasTitles && (jsxs("div", { className: "px-4 sm:px-0 pt-2 sm:pt-0 mb-2", children: [title && (jsx(HeadingText.SubTitle2, { className: buildClassName(titleClass), children: title })), subTitle && (jsx("p", { className: "mt-1 max-w-2xl text-sm/6 text-gray-500 dark:text-gray-300", children: subTitle }))] })), filteredDetails.length ? (jsx("div", { className: buildClassName('border-gray-100 dark:border-gray-700', hasTitles && 'border-t', detailsClass), children: jsx("dl", { className: buildClassName(divider && 'divide-y divide-gray-100 dark:divide-gray-700'), children: filteredDetails.map((detail) => (jsxs("div", { className: buildClassName('px-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0 items-center', compact ? 'py-1.5' : 'py-2.5'), children: [jsx("dt", { className: "text-sm/6 font-medium text-gray-900 dark:text-gray-100", children: detail.label }), jsx("dd", { className: buildClassName('mt-1 text-sm/6 text-gray-700 dark:text-gray-300 sm:col-span-2 sm:mt-0', detail.contentClass), children: detail.value || '- -' })] }, detail.label))) }) })) : null] }));
1030
+ return (jsxs("div", { className: buildClassName('p-2 md:p-4', compact ? 'md:p-2' : '', bordered ? 'border border-[var(--ui-border)]' : '', className), ref: ref, ...divProps, children: [hasTitles && (jsxs("div", { className: "px-4 sm:px-0 pt-2 sm:pt-0 mb-2", children: [title && (jsx(HeadingText.SubTitle2, { className: buildClassName(titleClass), children: title })), subTitle && (jsx("p", { className: "mt-1 max-w-2xl text-sm/6 text-gray-500 dark:text-gray-300", children: subTitle }))] })), filteredDetails.length ? (jsx("div", { className: buildClassName('border-[var(--ui-border-muted)]', hasTitles && 'border-t', detailsClass), children: jsx("dl", { className: buildClassName(divider && 'divide-y divide-[var(--ui-border-muted)]'), children: filteredDetails.map((detail) => (jsxs("div", { className: buildClassName('px-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0 items-center', compact ? 'py-1.5' : 'py-2.5'), children: [jsx("dt", { className: "text-sm/6 font-medium text-gray-900 dark:text-gray-100", children: detail.label }), jsx("dd", { className: buildClassName('mt-1 text-sm/6 text-gray-700 dark:text-gray-300 sm:col-span-2 sm:mt-0', detail.contentClass), children: detail.value || '- -' })] }, detail.label))) }) })) : null] }));
973
1031
  });
974
1032
  DetailedInformation.displayName = 'DetailedInformation';
975
1033
 
@@ -1009,7 +1067,7 @@ Drawer.displayName = 'Drawer';
1009
1067
 
1010
1068
  const BASE_ITEM_CLASS = 'flex w-full px-3 py-2 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 rounded-lg';
1011
1069
  const Dropdown = ({ triggerButton, renderTriggerButton, items, renderItem, itemsContainerClass, transition = true, anchor = 'bottom start', menuItemClass, onMenuClick, }) => {
1012
- return (jsxs(Menu, { as: "div", className: "relative inline-block", children: [renderTriggerButton ? (jsx(MenuButton, { as: Fragment$1, children: (state) => renderTriggerButton(state) })) : (jsx(MenuButton, { as: Fragment$1, children: triggerButton })), jsx(MenuItems, { transition: transition, anchor: anchor, className: buildClassName('w-52 origin-top-right rounded-xl shadow-sm p-1 text-sm transition duration-100 ease-out', 'border border-gray-100 bg-white text-gray-800', 'dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200', 'focus:outline-none data-[closed]:scale-95 data-[closed]:opacity-0', '[--anchor-gap:--spacing(1)]', itemsContainerClass), "data-testid": "dropdown-items", as: "ul", children: items.map((item, idx) => (jsxs(Fragment$1, { children: [jsx(MenuItem, { as: "li", disabled: item.disabled, children: ({ disabled }) => (jsx("div", { onClick: () => !disabled && (onMenuClick === null || onMenuClick === void 0 ? void 0 : onMenuClick(item, idx)), className: buildClassName(BASE_ITEM_CLASS, menuItemClass, disabled && 'cursor-not-allowed opacity-70'), "data-testid": `dropdown-item-${item.id}`, children: renderItem ? renderItem(item) : item.label })) }), item.divider && (jsx("li", { className: "my-1 h-px bg-gray-200 dark:bg-white/5", "data-testid": "dropdown-divider" }, item.id))] }, item.id))) })] }));
1070
+ return (jsxs(Menu, { as: "div", className: "relative inline-block", children: [renderTriggerButton ? (jsx(MenuButton, { as: Fragment$1, children: (state) => renderTriggerButton(state) })) : (jsx(MenuButton, { as: Fragment$1, children: triggerButton })), jsx(MenuItems, { transition: transition, anchor: anchor, className: buildClassName('w-52 origin-top-right rounded-xl shadow-sm p-1 text-sm transition duration-100 ease-out', 'border border-[var(--ui-border-muted)] bg-white text-gray-800', 'dark:bg-gray-800 dark:text-gray-200', 'focus:outline-none data-[closed]:scale-95 data-[closed]:opacity-0', '[--anchor-gap:--spacing(1)]', itemsContainerClass), "data-testid": "dropdown-items", as: "ul", children: items.map((item, idx) => (jsxs(Fragment$1, { children: [jsx(MenuItem, { as: "li", disabled: item.disabled, children: ({ disabled }) => (jsx("div", { onClick: () => !disabled && (onMenuClick === null || onMenuClick === void 0 ? void 0 : onMenuClick(item, idx)), className: buildClassName(BASE_ITEM_CLASS, menuItemClass, disabled && 'cursor-not-allowed opacity-70'), "data-testid": `dropdown-item-${item.id}`, children: renderItem ? renderItem(item) : item.label })) }), item.divider && (jsx("li", { className: "my-1 h-px bg-gray-200 dark:bg-white/5", "data-testid": "dropdown-divider" }, item.id))] }, item.id))) })] }));
1013
1071
  };
1014
1072
  Dropdown.displayName = 'Dropdown';
1015
1073
 
@@ -1615,9 +1673,12 @@ const DENSITY_CELL_CLASS$1 = {
1615
1673
  spacious: 'px-4 py-4',
1616
1674
  };
1617
1675
  const VirtualizedRow = ({ index, style, data, }) => {
1618
- const { items, columns, gridTemplate, onRowClick, rowClass, density = 'default', striped } = data;
1676
+ var _a, _b;
1677
+ const { items, columns, gridTemplate, onRowClick, rowClass, density = 'default', striped, selectable, getKey, isSelected, toggleRow, isRowSelectable, } = data;
1619
1678
  const item = items[index];
1620
1679
  const isStriped = striped && index % 2 === 1;
1680
+ const key = (_a = getKey === null || getKey === void 0 ? void 0 : getKey(item, index)) !== null && _a !== void 0 ? _a : index;
1681
+ const rowSelectable = !isRowSelectable || isRowSelectable(item);
1621
1682
  const resolvedRowClass = !rowClass
1622
1683
  ? ''
1623
1684
  : typeof rowClass === 'function'
@@ -1631,20 +1692,21 @@ const VirtualizedRow = ({ index, style, data, }) => {
1631
1692
  return col.cellClass;
1632
1693
  };
1633
1694
  const densityCellClass = DENSITY_CELL_CLASS$1[density];
1634
- return (jsx("div", { role: "row", className: buildClassName('grid border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 group', onRowClick && 'cursor-pointer', isStriped && 'bg-gray-50 dark:bg-gray-800/40', resolvedRowClass), style: {
1695
+ return (jsxs("div", { role: "row", className: buildClassName('grid border-b border-[var(--ui-border)] bg-white dark:bg-gray-900 group', onRowClick && 'cursor-pointer', isStriped && 'bg-gray-50 dark:bg-gray-800/40', resolvedRowClass), style: {
1635
1696
  ...style,
1636
1697
  display: 'grid',
1637
1698
  gridTemplateColumns: gridTemplate,
1638
1699
  minWidth: 'fit-content',
1639
- }, onClick: onRowClick ? () => onRowClick(item, index) : undefined, children: columns.map((col) => {
1640
- var _a;
1641
- const content = col.render ? col.render(item) : ((_a = get(item, col.name)) !== null && _a !== void 0 ? _a : 'Not set');
1642
- return (jsx("div", { role: "cell", className: buildClassName('whitespace-nowrap border-r last:border-r-0 border-gray-200 dark:border-gray-700', densityCellClass, col.align === 'center' && 'text-center', col.align === 'right' && 'text-right', col.sticky === 'left' &&
1643
- 'sticky left-0 z-10 bg-white dark:bg-gray-900 shadow-[2px_0_4px_rgba(0,0,0,0.05)]', col.sticky === 'right' &&
1644
- 'sticky right-0 z-10 bg-white dark:bg-gray-900 shadow-[-2px_0_4px_rgba(0,0,0,0.05)]', isStriped && 'bg-gray-50 dark:bg-gray-800/40', getCellClass(col)), children: content }, col.name));
1645
- }) }));
1700
+ }, onClick: onRowClick ? () => onRowClick(item, index) : undefined, children: [selectable && (jsx("div", { role: "cell", className: buildClassName('flex items-center whitespace-nowrap border-r last:border-r-0 border-[var(--ui-border)]', densityCellClass, isStriped && 'bg-gray-50 dark:bg-gray-800/40'), onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { "aria-label": "Select row", checked: (_b = isSelected === null || isSelected === void 0 ? void 0 : isSelected(key)) !== null && _b !== void 0 ? _b : false, disabled: !rowSelectable, onChange: () => toggleRow === null || toggleRow === void 0 ? void 0 : toggleRow(key) }) })), columns.map((col) => {
1701
+ var _a;
1702
+ const content = col.render ? col.render(item) : ((_a = get(item, col.name)) !== null && _a !== void 0 ? _a : 'Not set');
1703
+ return (jsx("div", { role: "cell", className: buildClassName('whitespace-nowrap border-r last:border-r-0 border-[var(--ui-border)]', densityCellClass, col.align === 'center' && 'text-center', col.align === 'right' && 'text-right', col.sticky === 'left' &&
1704
+ 'sticky left-0 z-10 bg-white dark:bg-gray-900 shadow-[2px_0_4px_rgba(0,0,0,0.05)]', col.sticky === 'right' &&
1705
+ 'sticky right-0 z-10 bg-white dark:bg-gray-900 shadow-[-2px_0_4px_rgba(0,0,0,0.05)]', isStriped && 'bg-gray-50 dark:bg-gray-800/40', getCellClass(col)), children: content }, col.name));
1706
+ })] }));
1646
1707
  };
1647
1708
 
1709
+ const SELECTION_COLUMN_WIDTH = '44px';
1648
1710
  const DENSITY_CELL_CLASS = {
1649
1711
  compact: 'px-2 py-1.5',
1650
1712
  default: 'px-3 py-3',
@@ -1657,11 +1719,28 @@ const columnWidth = (col) => {
1657
1719
  return `${col.width}px`;
1658
1720
  return col.width;
1659
1721
  };
1660
- function VirtualizedDataTable({ items, columns, sorting = {}, onSort, loading = false, emptyMessage = 'No data available', containerClass = '', wrapperClass = '', onRowClick, rowClass, density = 'default', striped = false, rowHeight = 48, maxHeight = 400, overscanCount = 3, }) {
1722
+ function VirtualizedDataTable({ items, columns, sorting = {}, onSort, loading = false, emptyMessage = 'No data available', containerClass = '', wrapperClass = '', onRowClick, rowClass, density = 'default', striped = false, rowHeight = 48, maxHeight = 400, overscanCount = 3, rowKey = 'id', selectable = false, selectedRowKeys, defaultSelectedRowKeys, onSelectionChange, isRowSelectable, }) {
1661
1723
  const scrollRef = useRef(null);
1662
1724
  const outerRef = useRef(null);
1663
1725
  const headerRef = useRef(null);
1664
- const gridTemplate = useMemo(() => columns.map((col) => columnWidth(col)).join(' '), [columns]);
1726
+ const getKey = useCallback((item, idx) => {
1727
+ var _a;
1728
+ if (typeof rowKey === 'function')
1729
+ return rowKey(item);
1730
+ return (_a = item[rowKey]) !== null && _a !== void 0 ? _a : idx;
1731
+ }, [rowKey]);
1732
+ const { isSelected, toggleRow, toggleAll, allSelected, someSelected } = useRowSelection({
1733
+ items,
1734
+ getKey,
1735
+ selectedRowKeys,
1736
+ defaultSelectedRowKeys,
1737
+ onSelectionChange,
1738
+ isRowSelectable,
1739
+ });
1740
+ const gridTemplate = useMemo(() => {
1741
+ const widths = columns.map((col) => columnWidth(col));
1742
+ return selectable ? [SELECTION_COLUMN_WIDTH, ...widths].join(' ') : widths.join(' ');
1743
+ }, [columns, selectable]);
1665
1744
  const densityCellClass = DENSITY_CELL_CLASS[density];
1666
1745
  const skeletonRows = Math.max(1, Math.floor(maxHeight / rowHeight));
1667
1746
  useEffect(() => {
@@ -1679,19 +1758,48 @@ function VirtualizedDataTable({ items, columns, sorting = {}, onSort, loading =
1679
1758
  if (column.sortable)
1680
1759
  onSort === null || onSort === void 0 ? void 0 : onSort(column);
1681
1760
  }, [onSort]);
1682
- const itemData = useMemo(() => ({ items, columns, gridTemplate, onRowClick, rowClass, density, striped }), [items, columns, gridTemplate, onRowClick, rowClass, density, striped]);
1761
+ const itemData = useMemo(() => ({
1762
+ items,
1763
+ columns,
1764
+ gridTemplate,
1765
+ onRowClick,
1766
+ rowClass,
1767
+ density,
1768
+ striped,
1769
+ selectable,
1770
+ getKey,
1771
+ isSelected,
1772
+ toggleRow,
1773
+ isRowSelectable,
1774
+ }), [
1775
+ items,
1776
+ columns,
1777
+ gridTemplate,
1778
+ onRowClick,
1779
+ rowClass,
1780
+ density,
1781
+ striped,
1782
+ selectable,
1783
+ getKey,
1784
+ isSelected,
1785
+ toggleRow,
1786
+ isRowSelectable,
1787
+ ]);
1683
1788
  /* -------------------------------------------------------
1684
1789
  * Header
1685
1790
  * ------------------------------------------------------- */
1686
- const Header = (jsx("div", { ref: headerRef, className: "overflow-hidden w-full", children: jsx("div", { className: "grid bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", style: { gridTemplateColumns: gridTemplate, minWidth: 'fit-content' }, children: columns.map((col) => (jsx("div", { role: "columnheader", className: buildClassName('font-semibold text-sm whitespace-nowrap flex items-center', densityCellClass, 'border-r last:border-r-0 border-gray-200 dark:border-gray-700', col.sticky === 'left' &&
1687
- 'sticky left-0 z-20 bg-gray-50 dark:bg-gray-800 shadow-[2px_0_4px_rgba(0,0,0,0.05)]', col.sticky === 'right' &&
1688
- 'sticky right-0 z-20 bg-gray-50 dark:bg-gray-800 shadow-[-2px_0_4px_rgba(0,0,0,0.05)]', col.headerClass), children: jsxs(TextContent, { role: col.sortable ? 'button' : undefined, className: buildClassName(col.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(col), children: [col.label, col.sortable ? getSortIcon(sorting[col.name]) : null] }) }, col.name))) }) }));
1689
- const wrapperCls = buildClassName('rounded-lg border border-gray-200 dark:border-gray-800 overflow-hidden', wrapperClass);
1791
+ const Header = (jsx("div", { ref: headerRef, className: "overflow-hidden w-full", children: jsxs("div", { className: "grid bg-gray-50 dark:bg-gray-800 border-b border-[var(--ui-border)]", style: { gridTemplateColumns: gridTemplate, minWidth: 'fit-content' }, children: [selectable && (jsx("div", { role: "columnheader", className: buildClassName('flex items-center border-r last:border-r-0 border-[var(--ui-border)]', densityCellClass), children: jsx(Checkbox, { "aria-label": "Select all rows", checked: allSelected, ref: (el) => {
1792
+ if (el)
1793
+ el.indeterminate = someSelected;
1794
+ }, onChange: toggleAll }) })), columns.map((col) => (jsx("div", { role: "columnheader", className: buildClassName('font-semibold text-sm whitespace-nowrap flex items-center', densityCellClass, 'border-r last:border-r-0 border-[var(--ui-border)]', col.sticky === 'left' &&
1795
+ 'sticky left-0 z-20 bg-gray-50 dark:bg-gray-800 shadow-[2px_0_4px_rgba(0,0,0,0.05)]', col.sticky === 'right' &&
1796
+ 'sticky right-0 z-20 bg-gray-50 dark:bg-gray-800 shadow-[-2px_0_4px_rgba(0,0,0,0.05)]', col.headerClass), children: jsxs(TextContent, { role: col.sortable ? 'button' : undefined, className: buildClassName(col.sortable && 'inline-flex items-center gap-2 cursor-pointer select-none'), onClick: () => handleSort(col), children: [col.label, col.sortable ? getSortIcon(sorting[col.name]) : null] }) }, col.name)))] }) }));
1797
+ const wrapperCls = buildClassName('rounded-lg border border-[var(--ui-border)] overflow-hidden', wrapperClass);
1690
1798
  /* -------------------------------------------------------
1691
1799
  * Loading state
1692
1800
  * ------------------------------------------------------- */
1693
1801
  if (loading) {
1694
- return (jsx("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: jsxs("div", { className: wrapperCls, children: [Header, jsx("div", { style: { height: maxHeight }, className: "flex flex-col", children: Array.from({ length: skeletonRows }).map((_, idx) => (jsx("div", { "data-testid": "skeleton-row", className: "grid animate-pulse bg-white dark:bg-gray-900 border-b border-gray-100 dark:border-gray-800", style: { gridTemplateColumns: gridTemplate, height: rowHeight }, children: columns.map((col) => (jsx("div", { className: densityCellClass, children: jsx("div", { className: "h-4 w-3/4 bg-gray-300 dark:bg-gray-700 rounded" }) }, col.name))) }, idx))) })] }) }));
1802
+ return (jsx("div", { className: buildClassName('w-full rounded-lg relative', containerClass), children: jsxs("div", { className: wrapperCls, children: [Header, jsx("div", { style: { height: maxHeight }, className: "flex flex-col", children: Array.from({ length: skeletonRows }).map((_, idx) => (jsxs("div", { "data-testid": "skeleton-row", className: "grid animate-pulse bg-white dark:bg-gray-900 border-b border-[var(--ui-border-muted)]", style: { gridTemplateColumns: gridTemplate, height: rowHeight }, children: [selectable && jsx("div", { className: densityCellClass }), columns.map((col) => (jsx("div", { className: densityCellClass, children: jsx("div", { className: "h-4 w-3/4 bg-gray-300 dark:bg-gray-700 rounded" }) }, col.name)))] }, idx))) })] }) }));
1695
1803
  }
1696
1804
  /* -------------------------------------------------------
1697
1805
  * Empty state
@@ -1741,5 +1849,5 @@ const useIsTabletOrMobile = () => {
1741
1849
  return isMobile || isTablet;
1742
1850
  };
1743
1851
 
1744
- export { Accordion, Alert, Badge, Banner, BodyText, Breadcrumb, Button, ButtonGroup, Card, Checkbox, CheckboxGroup, DOTS, DataTable, DetailedInformation, Dot, Drawer, Dropdown, EmptyState, EmptyTableRow, HeadingText, Input, Label, Loader, PASSWORD_PLACEHOLDER, PASSWORD_TYPE, Pagination, PasswordInput, Radio, RadioGroup, RadioSwitch, RangeInput, RangeSlider, SelectBox, SortIconMap, Table, TableBody, TableCell, TableFoot, TableHead, TableHeaderCell, TableRow, Tabs, TextContent, Textarea, Toast, ToastProvider, VirtualizedDataTable, buildClassName, buildInputClass, get, getSortIcon, isArray, isEmpty, nextSortDirection, updateSortQuery, useDebounce, useDebounceFn, useIsMobile, useIsTablet, useIsTabletOrMobile, usePagination, useToast };
1852
+ export { Accordion, Alert, Badge, Banner, BodyText, Breadcrumb, Button, ButtonGroup, Card, Checkbox, CheckboxGroup, DOTS, DataTable, DetailedInformation, Dot, Drawer, Dropdown, EmptyState, EmptyTableRow, HeadingText, Input, Label, Loader, PASSWORD_PLACEHOLDER, PASSWORD_TYPE, Pagination, PasswordInput, Radio, RadioGroup, RadioSwitch, RangeInput, RangeSlider, SelectBox, SortIconMap, Table, TableBody, TableCell, TableFoot, TableHead, TableHeaderCell, TableRow, Tabs, TextContent, Textarea, Toast, ToastProvider, VirtualizedDataTable, buildClassName, buildInputClass, get, getSortIcon, isArray, isEmpty, nextSortDirection, updateSortQuery, useDebounce, useDebounceFn, useIsMobile, useIsTablet, useIsTabletOrMobile, usePagination, useRowSelection, useToast };
1745
1853
  //# sourceMappingURL=react-tailwind.es.js.map