@eml-payments/ui-kit 1.1.5 → 1.2.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/index.css CHANGED
@@ -1,2 +1,2 @@
1
- /*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */
1
+ /*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
2
2
  @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--counter-value:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-yellow-600:oklch(68.1% .162 75.834);--color-green-600:oklch(62.7% .194 149.214);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-purple-600:oklch(55.8% .288 302.321);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-widest:.1em;--leading-relaxed:1.625;--radius-xs:.125rem;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentcolor)}::file-selector-button{border-color:var(--color-gray-200,currentcolor)}:root{--background:0 0% 100%;--foreground:0 0% 3.9%;--card:0 0% 100%;--card-foreground:0 0% 3.9%;--popover:0 0% 100%;--popover-foreground:0 0% 3.9%;--primary:0 0% 9%;--primary-foreground:0 0% 98%;--secondary:0 0% 96.1%;--secondary-foreground:0 0% 9%;--muted:0 0% 96.1%;--muted-foreground:0 0% 45.1%;--accent:0 0% 96.1%;--accent-foreground:0 0% 9%;--destructive:0 84.2% 60.2%;--destructive-foreground:0 0% 98%;--border:0 0% 89.8%;--input:0 0% 89.8%;--ring:0 0% 3.9%;--chart-1:12 76% 61%;--chart-2:173 58% 39%;--chart-3:197 37% 24%;--chart-4:43 74% 66%;--chart-5:27 87% 67%;--radius:.5rem}.dark{--background:0 0% 3.9%;--foreground:0 0% 98%;--card:0 0% 3.9%;--card-foreground:0 0% 98%;--popover:0 0% 3.9%;--popover-foreground:0 0% 98%;--primary:0 0% 98%;--primary-foreground:0 0% 9%;--secondary:0 0% 14.9%;--secondary-foreground:0 0% 98%;--muted:0 0% 14.9%;--muted-foreground:0 0% 63.9%;--accent:0 0% 14.9%;--accent-foreground:0 0% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:0 0% 98%;--border:0 0% 14.9%;--input:0 0% 14.9%;--ring:0 0% 83.1%;--chart-1:220 70% 50%;--chart-2:160 60% 45%;--chart-3:30 80% 55%;--chart-4:280 65% 60%;--chart-5:340 75% 55%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}}@layer components;@layer utilities{.\@container\/card-header{container:card-header/inline-size}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.top-2{top:calc(var(--spacing)*2)}.top-4{top:calc(var(--spacing)*4)}.top-\[50\%\]{top:50%}.right-2{right:calc(var(--spacing)*2)}.right-3{right:calc(var(--spacing)*3)}.right-4{right:calc(var(--spacing)*4)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-4{bottom:calc(var(--spacing)*4)}.left-2{left:calc(var(--spacing)*2)}.left-3{left:calc(var(--spacing)*3)}.left-4{left:calc(var(--spacing)*4)}.left-\[50\%\]{left:50%}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-96{margin-top:calc(var(--spacing)*96)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.ml-auto{margin-left:auto}.box-border{box-sizing:border-box}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.size-2{width:calc(var(--spacing)*2);height:calc(var(--spacing)*2)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-16{width:calc(var(--spacing)*16);height:calc(var(--spacing)*16)}.size-full{width:100%;height:100%}.\!h-3{height:calc(var(--spacing)*3)!important}.h-\(--radix-select-trigger-height\){height:var(--radix-select-trigger-height)}.h-2{height:calc(var(--spacing)*2)}.h-3\!{height:calc(var(--spacing)*3)!important}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-24{height:calc(var(--spacing)*24)}.h-\[12px\]{height:12px}.h-\[20px\]{height:20px}.h-\[22px\]{height:22px}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\(--radix-dropdown-menu-content-available-height\){max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-\(--radix-select-content-available-height\){max-height:var(--radix-select-content-available-height)}.max-h-\[600px\]{max-height:600px}.min-h-4{min-height:calc(var(--spacing)*4)}.min-h-\[300px\]{min-height:300px}.min-h-screen{min-height:100vh}.\!w-3{width:calc(var(--spacing)*3)!important}.w-2{width:calc(var(--spacing)*2)}.w-3\!{width:calc(var(--spacing)*3)!important}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-3\/4{width:75%}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-9{width:calc(var(--spacing)*9)}.w-56{width:calc(var(--spacing)*56)}.w-\[12px\]{width:12px}.w-\[20px\]{width:20px}.w-\[40px\]{width:40px}.w-\[200px\]{width:200px}.w-\[300px\]{width:300px}.w-\[320px\]{width:320px}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-\[calc\(100\%-2rem\)\]{max-width:calc(100% - 2rem)}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-\(--radix-select-trigger-width\){min-width:var(--radix-select-trigger-width)}.min-w-32{min-width:calc(var(--spacing)*32)}.min-w-\[200px\]{min-width:200px}.min-w-full{min-width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.origin-\(--radix-dropdown-menu-content-transform-origin\){transform-origin:var(--radix-dropdown-menu-content-transform-origin)}.origin-\(--radix-select-content-transform-origin\){transform-origin:var(--radix-select-content-transform-origin)}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-\[skeleton-wave_1\.6s_ease-in-out_infinite\]{animation:1.6s ease-in-out infinite skeleton-wave}.animate-pulse{animation:var(--animate-pulse)}.animate-slide-from-top{animation:.3s ease-out forwards slide-from-top}.animate-slide-to-top{animation:.3s ease-in forwards slide-to-top}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.auto-rows-min{grid-auto-rows:min-content}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-rows-\[auto_auto\]{grid-template-rows:auto auto}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.justify-items-start{justify-items:start}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}.gap-10{gap:calc(var(--spacing)*10)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing)*4)}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*4)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-x-reverse)))}.gap-y-0\.5{row-gap:calc(var(--spacing)*.5)}.self-start{align-self:flex-start}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:var(--uikit-radius,.5rem)}.rounded-\(--uikit-radius\){border-radius:var(--uikit-radius)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xs{border-radius:var(--radius-xs)}.rounded-t-\(--uikit-radius\){border-top-left-radius:var(--uikit-radius);border-top-right-radius:var(--uikit-radius)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[3px\]{border-style:var(--tw-border-style);border-width:3px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-none{--tw-border-style:none;border-style:none}.border-solid{--tw-border-style:solid;border-style:solid}.border-\(--uikit-error\){border-color:var(--uikit-error)}.border-\(--uikit-info\){border-color:var(--uikit-info)}.border-\(--uikit-inputEnabledBorder\){border-color:var(--uikit-inputEnabledBorder)}.border-\(--uikit-primary\){border-color:var(--uikit-primary)}.border-\(--uikit-secondary\){border-color:var(--uikit-secondary)}.border-\(--uikit-success\){border-color:var(--uikit-success)}.border-\(--uikit-warning\){border-color:var(--uikit-warning)}.border-black{border-color:var(--color-black)}.border-error{border-color:var(--uikit-error,#d7263d)}.border-gray-300{border-color:var(--color-gray-300)}.border-input{border-color:hsl(var(--input))}.border-primary{border-color:hsl(var(--primary))}.border-transparent{border-color:#0000}.\!bg-transparent{background-color:#0000!important}.bg-\(--uikit-actionDisabledBackground\){background-color:var(--uikit-actionDisabledBackground)}.bg-\(--uikit-error\),.bg-\(--uikit-error\)\/10{background-color:var(--uikit-error)}@supports (color:color-mix(in lab, red, red)){.bg-\(--uikit-error\)\/10{background-color:color-mix(in oklab,var(--uikit-error)10%,transparent)}}.bg-\(--uikit-info\){background-color:var(--uikit-info)}.bg-\(--uikit-primary\){background-color:var(--uikit-primary)}.bg-\(--uikit-primary-10\){background-color:var(--uikit-primary-10)}.bg-\(--uikit-secondary\){background-color:var(--uikit-secondary)}.bg-\(--uikit-success\),.bg-\(--uikit-success\)\/10{background-color:var(--uikit-success)}@supports (color:color-mix(in lab, red, red)){.bg-\(--uikit-success\)\/10{background-color:color-mix(in oklab,var(--uikit-success)10%,transparent)}}.bg-\(--uikit-tertiary\){background-color:var(--uikit-tertiary)}.bg-\(--uikit-warning\),.bg-\(--uikit-warning\)\/10{background-color:var(--uikit-warning)}@supports (color:color-mix(in lab, red, red)){.bg-\(--uikit-warning\)\/10{background-color:color-mix(in oklab,var(--uikit-warning)10%,transparent)}}.bg-\[\#ffffff\]{background-color:#fff}.bg-background{background-color:hsl(var(--background))}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-muted{background-color:hsl(var(--muted))}.bg-popover{background-color:hsl(var(--popover))}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-transparent{--tw-gradient-from:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.via-gray-50\/80{--tw-gradient-via:#f9fafbcc}@supports (color:color-mix(in lab, red, red)){.via-gray-50\/80{--tw-gradient-via:color-mix(in oklab,var(--color-gray-50)80%,transparent)}}.via-gray-50\/80{--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.bg-cover{background-size:cover}.bg-center{background-position:50%}.fill-\(--uikit-primary\){fill:var(--uikit-primary)}.fill-current{fill:currentColor}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-8{padding-inline:calc(var(--spacing)*8)}.px-\[4px\]{padding-inline:4px}.px-\[6px\]{padding-inline:6px}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-\[3px\]{padding-block:3px}.py-\[4px\]{padding-block:4px}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-12{padding-right:calc(var(--spacing)*12)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-10{padding-left:calc(var(--spacing)*10)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[14px\]{font-size:14px}.text-\[24px\]{font-size:24px}.leading-none{--tw-leading:1;line-height:1}.font-\(--uikit-font-family\){--tw-font-weight:var(--uikit-font-family);font-weight:var(--uikit-font-family)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.text-\(--uikit-actionActive\){color:var(--uikit-actionActive)}.text-\(--uikit-actionDisabled\){color:var(--uikit-actionDisabled)}.text-\(--uikit-error\){color:var(--uikit-error)}.text-\(--uikit-info\){color:var(--uikit-info)}.text-\(--uikit-primary\){color:var(--uikit-primary)}.text-\(--uikit-secondary\){color:var(--uikit-secondary)}.text-\(--uikit-success\){color:var(--uikit-success)}.text-\(--uikit-text-primary\){color:var(--uikit-text-primary)}.text-\(--uikit-textPrimary\){color:var(--uikit-textPrimary)}.text-\(--uikit-textSecondary\){color:var(--uikit-textSecondary)}.text-\(--uikit-warning\){color:var(--uikit-warning)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-card-foreground{color:hsl(var(--card-foreground))}.text-current{color:currentColor}.text-error{color:var(--uikit-error,#d7263d)}.text-foreground{color:hsl(var(--foreground))}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-green-600{color:var(--color-green-600)}.text-inherit{color:inherit}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-purple-600{color:var(--color-purple-600)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-transparent{color:#0000}.text-white{color:var(--color-white)}.text-yellow-600{color:var(--color-yellow-600)}.underline{text-decoration-line:underline}.opacity-10{opacity:.1}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_1px_5px_0_rgba\(0\,0\,0\,0\.12\)\,0_2px_2px_0_rgba\(0\,0\,0\,0\.14\)\,0_3px_1px_-2px_rgba\(0\,0\,0\,0\.20\)\]{--tw-shadow:0 1px 5px 0 var(--tw-shadow-color,#0000001f),0 2px 2px 0 var(--tw-shadow-color,#00000024),0 3px 1px -2px var(--tw-shadow-color,#0003);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-0{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\(--uikit-error\){--tw-ring-color:var(--uikit-error)}.ring-offset-background{--tw-ring-offset-color:hsl(var(--background))}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-none{transition-property:none}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-700{--tw-duration:.7s;transition-duration:.7s}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.duration-200{animation-duration:.2s}.duration-700{animation-duration:.7s}.ease-in{animation-timing-function:cubic-bezier(.4,0,1,1)}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-70:is(:where(.peer):disabled~*){opacity:.7}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:hsl(var(--foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:bottom-0:after{content:var(--tw-content);bottom:calc(var(--spacing)*0)}.after\:bottom-\[-3px\]:after{content:var(--tw-content);bottom:-3px}.after\:left-0:after{content:var(--tw-content);left:calc(var(--spacing)*0)}.after\:h-\[2px\]:after{content:var(--tw-content);height:2px}.after\:h-\[3px\]:after{content:var(--tw-content);height:3px}.after\:w-full:after{content:var(--tw-content);width:100%}.after\:bg-\(--uikit-primary\):after{content:var(--tw-content);background-color:var(--uikit-primary)}.after\:bg-transparent:after{content:var(--tw-content);background-color:#0000}.after\:content-\[\"\"\]:after,.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}@media (hover:hover){.hover\:cursor-pointer:hover{cursor:pointer}.hover\:rounded-\(--uikit-radius\):hover{border-radius:var(--uikit-radius)}.hover\:border:hover{border-style:var(--tw-border-style);border-width:1px}.hover\:border-none:hover{--tw-border-style:none;border-style:none}.hover\:border-\(--uikit-primary\):hover{border-color:var(--uikit-primary)}.hover\:bg-\(--uikit-error\)\/90:hover{background-color:var(--uikit-error)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\(--uikit-error\)\/90:hover{background-color:color-mix(in oklab,var(--uikit-error)90%,transparent)}}.hover\:bg-\(--uikit-primary\)\/10:hover{background-color:var(--uikit-primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\(--uikit-primary\)\/10:hover{background-color:color-mix(in oklab,var(--uikit-primary)10%,transparent)}}.hover\:bg-\(--uikit-primary\)\/90:hover{background-color:var(--uikit-primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\(--uikit-primary\)\/90:hover{background-color:color-mix(in oklab,var(--uikit-primary)90%,transparent)}}.hover\:bg-\(--uikit-secondary\):hover{background-color:var(--uikit-secondary)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-transparent:hover{background-color:#0000}.hover\:text-blue-700:hover{color:var(--color-blue-700)}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-white:hover{color:var(--color-white)}.hover\:opacity-100:hover{opacity:1}}.focus\:border-\(--uikit-primary\):focus{border-color:var(--uikit-primary)}.focus\:border-\(--uikit-secondary\):focus{border-color:var(--uikit-secondary)}.focus\:bg-\(--uikit-error\):focus{background-color:var(--uikit-error)}.focus\:bg-\(--uikit-primary\):focus{background-color:var(--uikit-primary)}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:bg-muted:focus{background-color:hsl(var(--muted))}.focus\:bg-white:focus{background-color:var(--color-white)}.focus\:text-\(--uikit-secondary\):focus{color:var(--uikit-secondary)}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:hsl(var(--ring))}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-0:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-error:focus-visible{--tw-ring-color:var(--uikit-error,#d7263d)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color:hsl(var(--background))}.focus-visible\:outline-hidden:focus-visible{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus-visible\:outline-hidden:focus-visible{outline-offset:2px;outline:2px solid #0000}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:text-muted-foreground:disabled{color:hsl(var(--muted-foreground))}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:after\:bg-transparent:disabled:after{content:var(--tw-content);background-color:#0000}@media (hover:hover){.disabled\:hover\:bg-transparent:disabled:hover{background-color:#0000}}.has-data-\[slot\=card-action\]\:grid-cols-\[1fr_auto\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-\[\>svg\]\:grid-cols-\[auto_1fr\]:has(>svg){grid-template-columns:auto 1fr}.data-disabled\:pointer-events-none[data-disabled]{pointer-events:none}.data-disabled\:opacity-50[data-disabled]{opacity:.5}.data-inset\:pl-8[data-inset]{padding-left:calc(var(--spacing)*8)}.data-placeholder\:text-muted-foreground[data-placeholder]{color:hsl(var(--muted-foreground))}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:-.5rem}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:.5rem}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:-.5rem}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:.5rem}.data-\[state\=active\]\:bg-\(--uikit-primary\)\/20[data-state=active]{background-color:var(--uikit-primary)}@supports (color:color-mix(in lab, red, red)){.data-\[state\=active\]\:bg-\(--uikit-primary\)\/20[data-state=active]{background-color:color-mix(in oklab,var(--uikit-primary)20%,transparent)}}.data-\[state\=active\]\:bg-transparent[data-state=active]{background-color:#0000}.data-\[state\=active\]\:text-\(--uikit-primary\)[data-state=active]{color:var(--uikit-primary)}.data-\[state\=active\]\:after\:bg-\(--uikit-primary\)[data-state=active]:after{content:var(--tw-content);background-color:var(--uikit-primary)}@media (hover:hover){.data-\[state\=active\]\:hover\:rounded-none[data-state=active]:hover{border-radius:0}}.data-\[state\=checked\]\:translate-x-\[21px\][data-state=checked]{--tw-translate-x:21px;translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[state\=checked\]\:bg-\(--uikit-primary\)[data-state=checked]{background-color:var(--uikit-primary)}.data-\[state\=checked\]\:text-\(--uikit-primary\)[data-state=checked]{color:var(--uikit-primary)}.data-\[state\=closed\]\:animate-out[data-state=closed]{--tw-exit-opacity:initial;--tw-exit-scale:initial;--tw-exit-rotate:initial;--tw-exit-translate-x:initial;--tw-exit-translate-y:initial;animation-name:exit;animation-duration:.15s}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}@media (hover:hover){.data-\[state\=inactive\]\:hover\:rounded-\(--uikit-radius\)[data-state=inactive]:hover{border-radius:var(--uikit-radius)}}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:hsl(var(--accent))}.data-\[state\=open\]\:text-accent-foreground[data-state=open]{color:hsl(var(--accent-foreground))}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:hsl(var(--muted-foreground))}.data-\[state\=open\]\:animate-in[data-state=open]{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[state\=unchecked\]\:translate-x-\[2px\][data-state=unchecked]{--tw-translate-x:2px;translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[state\=unchecked\]\:bg-black[data-state=unchecked]{background-color:var(--color-black)}.data-\[variant\=destructive\]\:text-destructive[data-variant=destructive]{color:hsl(var(--destructive))}.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:hsl(var(--destructive))}@supports (color:color-mix(in lab, red, red)){.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:color-mix(in oklab,hsl(var(--destructive))10%,transparent)}}.data-\[variant\=destructive\]\:focus\:text-destructive[data-variant=destructive]:focus{color:hsl(var(--destructive))}@media (min-width:40rem){.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:text-left{text-align:left}}@media (min-width:48rem){.md\:max-w-md{max-width:var(--container-md)}.md\:max-w-xl{max-width:var(--container-xl)}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (min-width:64rem){.lg\:max-w-2xl{max-width:var(--container-2xl)}}.dark\:bg-gray-700:is(.dark *){background-color:var(--color-gray-700)}.dark\:via-gray-600\/80:is(.dark *){--tw-gradient-via:#4a5565cc}@supports (color:color-mix(in lab, red, red)){.dark\:via-gray-600\/80:is(.dark *){--tw-gradient-via:color-mix(in oklab,var(--color-gray-600)80%,transparent)}}.dark\:via-gray-600\/80:is(.dark *){--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *)[data-variant=destructive]:focus{background-color:hsl(var(--destructive))}@supports (color:color-mix(in lab, red, red)){.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *)[data-variant=destructive]:focus{background-color:color-mix(in oklab,hsl(var(--destructive))20%,transparent)}}.\[\&_p\]\:leading-relaxed p{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\&_svg\]\:h-3 svg{height:calc(var(--spacing)*3)}.\[\&_svg\]\:h-4 svg{height:calc(var(--spacing)*4)}.\[\&_svg\]\:w-3 svg{width:calc(var(--spacing)*3)}.\[\&_svg\]\:w-4 svg{width:calc(var(--spacing)*4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.data-\[variant\=destructive\]\:\[\&_svg\]\:\!text-destructive[data-variant=destructive] svg{color:hsl(var(--destructive))!important}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\&_svg\:not\(\[class\*\=\'text-\'\]\)\]\:text-muted-foreground svg:not([class*=text-]){color:hsl(var(--muted-foreground))}.\[\.border-b\]\:pb-6.border-b{padding-bottom:calc(var(--spacing)*6)}.\[\.border-t\]\:pt-6.border-t{padding-top:calc(var(--spacing)*6)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\&\>svg\]\:translate-y-0\.5>svg{--tw-translate-y:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>svg\]\:text-\(--uikit-error\)>svg{color:var(--uikit-error)}.\[\&\>svg\]\:text-\(--uikit-success\)>svg{color:var(--uikit-success)}.\[\&\>svg\]\:text-\(--uikit-warning\)>svg{color:var(--uikit-warning)}.\[\&\>svg\]\:text-current>svg{color:currentColor}:root{--uikit-primary:#0a5fff;--uikit-primary-10:var(--uikit-primary)}@supports (color:color-mix(in lab, red, red)){:root{--uikit-primary-10:color-mix(in srgb,var(--uikit-primary)10%,transparent)}}:root{--uikit-secondary:#71717b;--uikit-tertiary:#f3f5fb;--uikit-accent:#e3ecff;--uikit-success:#16c784;--uikit-warning:#f4b740;--uikit-error:#d7263d;--uikit-info:#fef9bf;--uikit-radius:8px;--uikit-font-family:Inter,system-ui,sans-serif;--uikit-text-primary:#27272a}}@keyframes mui-bar1{0%{left:-35%;right:100%}60%{left:100%;right:-90%}to{left:100%;right:-90%}}@keyframes mui-bar2{0%{left:-200%;right:100%}60%{left:107%;right:-8%}to{left:107%;right:-8%}}.mui-loader{background-color:var(--uikit-primary-10);z-index:10;height:4px;position:absolute;top:37px;left:0;right:0;overflow:hidden}.mui-loader:before,.mui-loader:after{content:"";background-color:var(--uikit-primary);height:100%;position:absolute}.mui-loader:before{animation:2.5s cubic-bezier(.65,.815,.735,.395) infinite mui-bar1}.mui-loader:after{animation:2.5s cubic-bezier(.165,.84,.44,1) infinite mui-bar2}@property --counter-value{syntax:"<integer>";inherits:false;initial-value:0}.counter-animated{--counter-value:var(--counter-from,0);counter-reset:counter-num var(--counter-value)}.counter-animated.counter-active{animation:counter-animate var(--counter-duration,2s)ease-out forwards}.counter-animated .counter-number:after{content:counter(counter-num)}@keyframes counter-animate{to{--counter-value:var(--counter-to,100)}}@keyframes skeleton-wave{0%{transform:translate(-100%)}to{transform:translate(100%)}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes slide-from-top{0%{opacity:0;transform:translateY(-100%)}to{opacity:1;transform:translateY(0)}}@keyframes slide-to-top{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}
@@ -14,7 +14,7 @@ const SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) =>
14
14
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
15
15
  const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => (_jsx(SelectPrimitive.ScrollDownButton, { ref: ref, "aria-label": "Scroll down", className: cn('flex cursor-default items-center justify-center py-1', className), ...props, children: _jsx(IoMdArrowDropdown, { className: "h-4 w-4" }) })));
16
16
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
17
- const SelectContent = React.forwardRef(({ className, children, position = 'popper', disableSearch = false, searchPlaceholder = 'Search...', ...props }, ref) => {
17
+ const SelectContent = React.forwardRef(({ className, children, position = 'popper', showAlwaysSearch = false, searchPlaceholder = 'Search...', ...props }, ref) => {
18
18
  const [searchValue, setSearchValue] = React.useState('');
19
19
  const searchRef = React.useRef(null);
20
20
  const viewportRef = React.useRef(null);
@@ -38,7 +38,7 @@ const SelectContent = React.forwardRef(({ className, children, position = 'poppe
38
38
  countItems(children);
39
39
  return count;
40
40
  }, [children]);
41
- const shouldShowSearch = !disableSearch && totalItems > 7;
41
+ const shouldShowSearch = showAlwaysSearch || totalItems > 7;
42
42
  const handleSearchChange = (value) => {
43
43
  setSearchValue(value);
44
44
  setTimeout(() => {
@@ -9,4 +9,4 @@ export declare const WithLabel: Story;
9
9
  export declare const Size: Story;
10
10
  export declare const WithError: Story;
11
11
  export declare const WithManyOptions: Story;
12
- export declare const WithSearchDisabled: Story;
12
+ export declare const WithSearchEnabled: Story;
@@ -34,6 +34,6 @@ export const WithError = {
34
34
  export const WithManyOptions = {
35
35
  render: (args) => (_jsxs(Select, { ...args, children: [_jsx(SelectTrigger, { className: "w-[320px]", children: _jsx(SelectValue, { placeholder: "Select a fruit..." }) }), _jsxs(SelectContent, { searchPlaceholder: "Search fruits...", children: [_jsx(SelectScrollUpButton, { children: _jsx(FaChevronUp, { className: "h-4 w-4" }) }), _jsx(SelectScrollDownButton, { children: _jsx(FaChevronDown, { className: "h-4 w-4" }) }), _jsxs(SelectGroup, { children: [_jsx(SelectItem, { value: "apple", children: "Apple" }), _jsx(SelectItem, { value: "banana", children: "Banana" }), _jsx(SelectItem, { value: "orange", children: "Orange" }), _jsx(SelectItem, { value: "grape", children: "Grape" }), _jsx(SelectItem, { value: "pineapple", children: "Pineapple" }), _jsx(SelectItem, { value: "strawberry", children: "Strawberry" }), _jsx(SelectItem, { value: "mango", children: "Mango" }), _jsx(SelectItem, { value: "watermelon", children: "Watermelon" }), _jsx(SelectItem, { value: "kiwi", children: "Kiwi" }), _jsx(SelectItem, { value: "blueberry", children: "Blueberry" })] })] })] })),
36
36
  };
37
- export const WithSearchDisabled = {
38
- render: (args) => (_jsxs(Select, { ...args, children: [_jsx(SelectTrigger, { className: "w-[320px]", children: _jsx(SelectValue, { placeholder: "Select a fruit..." }) }), _jsxs(SelectContent, { disableSearch: true, children: [_jsx(SelectScrollUpButton, { children: _jsx(FaChevronUp, { className: "h-4 w-4" }) }), _jsx(SelectScrollDownButton, { children: _jsx(FaChevronDown, { className: "h-4 w-4" }) }), _jsxs(SelectGroup, { children: [_jsx(SelectItem, { value: "apple", children: "Apple" }), _jsx(SelectItem, { value: "banana", children: "Banana" }), _jsx(SelectItem, { value: "orange", children: "Orange" }), _jsx(SelectItem, { value: "grape", children: "Grape" }), _jsx(SelectItem, { value: "pineapple", children: "Pineapple" }), _jsx(SelectItem, { value: "strawberry", children: "Strawberry" }), _jsx(SelectItem, { value: "mango", children: "Mango" }), _jsx(SelectItem, { value: "watermelon", children: "Watermelon" }), _jsx(SelectItem, { value: "kiwi", children: "Kiwi" }), _jsx(SelectItem, { value: "blueberry", children: "Blueberry" })] })] })] })),
37
+ export const WithSearchEnabled = {
38
+ render: (args) => (_jsxs(Select, { ...args, children: [_jsx(SelectTrigger, { className: "w-[320px]", children: _jsx(SelectValue, { placeholder: "Select a fruit..." }) }), _jsxs(SelectContent, { showAlwaysSearch: true, children: [_jsx(SelectScrollUpButton, { children: _jsx(FaChevronUp, { className: "h-4 w-4" }) }), _jsx(SelectScrollDownButton, { children: _jsx(FaChevronDown, { className: "h-4 w-4" }) }), _jsxs(SelectGroup, { children: [_jsx(SelectItem, { value: "apple", children: "Apple" }), _jsx(SelectItem, { value: "banana", children: "Banana" })] })] })] })),
39
39
  };
@@ -10,6 +10,6 @@ export interface SelectTriggerProps extends ComponentProps<typeof ShadCNSelectTr
10
10
  size?: 'sm' | 'md';
11
11
  }
12
12
  export interface SelectContentProps extends ComponentProps<typeof ShadCNSelectContent> {
13
- disableSearch?: boolean;
13
+ showAlwaysSearch?: boolean;
14
14
  searchPlaceholder?: string;
15
15
  }
@@ -1,9 +1,10 @@
1
1
  import type { Table } from '@tanstack/react-table';
2
2
  import type { SelectWrapperProps } from '../../SelectWrapper';
3
+ import { PaginationMode } from '../Table.types';
3
4
  export interface PaginationControlsProps<T> {
4
5
  tableId: string;
5
6
  table: Table<T>;
6
- paginationMode?: 'client' | 'server';
7
+ paginationMode?: PaginationMode;
7
8
  totalServerRows?: number;
8
9
  pageSizeOptions?: string[];
9
10
  onPageSizeChange?: (size: number) => void;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { flexRender } from '@tanstack/react-table';
3
3
  import { classNames } from '../../utils/classNames';
4
4
  import { PaginationFooter } from './Pagination/PaginationControls';
@@ -8,26 +8,26 @@ import { DropdownWrapper } from '../DropdownWrapper';
8
8
  import { FiMoreHorizontal } from 'react-icons/fi';
9
9
  import { Button } from '../Button';
10
10
  export function Table(props) {
11
- var _a, _b;
12
- const { table, setPageSize, showHeader, ...pagination } = useTableController(props);
11
+ var _a, _b, _c, _d, _e, _f;
12
+ const { table, setPageSize, showHeader, height, virtualizationEnabled, rowVirtualizer, hasNextPage, parentScrollRef, loaderRef, ...pagination } = useTableController(props);
13
13
  let tableContent;
14
14
  if (props.isLoading && props.showSkeletonRows) {
15
- tableContent = Array.from({ length: 3 }).map((_c) => (_jsx("tr", { className: "border-t animate-pulse", children: table.getVisibleFlatColumns().map((__c) => (_jsx("td", { className: "px-4 py-2", children: _jsx("div", { className: "h-4 w-3/4 bg-(--uikit-tertiary) rounded" }) }, `skeleton-cell-${__c.id}`))) }, `skeleton-row`)));
15
+ tableContent = Array.from({ length: 3 }).map(() => (_jsx("tr", { className: "border-t animate-pulse", children: table.getVisibleFlatColumns().map((__c) => (_jsx("td", { className: "px-4 py-2", children: _jsx("div", { className: "h-4 w-3/4 bg-(--uikit-tertiary) rounded" }) }, `skeleton-cell-${__c.id}`))) }, "skeleton-row")));
16
16
  }
17
- else if (table.getRowModel().rows.length === 0) {
17
+ else if (!virtualizationEnabled && table.getRowModel().rows.length === 0) {
18
18
  const noResultsMessage = props.isSearchActive
19
19
  ? ((_a = props.noSearchResultsMessage) !== null && _a !== void 0 ? _a : 'No results meet your search criteria')
20
20
  : ((_b = props.noRowsMessage) !== null && _b !== void 0 ? _b : 'No rows to display');
21
21
  tableContent = (_jsx("tr", { children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length, className: "px-4 py-8 text-center text-muted-foreground", children: noResultsMessage }) }));
22
22
  }
23
- else {
23
+ else if (!virtualizationEnabled) {
24
24
  const renderRow = (row) => {
25
- var _a, _b, _d, _e, _f, _g, _h, _j, _k;
25
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
26
26
  const rows = [];
27
27
  const isRowClickable = (_a = props.isRowClickable) === null || _a === void 0 ? void 0 : _a.call(props, row.original);
28
28
  if (row.getIsGrouped() && row.groupingColumnId) {
29
29
  const column = table.getColumn(row.groupingColumnId);
30
- const bgColor = (_d = (_b = column === null || column === void 0 ? void 0 : column.columnDef.meta) === null || _b === void 0 ? void 0 : _b.bgColor) !== null && _d !== void 0 ? _d : 'transparent';
30
+ const bgColor = (_c = (_b = column === null || column === void 0 ? void 0 : column.columnDef.meta) === null || _b === void 0 ? void 0 : _b.bgColor) !== null && _c !== void 0 ? _c : 'transparent';
31
31
  rows.push(_jsx("tr", { className: "border-none", children: _jsx("td", { colSpan: table.getVisibleLeafColumns().length, className: "p-0", children: _jsx("div", { className: "px-4 py-4 text-sm text-muted-foreground", style: { backgroundColor: bgColor }, children: row.getGroupingValue(row.groupingColumnId) }) }) }, `group-${row.id}`));
32
32
  row.subRows.forEach((subRow) => {
33
33
  rows.push(...renderRow(subRow));
@@ -37,17 +37,24 @@ export function Table(props) {
37
37
  rows.push(_jsxs("tr", { className: classNames('border-t', isRowClickable && 'cursor-pointer', row.getIsSelected() && 'bg-(--uikit-primary-10)'), onClick: () => { var _a; return isRowClickable && ((_a = props.onRowClick) === null || _a === void 0 ? void 0 : _a.call(props, row.original)); }, children: [row.getVisibleCells().map((cell) => {
38
38
  const width = cell.column.getSize();
39
39
  return (_jsx("td", { style: { width }, className: cell.column.id === 'select' ? 'p-1' : 'p-4', children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
40
- }), props.tableActionsDropdown && (_jsx("td", { className: "w-[40px] px-2 py-2 text-right", children: _jsx(DropdownWrapper, { structure: (_e = props.tableActionsDropdown.structure) !== null && _e !== void 0 ? _e : 'default', options: props.tableActionsDropdown.getOptions(row.original), menuAlignment: props.tableActionsDropdown.menuAlignment, isTriggerElementDisabled: typeof props.tableActionsDropdown.isDisabled === 'function'
40
+ }), props.tableActionsDropdown && (_jsx("td", { className: "w-[40px] px-2 py-2 text-right", children: _jsx(DropdownWrapper, { structure: (_d = props.tableActionsDropdown.structure) !== null && _d !== void 0 ? _d : 'default', options: props.tableActionsDropdown.getOptions(row.original), menuAlignment: props.tableActionsDropdown.menuAlignment, isTriggerElementDisabled: typeof props.tableActionsDropdown.isDisabled === 'function'
41
41
  ? props.tableActionsDropdown.isDisabled(row.original)
42
- : props.tableActionsDropdown.isDisabled, triggerElement: (_h = (_g = (_f = props.tableActionsDropdown).renderCustomTrigger) === null || _g === void 0 ? void 0 : _g.call(_f, row.original)) !== null && _h !== void 0 ? _h : (_jsx(Button, { "aria-label": "Open actions menu", title: "Open actions menu", size: "icon", variant: "ghost", disabled: typeof props.tableActionsDropdown.isDisabled === 'function'
42
+ : props.tableActionsDropdown.isDisabled, triggerElement: (_g = (_f = (_e = props.tableActionsDropdown).renderCustomTrigger) === null || _f === void 0 ? void 0 : _f.call(_e, row.original)) !== null && _g !== void 0 ? _g : (_jsx(Button, { "aria-label": "Open actions menu", title: "Open actions menu", size: "icon", variant: "ghost", disabled: typeof props.tableActionsDropdown.isDisabled === 'function'
43
43
  ? props.tableActionsDropdown.isDisabled(row.original)
44
- : ((_j = props.tableActionsDropdown.isDisabled) !== null && _j !== void 0 ? _j : false), className: "p-1 focus-visible:outline-hidden focus-visible:ring-0", children: _jsx(FiMoreHorizontal, { size: 16 }) })) }) }))] }, row.original[((_k = props.rowIdKey) !== null && _k !== void 0 ? _k : 'id')]));
44
+ : ((_h = props.tableActionsDropdown.isDisabled) !== null && _h !== void 0 ? _h : false), className: "p-1 focus-visible:outline-hidden focus-visible:ring-0", children: _jsx(FiMoreHorizontal, { size: 16 }) })) }) }))] }, row.original[((_j = props.rowIdKey) !== null && _j !== void 0 ? _j : 'id')]));
45
45
  }
46
46
  return rows;
47
47
  };
48
48
  tableContent = table.getRowModel().rows.flatMap(renderRow);
49
49
  }
50
- return (_jsxs("div", { className: "relative w-full overflow-auto", children: [props.isLoading && _jsx("div", { className: "mui-loader mt-4" }), _jsx("div", { className: "rounded-t-(--uikit-radius) overflow-y-hidden overflow-x-auto", children: _jsxs("table", { className: classNames('min-w-full text-sm table-fixed bg-[#ffffff]', props.className), role: "table", id: props.id, children: [showHeader && (_jsx("thead", { className: "bg-(--uikit-tertiary)", children: table.getHeaderGroups().map((headerGroup) => (_jsxs("tr", { className: "p-4", children: [headerGroup.headers.map((header) => {
50
+ const virtualItems = virtualizationEnabled && rowVirtualizer ? rowVirtualizer.getVirtualItems() : [];
51
+ const paddingTop = virtualItems.length ? virtualItems[0].start : 0;
52
+ const lastVirtual = virtualItems[virtualItems.length - 1];
53
+ const totalSize = (_d = (_c = rowVirtualizer === null || rowVirtualizer === void 0 ? void 0 : rowVirtualizer.getTotalSize) === null || _c === void 0 ? void 0 : _c.call(rowVirtualizer)) !== null && _d !== void 0 ? _d : 0;
54
+ const end = lastVirtual ? lastVirtual.end : 0;
55
+ const paddingBottom = Math.max(totalSize - end, 0);
56
+ const tableRows = table.getRowModel().rows;
57
+ return (_jsxs("div", { ref: parentScrollRef, style: { height }, className: "relative w-full overflow-auto", children: [props.isLoading && _jsx("div", { className: "mui-loader mt-4" }), _jsx("div", { className: "rounded-t-(--uikit-radius) overflow-y-hidden overflow-x-auto", children: _jsxs("table", { className: classNames('min-w-full text-sm table-fixed bg-[#ffffff]', props.className), role: "table", id: props.id, children: [showHeader && (_jsx("thead", { className: "bg-(--uikit-tertiary)", children: table.getHeaderGroups().map((headerGroup) => (_jsxs("tr", { className: "p-4", children: [headerGroup.headers.map((header) => {
51
58
  return (_jsx("th", { style: { width: header.getSize() }, className: classNames('select-none text-[14px] font-bold ', header.id === 'select' ? 'p-0' : ' p-4 text-left cursor-pointer'), onClick: header.column.getCanSort()
52
59
  ? header.column.getToggleSortingHandler()
53
60
  : undefined, children: _jsxs("div", { className: classNames('w-full h-full', header.id === 'select'
@@ -56,5 +63,24 @@ export function Table(props) {
56
63
  asc: _jsx(FaChevronUp, {}),
57
64
  desc: _jsx(FaChevronDown, {}),
58
65
  }[header.column.getIsSorted()] || null }))] }) }, header.id));
59
- }), props.tableActionsDropdown && _jsx("th", { className: "w-[40px] px-2 py-2 text-right" })] }, headerGroup.id))) })), _jsx("tbody", { children: tableContent })] }) }), _jsx(PaginationFooter, { tableId: props.id, table: table, paginationMode: props.paginationMode, totalServerRows: props.totalServerRows, onPageSizeChange: setPageSize, ...pagination })] }));
66
+ }), props.tableActionsDropdown && _jsx("th", { className: "w-[40px] px-2 py-2 text-right" })] }, headerGroup.id))) })), _jsx("tbody", { children: virtualizationEnabled && rowVirtualizer ? (_jsxs(_Fragment, { children: [_jsx("tr", { style: { height: `${paddingTop}px` }, children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length + (props.tableActionsDropdown ? 1 : 0) }) }), virtualItems.map((vi) => {
67
+ var _a, _b, _c, _d, _e, _f;
68
+ const isLoaderRow = vi.index >= tableRows.length;
69
+ if (isLoaderRow) {
70
+ return (_jsx("tr", { className: "border-t", children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length +
71
+ (props.tableActionsDropdown ? 1 : 0), className: "px-4 py-2", children: hasNextPage ? 'Loading more...' : 'Nothing more to load' }) }, `loader-${vi.key}`));
72
+ }
73
+ const row = tableRows[vi.index];
74
+ const isRowClickable = (_a = props.isRowClickable) === null || _a === void 0 ? void 0 : _a.call(props, row.original);
75
+ return (_jsxs("tr", { className: classNames('border-t', isRowClickable && 'cursor-pointer', (row === null || row === void 0 ? void 0 : row.getIsSelected()) && 'bg-(--uikit-primary-10)'), onClick: () => { var _a; return isRowClickable && ((_a = props.onRowClick) === null || _a === void 0 ? void 0 : _a.call(props, row.original)); }, children: [row === null || row === void 0 ? void 0 : row.getVisibleCells().map((cell) => {
76
+ const width = cell.column.getSize();
77
+ return (_jsx("td", { style: { width }, className: cell.column.id === 'select' ? 'p-1' : 'p-4', children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
78
+ }), props.tableActionsDropdown && (_jsx("td", { className: "w-[40px] px-2 py-2 text-right", children: _jsx(DropdownWrapper, { structure: (_b = props.tableActionsDropdown.structure) !== null && _b !== void 0 ? _b : 'default', options: props.tableActionsDropdown.getOptions(row.original), menuAlignment: props.tableActionsDropdown.menuAlignment, isTriggerElementDisabled: typeof props.tableActionsDropdown.isDisabled === 'function'
79
+ ? props.tableActionsDropdown.isDisabled(row.original)
80
+ : props.tableActionsDropdown.isDisabled, triggerElement: (_e = (_d = (_c = props.tableActionsDropdown).renderCustomTrigger) === null || _d === void 0 ? void 0 : _d.call(_c, row.original)) !== null && _e !== void 0 ? _e : (_jsx(Button, { "aria-label": "Open actions menu", title: "Open actions menu", size: "icon", variant: "ghost", disabled: typeof props.tableActionsDropdown.isDisabled ===
81
+ 'function'
82
+ ? props.tableActionsDropdown.isDisabled(row.original)
83
+ : ((_f = props.tableActionsDropdown.isDisabled) !== null && _f !== void 0 ? _f : false), className: "p-1 focus-visible:outline-hidden focus-visible:ring-0", children: _jsx(FiMoreHorizontal, { size: 16 }) })) }) }))] }, row.id));
84
+ }), _jsx("tr", { style: { height: `${paddingBottom}px` }, children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length + (props.tableActionsDropdown ? 1 : 0) }) })] })) : (_jsxs(_Fragment, { children: [tableContent, ((_e = props.infiniteScroll) === null || _e === void 0 ? void 0 : _e.enabled) && (_jsx("tr", { ref: loaderRef, className: "border-t", children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length +
85
+ (props.tableActionsDropdown ? 1 : 0), className: "px-4 py-2", children: hasNextPage ? 'Loading more...' : 'Nothing more to load' }) }))] })) })] }) }), !((_f = props.infiniteScroll) === null || _f === void 0 ? void 0 : _f.enabled) && (_jsx(PaginationFooter, { tableId: props.id, table: table, paginationMode: props.paginationMode, totalServerRows: props.totalServerRows, onPageSizeChange: setPageSize, ...pagination }))] }));
60
86
  }
@@ -25,3 +25,5 @@ export declare const ServerSideSearch: Story;
25
25
  export declare const ClientPaginationWithQueryParams: StoryObj;
26
26
  export declare const ServerPaginationWithQueryParams: StoryObj;
27
27
  export declare const TwoTablesWithQueryParams: StoryObj;
28
+ export declare const InfiniteScrollVirtualized: StoryObj;
29
+ export declare const InfiniteScrollNonVirtual: StoryObj;
@@ -267,7 +267,7 @@ export const ServerSideSearch = {
267
267
  return (_jsxs("div", { className: "space-y-4", children: [_jsx("div", { style: { width: '300px' }, children: _jsx(SearchInput, { onSearch: (q) => setQuery(q), onClear: () => setQuery(''), placeholder: "Search users..." }) }), _jsx(Table, { id: "server-search-table", data: data, columns: columns, paginationMode: "server", totalServerRows: 100, onRefetch: fetchData, isLoading: isLoading, isSearchActive: query.trim().length >= 3 })] }));
268
268
  },
269
269
  };
270
- // Note: Does not update state search params
270
+ // Note: Does not update state search params
271
271
  export const ClientPaginationWithQueryParams = {
272
272
  args: {
273
273
  initialPageNo: 2,
@@ -283,7 +283,7 @@ export const ClientPaginationWithQueryParams = {
283
283
  ],
284
284
  render: () => (_jsxs(_Fragment, { children: [_jsx(CurrentUrl, {}), _jsx(Table, { id: "clients", data: data, columns: columns, paginationMode: "client", showHeader: true })] })),
285
285
  };
286
- // Note: Does not update state search params
286
+ // Note: Does not update state search params
287
287
  export const ServerPaginationWithQueryParams = {
288
288
  args: {
289
289
  initialPageNo: 2,
@@ -309,7 +309,7 @@ export const ServerPaginationWithQueryParams = {
309
309
  return (_jsxs(_Fragment, { children: [_jsx(CurrentUrl, {}), _jsx(Table, { id: "clients", data: data, columns: columns, paginationMode: "server", totalServerRows: 100, onRefetch: fetchData, isLoading: isLoading, showHeader: true })] }));
310
310
  },
311
311
  };
312
- // Note: Does not update state search params
312
+ // Note: Does not update state search params
313
313
  export const TwoTablesWithQueryParams = {
314
314
  args: {
315
315
  clientsInitialPageNo: 2,
@@ -337,3 +337,100 @@ export const TwoTablesWithQueryParams = {
337
337
  return (_jsxs(_Fragment, { children: [_jsx(CurrentUrl, {}), _jsxs("div", { style: { display: 'flex', gap: '2rem' }, children: [_jsx(Table, { id: "clients", data: data, columns: columns, paginationMode: "client", showHeader: true }), _jsx(Table, { id: "users", data: usersData, columns: columns, paginationMode: "server", totalServerRows: 100, onRefetch: fetchUsersData, isLoading: isLoadingUsers, showHeader: true })] })] }));
338
338
  },
339
339
  };
340
+ function fetchInfiniteUsers(limit, offset = 0) {
341
+ const start = offset * limit;
342
+ const rows = Array.from({ length: limit }).map((_, i) => {
343
+ const idx = start + i + 1;
344
+ return {
345
+ id: `user-${idx}`,
346
+ name: `User ${idx}`,
347
+ email: `user${idx}@example.com`,
348
+ role: idx % 2 === 0 ? 'Admin' : 'User',
349
+ };
350
+ });
351
+ return new Promise((resolve) => {
352
+ setTimeout(() => {
353
+ const nextOffset = offset + 1;
354
+ const maxPages = Math.ceil(100 / limit);
355
+ const hasMore = nextOffset < maxPages;
356
+ resolve({ rows, nextOffset, hasMore });
357
+ }, 300);
358
+ });
359
+ }
360
+ export const InfiniteScrollVirtualized = {
361
+ name: 'Infinite Scroll — Virtualized',
362
+ render: () => {
363
+ const [rows, setRows] = useState([]);
364
+ const [nextOffset, setNextOffset] = useState(0);
365
+ const [hasNextPage, setHasNextPage] = useState(true);
366
+ const [isFetchingNextPage, setIsFetchingNextPage] = useState(false);
367
+ useEffect(() => {
368
+ (async () => {
369
+ setIsFetchingNextPage(true);
370
+ const res = await fetchInfiniteUsers(20, 0);
371
+ setRows(res.rows);
372
+ setNextOffset(res.nextOffset);
373
+ setHasNextPage(res.hasMore);
374
+ setIsFetchingNextPage(false);
375
+ })();
376
+ }, []);
377
+ const fetchNextPage = useCallback(async () => {
378
+ if (isFetchingNextPage || !hasNextPage)
379
+ return;
380
+ setIsFetchingNextPage(true);
381
+ const res = await fetchInfiniteUsers(20, nextOffset);
382
+ setRows((prev) => [...prev, ...res.rows]);
383
+ setNextOffset(res.nextOffset);
384
+ setHasNextPage(res.hasMore);
385
+ setIsFetchingNextPage(false);
386
+ }, [isFetchingNextPage, hasNextPage, nextOffset]);
387
+ return (_jsx("div", { children: _jsx(Table, { id: "infinite-virtualized", height: 500, data: rows, columns: columns, showHeader: true, infiniteScroll: {
388
+ enabled: true,
389
+ hasNextPage,
390
+ isFetchingNextPage,
391
+ fetchNextPage,
392
+ }, virtualization: {
393
+ enabled: true,
394
+ rowEstimate: 48,
395
+ overscan: 6,
396
+ } }) }));
397
+ },
398
+ };
399
+ export const InfiniteScrollNonVirtual = {
400
+ name: 'Infinite Scroll — Non-virtual',
401
+ render: () => {
402
+ const [rows, setRows] = useState([]);
403
+ const [nextOffset, setNextOffset] = useState(0);
404
+ const [hasNextPage, setHasNextPage] = useState(true);
405
+ const [isFetchingNextPage, setIsFetchingNextPage] = useState(false);
406
+ useEffect(() => {
407
+ (async () => {
408
+ setIsFetchingNextPage(true);
409
+ const res = await fetchInfiniteUsers(20, 0);
410
+ setRows(res.rows);
411
+ setNextOffset(res.nextOffset);
412
+ setHasNextPage(res.hasMore);
413
+ setIsFetchingNextPage(false);
414
+ })();
415
+ }, []);
416
+ const fetchNextPage = useCallback(async () => {
417
+ if (isFetchingNextPage || !hasNextPage)
418
+ return;
419
+ setIsFetchingNextPage(true);
420
+ const res = await fetchInfiniteUsers(20, nextOffset);
421
+ setRows((prev) => [...prev, ...res.rows]);
422
+ setNextOffset(res.nextOffset);
423
+ setHasNextPage(res.hasMore);
424
+ setIsFetchingNextPage(false);
425
+ }, [isFetchingNextPage, hasNextPage, nextOffset]);
426
+ return (_jsx("div", { children: _jsx(Table, { id: "infinite-nonvirtual", height: "80vh", data: rows, columns: columns, showHeader: true, infiniteScroll: {
427
+ enabled: true,
428
+ hasNextPage,
429
+ isFetchingNextPage,
430
+ fetchNextPage,
431
+ rootMarginPx: 300,
432
+ }, virtualization: {
433
+ enabled: false,
434
+ } }) }));
435
+ },
436
+ };
@@ -3,8 +3,22 @@ import type { DropdownOption, DropdownStructure } from '../DropdownWrapper/Dropd
3
3
  export type FlexColumnDef<T> = ColumnDef<T> & {
4
4
  flex?: number;
5
5
  };
6
+ export type InfiniteScrollOptions = {
7
+ enabled: boolean;
8
+ hasNextPage: boolean;
9
+ isFetchingNextPage?: boolean;
10
+ fetchNextPage: () => void;
11
+ rootMarginPx?: number;
12
+ };
13
+ export type PaginationMode = 'client' | 'server' | 'none';
14
+ export interface VirtualizationOptions {
15
+ enabled: boolean;
16
+ rowEstimate?: number;
17
+ overscan?: number;
18
+ }
6
19
  export interface TableProps<T> {
7
20
  id: string;
21
+ height?: number | string;
8
22
  data: T[];
9
23
  columns: FlexColumnDef<T>[];
10
24
  rowIdKey?: keyof T | 'id';
@@ -20,7 +34,7 @@ export interface TableProps<T> {
20
34
  onRefetch?: (pageIndex: number, pageSize: number) => void;
21
35
  isMultiRowSelection?: boolean;
22
36
  totalServerRows?: number;
23
- paginationMode?: 'client' | 'server';
37
+ paginationMode?: PaginationMode;
24
38
  noRowsMessage?: string;
25
39
  rowsPerPage?: number;
26
40
  selectedRowIds?: string[];
@@ -37,4 +51,6 @@ export interface TableProps<T> {
37
51
  grouping?: string[];
38
52
  isSearchActive?: boolean;
39
53
  noSearchResultsMessage?: string;
54
+ infiniteScroll?: InfiniteScrollOptions;
55
+ virtualization?: VirtualizationOptions;
40
56
  }
@@ -0,0 +1,29 @@
1
+ import type { RefObject } from 'react';
2
+ import type { Virtualizer } from '@tanstack/react-virtual';
3
+ import type { InfiniteScrollOptions, VirtualizationOptions } from '../Table.types';
4
+ type PageEnvelope<T> = {
5
+ rows: T[];
6
+ };
7
+ export interface UseInfiniteScrollingParams<T extends {
8
+ id: string;
9
+ }> {
10
+ dataPages?: PageEnvelope<T>[] | undefined;
11
+ flatData?: T[] | undefined;
12
+ infiniteScroll?: InfiniteScrollOptions;
13
+ virtualization?: VirtualizationOptions;
14
+ parentScrollRef: RefObject<HTMLDivElement>;
15
+ loaderRef?: RefObject<HTMLElement>;
16
+ }
17
+ export interface UseInfiniteScrollingReturn<T extends {
18
+ id: string;
19
+ }> {
20
+ allRows: T[];
21
+ virtualizationEnabled: boolean;
22
+ rowVirtualizer?: Virtualizer<HTMLDivElement, Element>;
23
+ hasNextPage: boolean;
24
+ isFetchingNextPage: boolean;
25
+ }
26
+ export declare function useInfiniteScrolling<T extends {
27
+ id: string;
28
+ }>(params: UseInfiniteScrollingParams<T>): UseInfiniteScrollingReturn<T>;
29
+ export {};
@@ -0,0 +1,86 @@
1
+ import { useEffect, useMemo } from 'react';
2
+ import { useVirtualizer } from '@tanstack/react-virtual';
3
+ export function useInfiniteScrolling(params) {
4
+ var _a;
5
+ const { dataPages, flatData, infiniteScroll, virtualization, parentScrollRef, loaderRef } = params;
6
+ const isInfinite = !!(infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.enabled);
7
+ const hasNextPage = !!(infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.hasNextPage);
8
+ const isFetchingNextPage = !!(infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.isFetchingNextPage);
9
+ const fetchNextPage = infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.fetchNextPage;
10
+ const allRows = useMemo(() => {
11
+ if (isInfinite && Array.isArray(dataPages)) {
12
+ const byId = new Map();
13
+ for (const p of dataPages) {
14
+ for (const r of p.rows) {
15
+ byId.set(String(r.id), r);
16
+ }
17
+ }
18
+ return Array.from(byId.values());
19
+ }
20
+ return flatData !== null && flatData !== void 0 ? flatData : [];
21
+ }, [isInfinite, dataPages, flatData]);
22
+ const virtualizationEnabled = !!(virtualization === null || virtualization === void 0 ? void 0 : virtualization.enabled);
23
+ const rowVirtualizer = useVirtualizer({
24
+ count: allRows.length + (isInfinite && hasNextPage ? 1 : 0),
25
+ getScrollElement: () => parentScrollRef.current,
26
+ estimateSize: () => { var _a; return (_a = virtualization === null || virtualization === void 0 ? void 0 : virtualization.rowEstimate) !== null && _a !== void 0 ? _a : 48; },
27
+ measureElement: (el) => { var _a; return (_a = el === null || el === void 0 ? void 0 : el.getBoundingClientRect().height) !== null && _a !== void 0 ? _a : 48; },
28
+ overscan: (_a = virtualization === null || virtualization === void 0 ? void 0 : virtualization.overscan) !== null && _a !== void 0 ? _a : 6,
29
+ });
30
+ useEffect(() => {
31
+ if (!virtualizationEnabled || !isInfinite)
32
+ return;
33
+ if (!rowVirtualizer || !fetchNextPage)
34
+ return;
35
+ if (isFetchingNextPage || !hasNextPage)
36
+ return;
37
+ const items = rowVirtualizer.getVirtualItems();
38
+ if (!items.length)
39
+ return;
40
+ const last = items[items.length - 1];
41
+ const loaderIndex = allRows.length;
42
+ if (last.index >= loaderIndex) {
43
+ fetchNextPage();
44
+ }
45
+ });
46
+ useEffect(() => {
47
+ var _a, _b;
48
+ if (!isInfinite || virtualizationEnabled)
49
+ return;
50
+ if (!(loaderRef === null || loaderRef === void 0 ? void 0 : loaderRef.current) || !fetchNextPage)
51
+ return;
52
+ const rootMargin = `${(_a = infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.rootMarginPx) !== null && _a !== void 0 ? _a : 300}px`;
53
+ const observer = new IntersectionObserver((entries) => {
54
+ const entry = entries[0];
55
+ if (entry.isIntersecting && hasNextPage && !isFetchingNextPage) {
56
+ fetchNextPage();
57
+ }
58
+ }, {
59
+ root: (_b = parentScrollRef.current) !== null && _b !== void 0 ? _b : null,
60
+ rootMargin: `0px 0px ${rootMargin} 0px`,
61
+ threshold: 0.01,
62
+ });
63
+ const el = loaderRef.current;
64
+ observer.observe(el);
65
+ return () => {
66
+ observer.unobserve(el);
67
+ observer.disconnect();
68
+ };
69
+ }, [
70
+ isInfinite,
71
+ virtualizationEnabled,
72
+ hasNextPage,
73
+ isFetchingNextPage,
74
+ fetchNextPage,
75
+ infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.rootMarginPx,
76
+ parentScrollRef,
77
+ loaderRef,
78
+ ]);
79
+ return {
80
+ allRows,
81
+ virtualizationEnabled,
82
+ rowVirtualizer,
83
+ hasNextPage,
84
+ isFetchingNextPage,
85
+ };
86
+ }
@@ -1,7 +1,8 @@
1
1
  import type { Table } from '@tanstack/react-table';
2
+ import { PaginationMode } from '../Table.types';
2
3
  interface UsePaginationControllerOptions<T> {
3
4
  table: Table<T>;
4
- paginationMode: 'client' | 'server';
5
+ paginationMode: PaginationMode;
5
6
  onRefetch?: (pageIndex: number, pageSize: number) => void;
6
7
  }
7
8
  export declare function usePaginationController<T>({ table, paginationMode, onRefetch }: UsePaginationControllerOptions<T>): {
@@ -2,7 +2,7 @@ import { type SortingState } from '@tanstack/react-table';
2
2
  import type { TableProps } from '../Table.types';
3
3
  export declare function useTableController<T extends {
4
4
  id: string;
5
- }>({ id, data, columns, checkboxSelection, checkboxPosition, paginationMode, sorting, onSortingChange, onSelectionChange, enableRowSelection, rowsPerPage, isMultiRowSelection, selectedRowIds, rowIdKey, totalServerRows, onRefetch, showHeader, grouping, }: TableProps<T>): {
5
+ }>({ id, height, data, columns, checkboxSelection, checkboxPosition, paginationMode, sorting, onSortingChange, onSelectionChange, enableRowSelection, rowsPerPage, isMultiRowSelection, selectedRowIds, rowIdKey, totalServerRows, onRefetch, showHeader, grouping, infiniteScroll, virtualization, }: TableProps<T>): {
6
6
  pageIndex: number;
7
7
  pageSize: number;
8
8
  canNextPage: boolean;
@@ -10,9 +10,17 @@ export declare function useTableController<T extends {
10
10
  onNextPage: () => void;
11
11
  onPrevPage: () => void;
12
12
  table: import("@tanstack/table-core").Table<T>;
13
+ height: string | number | undefined;
14
+ showHeader: boolean;
15
+ grouping: string[] | undefined;
13
16
  setPageSize: import("react").Dispatch<import("react").SetStateAction<number>>;
14
17
  setPageIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
15
18
  sorting: SortingState;
16
- showHeader: boolean;
17
- grouping: string[] | undefined;
19
+ virtualizationEnabled: boolean;
20
+ rowVirtualizer: import("@tanstack/virtual-core").Virtualizer<HTMLDivElement, Element> | undefined;
21
+ hasNextPage: boolean;
22
+ parentScrollRef: import("react").RefObject<HTMLDivElement>;
23
+ loaderRef: import("react").RefObject<HTMLTableRowElement>;
24
+ infiniteScroll: import("..").InfiniteScrollOptions | undefined;
25
+ virtualization: import("..").VirtualizationOptions | undefined;
18
26
  };
@@ -1,11 +1,14 @@
1
- import { useEffect, useMemo, useState } from 'react';
1
+ import { useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { useReactTable, getCoreRowModel, getSortedRowModel, getPaginationRowModel, getGroupedRowModel, getExpandedRowModel, } from '@tanstack/react-table';
3
3
  import { applyFlexSizes, getCheckboxSelectionColumn } from '../table.helpers';
4
4
  import { usePaginationController } from './usePaginationController';
5
5
  import { useUrlPaginationSync } from './useUrlPaginationSync';
6
- export function useTableController({ id, data, columns, checkboxSelection, checkboxPosition = 'start', paginationMode = 'client', sorting, onSortingChange, onSelectionChange, enableRowSelection, rowsPerPage = 10, isMultiRowSelection = true, selectedRowIds, rowIdKey = 'id', totalServerRows, onRefetch, showHeader = true, grouping, }) {
6
+ import { useInfiniteScrolling } from './useInfiniteScrolling';
7
+ export function useTableController({ id, height, data, columns, checkboxSelection, checkboxPosition = 'start', paginationMode = 'client', sorting, onSortingChange, onSelectionChange, enableRowSelection, rowsPerPage = 10, isMultiRowSelection = true, selectedRowIds, rowIdKey = 'id', totalServerRows, onRefetch, showHeader = true, grouping, infiniteScroll, virtualization, }) {
7
8
  const safeData = Array.isArray(data) ? data : [];
8
9
  const stableGrouping = useMemo(() => grouping !== null && grouping !== void 0 ? grouping : [], [grouping]);
10
+ const parentScrollRef = useRef(null);
11
+ const loaderRef = useRef(null);
9
12
  const columnVisibility = useMemo(() => {
10
13
  return Object.fromEntries(stableGrouping.map((columnId) => [columnId, false]));
11
14
  }, [stableGrouping]);
@@ -21,8 +24,18 @@ export function useTableController({ id, data, columns, checkboxSelection, check
21
24
  return {};
22
25
  });
23
26
  const { pageIndex, setPageIndex, pageSize, setPageSize } = useUrlPaginationSync(rowsPerPage, id);
27
+ const isInfinite = !!(infiniteScroll === null || infiniteScroll === void 0 ? void 0 : infiniteScroll.enabled);
28
+ const { allRows, virtualizationEnabled, rowVirtualizer, hasNextPage } = useInfiniteScrolling({
29
+ dataPages: Array.isArray(data) ? [{ rows: data }] : undefined,
30
+ flatData: data,
31
+ infiniteScroll,
32
+ virtualization,
33
+ parentScrollRef,
34
+ loaderRef,
35
+ });
36
+ const dataForTable = useMemo(() => (virtualizationEnabled || isInfinite ? allRows : safeData), [virtualizationEnabled, isInfinite, allRows, safeData]);
24
37
  const table = useReactTable({
25
- data: safeData,
38
+ data: dataForTable,
26
39
  columns: tableColumns,
27
40
  getRowId: (row) => String(row[rowIdKey]),
28
41
  state: {
@@ -34,10 +47,10 @@ export function useTableController({ id, data, columns, checkboxSelection, check
34
47
  },
35
48
  getSortedRowModel: getSortedRowModel(),
36
49
  getCoreRowModel: getCoreRowModel(),
37
- getPaginationRowModel: paginationMode === 'client' ? getPaginationRowModel() : undefined,
38
- manualPagination: paginationMode === 'server',
50
+ getPaginationRowModel: !isInfinite && paginationMode === 'client' ? getPaginationRowModel() : undefined,
51
+ manualPagination: !isInfinite && paginationMode === 'server',
39
52
  autoResetPageIndex: false,
40
- pageCount: paginationMode === 'server' ? Math.ceil((totalServerRows !== null && totalServerRows !== void 0 ? totalServerRows : 0) / pageSize) : undefined,
53
+ pageCount: !isInfinite && paginationMode === 'server' ? Math.ceil((totalServerRows !== null && totalServerRows !== void 0 ? totalServerRows : 0) / pageSize) : undefined,
41
54
  onPaginationChange: (updater) => {
42
55
  const next = typeof updater === 'function' ? updater({ pageIndex, pageSize }) : updater;
43
56
  setPageIndex(next.pageIndex);
@@ -61,6 +74,17 @@ export function useTableController({ id, data, columns, checkboxSelection, check
61
74
  getGroupedRowModel: getGroupedRowModel(),
62
75
  getExpandedRowModel: getExpandedRowModel(),
63
76
  });
77
+ useEffect(() => {
78
+ if (paginationMode === 'none') {
79
+ setPageIndex(0);
80
+ }
81
+ }, [paginationMode, setPageIndex]);
82
+ useEffect(() => {
83
+ if (isInfinite) {
84
+ table.setPageIndex(0);
85
+ table.setPageSize(Number.MAX_SAFE_INTEGER);
86
+ }
87
+ }, [isInfinite, table]);
64
88
  const pagination = usePaginationController({
65
89
  table,
66
90
  paginationMode,
@@ -90,11 +114,19 @@ export function useTableController({ id, data, columns, checkboxSelection, check
90
114
  }, [columns, checkboxSelection, checkboxPosition]);
91
115
  return {
92
116
  table,
117
+ height,
118
+ showHeader,
119
+ grouping,
93
120
  setPageSize,
94
121
  setPageIndex,
95
122
  sorting: sorting !== null && sorting !== void 0 ? sorting : internalSorting,
96
- showHeader,
97
- grouping,
123
+ virtualizationEnabled,
124
+ rowVirtualizer,
125
+ hasNextPage,
126
+ parentScrollRef,
127
+ loaderRef,
128
+ infiniteScroll,
129
+ virtualization,
98
130
  ...pagination,
99
131
  };
100
132
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eml-payments/ui-kit",
3
- "version": "1.1.5",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "description": "ARLO UIKit",
6
6
  "homepage": "https://github.com/EML-Payments/arlo.npm.uikit#readme",
@@ -62,6 +62,7 @@
62
62
  "@radix-ui/react-tooltip": "^1.2.7",
63
63
  "@tailwindcss/postcss": "^4.1.11",
64
64
  "@tanstack/react-table": "^8.12.0",
65
+ "@tanstack/react-virtual": "^3.13.13",
65
66
  "class-variance-authority": "^0.7.1",
66
67
  "clsx": "^2.1.1",
67
68
  "prettier": "^3.6.2",
@@ -81,6 +82,7 @@
81
82
  "@storybook/addon-themes": "^10.0.2",
82
83
  "@storybook/react-vite": "^10.0.6",
83
84
  "@tailwindcss/cli": "^4.1.12",
85
+ "@types/node": "^25.0.3",
84
86
  "@typescript-eslint/eslint-plugin": "^8.35.1",
85
87
  "eslint": "^9.31.0",
86
88
  "eslint-config-prettier": "^10.1.5",