@hyddenlabs/hydn-ui 0.3.0-alpha.188 → 0.3.0-alpha.189

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.cjs CHANGED
@@ -3970,6 +3970,110 @@ function CodeBlock({ code, className = "", showCopy = true }) {
3970
3970
  }
3971
3971
  CodeBlock.displayName = "CodeBlock";
3972
3972
  var code_block_default = CodeBlock;
3973
+ function Input({
3974
+ value,
3975
+ defaultValue,
3976
+ onChange,
3977
+ onFocus,
3978
+ onBlur,
3979
+ placeholder,
3980
+ disabled = false,
3981
+ type = "text",
3982
+ ariaLabel,
3983
+ ref,
3984
+ id,
3985
+ name,
3986
+ required = false,
3987
+ size = "md",
3988
+ width,
3989
+ validationState = "default",
3990
+ autoComplete,
3991
+ maxLength,
3992
+ minLength,
3993
+ pattern,
3994
+ title,
3995
+ readOnly = false
3996
+ }) {
3997
+ const widthClass = width ? inputWidthSizes[width] : "w-full";
3998
+ const inputClasses = `${getInputClasses(size, validationState)} ${widthClass}`.trim();
3999
+ return /* @__PURE__ */ jsxRuntime.jsx(
4000
+ "input",
4001
+ {
4002
+ type,
4003
+ value,
4004
+ defaultValue,
4005
+ ref,
4006
+ onChange,
4007
+ onFocus,
4008
+ onBlur,
4009
+ placeholder,
4010
+ autoComplete,
4011
+ disabled,
4012
+ "aria-label": ariaLabel,
4013
+ id,
4014
+ name,
4015
+ required,
4016
+ readOnly,
4017
+ maxLength,
4018
+ minLength,
4019
+ pattern,
4020
+ title,
4021
+ "aria-invalid": validationState === "error",
4022
+ className: inputClasses
4023
+ }
4024
+ );
4025
+ }
4026
+ Input.displayName = "Input";
4027
+ var input_default = Input;
4028
+ var containerBaseClasses = "inline-flex items-stretch rounded-lg border shadow-sm bg-background focus-within:ring-2 focus-within:ring-ring/20 transition-colors duration-150 overflow-hidden";
4029
+ var inputResetClasses = [
4030
+ "[&>input]:border-0 [&>input]:shadow-none [&>input]:rounded-none [&>input]:ring-0",
4031
+ "[&>input]:focus:ring-0 [&>input]:focus:border-0 [&>input]:bg-transparent",
4032
+ "[&>input]:flex-1 [&>input]:min-w-0"
4033
+ ].join(" ");
4034
+ var buttonResetClasses = [
4035
+ "[&_button]:rounded-none [&_button]:border-0 [&_button]:shadow-none [&_button]:m-0",
4036
+ "[&_button]:h-full"
4037
+ ].join(" ");
4038
+ function InputGroup({
4039
+ children,
4040
+ prefix,
4041
+ suffix,
4042
+ validationState = "default",
4043
+ disabled = false,
4044
+ className
4045
+ }) {
4046
+ const isTextPrefix = typeof prefix === "string" || typeof prefix === "number";
4047
+ const isTextSuffix = typeof suffix === "string" || typeof suffix === "number";
4048
+ const borderClass = validationState === "default" ? "border-input focus-within:border-ring" : validationBorderClasses[validationState].split(" ")[0];
4049
+ const disabledClass = disabled ? "opacity-50 cursor-not-allowed" : "";
4050
+ const enhancedChild = React.isValidElement(children) && disabled ? React.cloneElement(children, { disabled: true }) : children;
4051
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4052
+ "div",
4053
+ {
4054
+ className: `${containerBaseClasses} ${borderClass} ${inputResetClasses} ${buttonResetClasses} ${disabledClass} ${className ?? ""}`.trim(),
4055
+ children: [
4056
+ prefix && /* @__PURE__ */ jsxRuntime.jsx(
4057
+ "div",
4058
+ {
4059
+ className: `flex items-center shrink-0 ${isTextPrefix ? "px-3 bg-muted/50 text-muted-foreground text-sm" : "px-3 text-muted-foreground"}`,
4060
+ children: prefix
4061
+ }
4062
+ ),
4063
+ enhancedChild,
4064
+ suffix && /* @__PURE__ */ jsxRuntime.jsx(
4065
+ "div",
4066
+ {
4067
+ className: isTextSuffix ? "flex items-center px-3 bg-muted/50 text-muted-foreground text-sm shrink-0" : "flex items-stretch shrink-0",
4068
+ children: suffix
4069
+ }
4070
+ )
4071
+ ]
4072
+ }
4073
+ );
4074
+ }
4075
+ InputGroup.displayName = "InputGroup";
4076
+ var input_group_default = InputGroup;
3973
4077
  function Table({
3974
4078
  children,
3975
4079
  className = "",
@@ -4100,15 +4204,41 @@ function EmptyState({ title, description, icon, action, className = "" }) {
4100
4204
  }
4101
4205
  EmptyState.displayName = "EmptyState";
4102
4206
  var empty_state_default = EmptyState;
4103
- function useTable({ data, initialSort, pageSize = 10 }) {
4207
+ function useTable({
4208
+ data,
4209
+ initialSort,
4210
+ pageSize = 10,
4211
+ searchQuery = "",
4212
+ searchKeys
4213
+ }) {
4104
4214
  const [sortConfig, setSortConfig] = React.useState(
4105
4215
  initialSort ? { key: initialSort.key, direction: initialSort.direction } : null
4106
4216
  );
4107
4217
  const [currentPage, setCurrentPage] = React.useState(1);
4108
4218
  const [selectedRows, setSelectedRows] = React.useState(/* @__PURE__ */ new Set());
4219
+ React.useEffect(() => {
4220
+ setCurrentPage(1);
4221
+ }, [searchQuery]);
4222
+ const filteredData = React.useMemo(() => {
4223
+ if (!searchQuery || searchQuery.trim() === "") return data;
4224
+ const query = searchQuery.toLowerCase();
4225
+ return data.filter((row) => {
4226
+ if (searchKeys && searchKeys.length > 0) {
4227
+ return searchKeys.some((key) => {
4228
+ const value = row[key];
4229
+ if (value == null) return false;
4230
+ return String(value).toLowerCase().includes(query);
4231
+ });
4232
+ }
4233
+ return Object.values(row).some((value) => {
4234
+ if (value == null) return false;
4235
+ return String(value).toLowerCase().includes(query);
4236
+ });
4237
+ });
4238
+ }, [data, searchQuery, searchKeys]);
4109
4239
  const sortedData = React.useMemo(() => {
4110
- if (!sortConfig) return data;
4111
- const sorted = [...data].sort((a, b) => {
4240
+ if (!sortConfig) return filteredData;
4241
+ const sorted = [...filteredData].sort((a, b) => {
4112
4242
  const aValue = a[sortConfig.key];
4113
4243
  const bValue = b[sortConfig.key];
4114
4244
  if (aValue === bValue) return 0;
@@ -4120,7 +4250,7 @@ function useTable({ data, initialSort, pageSize = 10 }) {
4120
4250
  return sortConfig.direction === "asc" ? 1 : -1;
4121
4251
  });
4122
4252
  return sorted;
4123
- }, [data, sortConfig]);
4253
+ }, [filteredData, sortConfig]);
4124
4254
  const totalPages = Math.ceil(sortedData.length / pageSize);
4125
4255
  const startIndex = (currentPage - 1) * pageSize;
4126
4256
  const endIndex = startIndex + pageSize;
@@ -4170,6 +4300,7 @@ function useTable({ data, initialSort, pageSize = 10 }) {
4170
4300
  return {
4171
4301
  currentData,
4172
4302
  sortedData,
4303
+ filteredData,
4173
4304
  sortConfig,
4174
4305
  handleSort,
4175
4306
  currentPage,
@@ -4201,6 +4332,10 @@ function DataTable({
4201
4332
  paginated = false,
4202
4333
  pageSize = 10,
4203
4334
  selectable = false,
4335
+ searchable = false,
4336
+ searchKeys,
4337
+ searchPlaceholder = "Search...",
4338
+ onSearchChange,
4204
4339
  actions,
4205
4340
  actionsLabel = "Actions",
4206
4341
  actionsWidth = "w-32",
@@ -4212,14 +4347,24 @@ function DataTable({
4212
4347
  title,
4213
4348
  initialSort
4214
4349
  }) {
4350
+ const [searchQuery, setSearchQuery] = React.useState("");
4351
+ const handleSearchChange = (value) => {
4352
+ setSearchQuery(value);
4353
+ if (onSearchChange) {
4354
+ onSearchChange(value);
4355
+ }
4356
+ };
4215
4357
  const tableOptions = {
4216
4358
  data,
4217
4359
  initialSort,
4218
- pageSize
4360
+ pageSize,
4361
+ searchQuery,
4362
+ searchKeys
4219
4363
  };
4220
4364
  const {
4221
4365
  currentData,
4222
4366
  sortedData,
4367
+ filteredData,
4223
4368
  sortConfig,
4224
4369
  handleSort,
4225
4370
  currentPage,
@@ -4235,7 +4380,7 @@ function DataTable({
4235
4380
  isAllSelected
4236
4381
  } = useTable(tableOptions);
4237
4382
  const displayData = paginated ? currentData : sortedData;
4238
- const hasHeader = Boolean(title && String(title).length > 0 || headerActions);
4383
+ const hasHeader = Boolean(title && String(title).length > 0 || headerActions || searchable);
4239
4384
  const handleToggleRow = (index) => {
4240
4385
  toggleRow(index);
4241
4386
  if (onSelectionChange) {
@@ -4320,126 +4465,152 @@ function DataTable({
4320
4465
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border border-border rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(empty_state_default, { title: emptyMessage, icon: emptyIcon, className: "py-12" }) });
4321
4466
  }
4322
4467
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
4323
- hasHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
4324
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground", children: title }),
4325
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: Array.isArray(headerActions) && headerActions.map((act, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
4326
- button_default,
4327
- {
4328
- onClick: act.onClick,
4329
- variant: act.variant,
4330
- style: act.style,
4331
- size: act.size,
4332
- className: act.className,
4333
- ariaLabel: act.label && act.icon && !act.label ? act.label : void 0,
4334
- children: [
4335
- act.icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: act.icon, size: "sm" }) : null,
4336
- act.label
4337
- ]
4338
- },
4339
- idx
4340
- )) })
4341
- ] }),
4342
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${stickyHeader ? "overflow-auto max-h-[600px]" : ""} overflow-x-auto`, children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { striped, bordered, hoverable, compact, children: [
4343
- /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { className: stickyHeader ? "sticky top-0 z-10 bg-background shadow-sm" : "", children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { children: [
4344
- selectable && /* @__PURE__ */ jsxRuntime.jsx(TableHeadCell, { className: "w-12", children: /* @__PURE__ */ jsxRuntime.jsx(checkbox_default, { checked: isAllSelected, onChange: handleToggleAll, ariaLabel: "Select all rows" }) }),
4345
- columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
4346
- TableHeadCell,
4468
+ hasHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 mb-3", children: [
4469
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground", children: title }),
4470
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
4471
+ searchable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 max-w-md", children: /* @__PURE__ */ jsxRuntime.jsx(input_group_default, { prefix: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "search", size: "sm" }), className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
4472
+ input_default,
4347
4473
  {
4348
- align: column.align,
4349
- className: column.width ? `w-[${column.width}]` : "",
4350
- children: column.sortable !== false && sortable ? /* @__PURE__ */ jsxRuntime.jsxs(
4351
- "button",
4352
- {
4353
- onClick: () => handleSort(column.key),
4354
- className: "flex items-center gap-1 hover:text-foreground transition-colors font-medium",
4355
- type: "button",
4356
- children: [
4357
- column.label,
4358
- renderSortIcon(column.key)
4359
- ]
4360
- }
4361
- ) : column.label
4362
- },
4363
- String(column.key)
4364
- )),
4365
- actions && /* @__PURE__ */ jsxRuntime.jsx(TableHeadCell, { align: "center", className: actionsWidth, children: actionsLabel })
4366
- ] }) }),
4367
- /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: displayData.map((row, rowIndex) => {
4368
- const actualIndex = paginated ? (currentPage - 1) * pageSize + rowIndex : rowIndex;
4369
- const isSelected = isRowSelected(actualIndex);
4370
- return /* @__PURE__ */ jsxRuntime.jsxs(
4371
- TableRow,
4474
+ type: "text",
4475
+ value: searchQuery,
4476
+ onChange: (e) => handleSearchChange(e.target.value),
4477
+ placeholder: searchPlaceholder
4478
+ }
4479
+ ) }) }),
4480
+ Array.isArray(headerActions) && headerActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: headerActions.map((act, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
4481
+ button_default,
4372
4482
  {
4373
- selected: isSelected,
4374
- onClick: onRowClick ? () => onRowClick(row, actualIndex) : void 0,
4375
- className: onRowClick ? "cursor-pointer" : "",
4483
+ onClick: act.onClick,
4484
+ variant: act.variant,
4485
+ style: act.style,
4486
+ size: act.size,
4487
+ className: act.className,
4488
+ ariaLabel: act.label && act.icon && !act.label ? act.label : void 0,
4376
4489
  children: [
4377
- selectable && /* @__PURE__ */ jsxRuntime.jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
4378
- checkbox_default,
4490
+ act.icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: act.icon, size: "sm" }) : null,
4491
+ act.label
4492
+ ]
4493
+ },
4494
+ idx
4495
+ )) })
4496
+ ] })
4497
+ ] }),
4498
+ filteredData.length === 0 && searchQuery.trim() ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border border-border rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(
4499
+ empty_state_default,
4500
+ {
4501
+ title: "No results found",
4502
+ description: `No items match "${searchQuery}". Try adjusting your search.`,
4503
+ icon: "search",
4504
+ className: "py-12"
4505
+ }
4506
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4507
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${stickyHeader ? "overflow-auto max-h-[600px]" : ""} overflow-x-auto`, children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { striped, bordered, hoverable, compact, children: [
4508
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { className: stickyHeader ? "sticky top-0 z-10 bg-background shadow-sm" : "", children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { children: [
4509
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(TableHeadCell, { className: "w-12", children: /* @__PURE__ */ jsxRuntime.jsx(checkbox_default, { checked: isAllSelected, onChange: handleToggleAll, ariaLabel: "Select all rows" }) }),
4510
+ columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
4511
+ TableHeadCell,
4512
+ {
4513
+ align: column.align,
4514
+ className: column.width ? `w-[${column.width}]` : "",
4515
+ children: column.sortable !== false && sortable ? /* @__PURE__ */ jsxRuntime.jsxs(
4516
+ "button",
4379
4517
  {
4380
- checked: isSelected,
4381
- onChange: () => handleToggleRow(actualIndex),
4382
- ariaLabel: `Select row ${actualIndex + 1}`
4518
+ onClick: () => handleSort(column.key),
4519
+ className: "flex items-center gap-1 hover:text-foreground transition-colors font-medium",
4520
+ type: "button",
4521
+ children: [
4522
+ column.label,
4523
+ renderSortIcon(column.key)
4524
+ ]
4383
4525
  }
4384
- ) }),
4385
- columns.map((column) => {
4386
- const value = row[column.key];
4387
- const content = renderCellContent(value, column, row, actualIndex);
4388
- return /* @__PURE__ */ jsxRuntime.jsx(TableCell, { align: column.align, wrapText: column.wrapText, children: content }, String(column.key));
4389
- }),
4390
- actions && /* @__PURE__ */ jsxRuntime.jsx(TableCell, { align: "center", onClick: (e) => e.stopPropagation(), children: (() => {
4391
- let rowActions;
4392
- if (Array.isArray(actions)) {
4393
- rowActions = actions;
4394
- } else {
4395
- const result = actions(row, actualIndex);
4396
- if (Array.isArray(result)) {
4397
- rowActions = result;
4398
- } else {
4399
- return result;
4526
+ ) : column.label
4527
+ },
4528
+ String(column.key)
4529
+ )),
4530
+ actions && /* @__PURE__ */ jsxRuntime.jsx(TableHeadCell, { align: "center", className: actionsWidth, children: actionsLabel })
4531
+ ] }) }),
4532
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: displayData.map((row, rowIndex) => {
4533
+ const actualIndex = paginated ? (currentPage - 1) * pageSize + rowIndex : rowIndex;
4534
+ const isSelected = isRowSelected(actualIndex);
4535
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4536
+ TableRow,
4537
+ {
4538
+ selected: isSelected,
4539
+ onClick: onRowClick ? () => onRowClick(row, actualIndex) : void 0,
4540
+ className: onRowClick ? "cursor-pointer" : "",
4541
+ children: [
4542
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
4543
+ checkbox_default,
4544
+ {
4545
+ checked: isSelected,
4546
+ onChange: () => handleToggleRow(actualIndex),
4547
+ ariaLabel: `Select row ${actualIndex + 1}`
4400
4548
  }
4401
- }
4402
- return /* @__PURE__ */ jsxRuntime.jsx(stack_default, { direction: "horizontal", spacing: "sm", justify: "center", children: rowActions.map((action, actionIndex) => {
4403
- if (action && typeof action === "object" && "onClick" in action) {
4404
- const actionConfig = action;
4405
- const button = /* @__PURE__ */ jsxRuntime.jsx(
4406
- icon_button_default,
4407
- {
4408
- icon: actionConfig.icon,
4409
- iconSize: actionConfig.iconSize || "md",
4410
- buttonStyle: "ghost",
4411
- variant: actionConfig.variant || "neutral",
4412
- iconColor: actionConfig.iconColor,
4413
- ariaLabel: actionConfig.label,
4414
- onClick: () => actionConfig.onClick(row, actualIndex)
4415
- },
4416
- actionIndex
4417
- );
4418
- return actionConfig.tooltip ? /* @__PURE__ */ jsxRuntime.jsx(tooltip_default, { content: actionConfig.tooltip, children: button }, actionIndex) : button;
4549
+ ) }),
4550
+ columns.map((column) => {
4551
+ const value = row[column.key];
4552
+ const content = renderCellContent(value, column, row, actualIndex);
4553
+ return /* @__PURE__ */ jsxRuntime.jsx(TableCell, { align: column.align, wrapText: column.wrapText, children: content }, String(column.key));
4554
+ }),
4555
+ actions && /* @__PURE__ */ jsxRuntime.jsx(TableCell, { align: "center", onClick: (e) => e.stopPropagation(), children: (() => {
4556
+ let rowActions;
4557
+ if (Array.isArray(actions)) {
4558
+ rowActions = actions;
4419
4559
  } else {
4420
- return /* @__PURE__ */ jsxRuntime.jsx("div", { children: action }, actionIndex);
4560
+ const result = actions(row, actualIndex);
4561
+ if (Array.isArray(result)) {
4562
+ rowActions = result;
4563
+ } else {
4564
+ return result;
4565
+ }
4421
4566
  }
4422
- }) });
4423
- })() })
4424
- ]
4425
- },
4426
- actualIndex
4427
- );
4428
- }) })
4429
- ] }) }),
4430
- paginated && totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-t border-border", children: [
4431
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-muted-foreground", children: [
4432
- "Page ",
4433
- currentPage,
4434
- " of ",
4435
- totalPages,
4436
- " (",
4437
- data.length,
4438
- " total rows)"
4439
- ] }),
4440
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
4441
- /* @__PURE__ */ jsxRuntime.jsx(button_default, { size: "sm", style: "outline", onClick: prevPage, disabled: !canPrevPage, children: "Previous" }),
4442
- /* @__PURE__ */ jsxRuntime.jsx(button_default, { size: "sm", style: "outline", onClick: nextPage, disabled: !canNextPage, children: "Next" })
4567
+ return /* @__PURE__ */ jsxRuntime.jsx(stack_default, { direction: "horizontal", spacing: "sm", justify: "center", children: rowActions.map((action, actionIndex) => {
4568
+ if (action && typeof action === "object" && "onClick" in action) {
4569
+ const actionConfig = action;
4570
+ const button = /* @__PURE__ */ jsxRuntime.jsx(
4571
+ icon_button_default,
4572
+ {
4573
+ icon: actionConfig.icon,
4574
+ iconSize: actionConfig.iconSize || "md",
4575
+ buttonStyle: "ghost",
4576
+ variant: actionConfig.variant || "neutral",
4577
+ iconColor: actionConfig.iconColor,
4578
+ ariaLabel: actionConfig.label,
4579
+ onClick: () => actionConfig.onClick(row, actualIndex)
4580
+ },
4581
+ actionIndex
4582
+ );
4583
+ return actionConfig.tooltip ? /* @__PURE__ */ jsxRuntime.jsx(tooltip_default, { content: actionConfig.tooltip, children: button }, actionIndex) : button;
4584
+ } else {
4585
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: action }, actionIndex);
4586
+ }
4587
+ }) });
4588
+ })() })
4589
+ ]
4590
+ },
4591
+ actualIndex
4592
+ );
4593
+ }) })
4594
+ ] }) }),
4595
+ paginated && totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-t border-border", children: [
4596
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-muted-foreground", children: [
4597
+ "Page ",
4598
+ currentPage,
4599
+ " of ",
4600
+ totalPages,
4601
+ " (",
4602
+ filteredData.length,
4603
+ " ",
4604
+ searchQuery.trim() ? "filtered" : "total",
4605
+ " ",
4606
+ "rows",
4607
+ searchQuery.trim() && data.length !== filteredData.length ? ` of ${data.length}` : "",
4608
+ ")"
4609
+ ] }),
4610
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
4611
+ /* @__PURE__ */ jsxRuntime.jsx(button_default, { size: "sm", style: "outline", onClick: prevPage, disabled: !canPrevPage, children: "Previous" }),
4612
+ /* @__PURE__ */ jsxRuntime.jsx(button_default, { size: "sm", style: "outline", onClick: nextPage, disabled: !canNextPage, children: "Next" })
4613
+ ] })
4443
4614
  ] })
4444
4615
  ] })
4445
4616
  ] });
@@ -5637,61 +5808,6 @@ function FormField({
5637
5808
  }
5638
5809
  FormField.displayName = "FormField";
5639
5810
  var form_field_default = FormField;
5640
- function Input({
5641
- value,
5642
- defaultValue,
5643
- onChange,
5644
- onFocus,
5645
- onBlur,
5646
- placeholder,
5647
- disabled = false,
5648
- type = "text",
5649
- ariaLabel,
5650
- ref,
5651
- id,
5652
- name,
5653
- required = false,
5654
- size = "md",
5655
- width,
5656
- validationState = "default",
5657
- autoComplete,
5658
- maxLength,
5659
- minLength,
5660
- pattern,
5661
- title,
5662
- readOnly = false
5663
- }) {
5664
- const widthClass = width ? inputWidthSizes[width] : "w-full";
5665
- const inputClasses = `${getInputClasses(size, validationState)} ${widthClass}`.trim();
5666
- return /* @__PURE__ */ jsxRuntime.jsx(
5667
- "input",
5668
- {
5669
- type,
5670
- value,
5671
- defaultValue,
5672
- ref,
5673
- onChange,
5674
- onFocus,
5675
- onBlur,
5676
- placeholder,
5677
- autoComplete,
5678
- disabled,
5679
- "aria-label": ariaLabel,
5680
- id,
5681
- name,
5682
- required,
5683
- readOnly,
5684
- maxLength,
5685
- minLength,
5686
- pattern,
5687
- title,
5688
- "aria-invalid": validationState === "error",
5689
- className: inputClasses
5690
- }
5691
- );
5692
- }
5693
- Input.displayName = "Input";
5694
- var input_default = Input;
5695
5811
  function FormInput({
5696
5812
  // FormField props
5697
5813
  label,
@@ -5891,55 +6007,6 @@ function FormTextarea({
5891
6007
  }
5892
6008
  FormTextarea.displayName = "FormTextarea";
5893
6009
  var form_textarea_default = FormTextarea;
5894
- var containerBaseClasses = "inline-flex items-stretch rounded-lg border shadow-sm bg-background focus-within:ring-2 focus-within:ring-ring/20 transition-colors duration-150 overflow-hidden";
5895
- var inputResetClasses = [
5896
- "[&>input]:border-0 [&>input]:shadow-none [&>input]:rounded-none [&>input]:ring-0",
5897
- "[&>input]:focus:ring-0 [&>input]:focus:border-0 [&>input]:bg-transparent",
5898
- "[&>input]:flex-1 [&>input]:min-w-0"
5899
- ].join(" ");
5900
- var buttonResetClasses = [
5901
- "[&_button]:rounded-none [&_button]:border-0 [&_button]:shadow-none [&_button]:m-0",
5902
- "[&_button]:h-full"
5903
- ].join(" ");
5904
- function InputGroup({
5905
- children,
5906
- prefix,
5907
- suffix,
5908
- validationState = "default",
5909
- disabled = false,
5910
- className
5911
- }) {
5912
- const isTextPrefix = typeof prefix === "string" || typeof prefix === "number";
5913
- const isTextSuffix = typeof suffix === "string" || typeof suffix === "number";
5914
- const borderClass = validationState === "default" ? "border-input focus-within:border-ring" : validationBorderClasses[validationState].split(" ")[0];
5915
- const disabledClass = disabled ? "opacity-50 cursor-not-allowed" : "";
5916
- const enhancedChild = React.isValidElement(children) && disabled ? React.cloneElement(children, { disabled: true }) : children;
5917
- return /* @__PURE__ */ jsxRuntime.jsxs(
5918
- "div",
5919
- {
5920
- className: `${containerBaseClasses} ${borderClass} ${inputResetClasses} ${buttonResetClasses} ${disabledClass} ${className ?? ""}`.trim(),
5921
- children: [
5922
- prefix && /* @__PURE__ */ jsxRuntime.jsx(
5923
- "div",
5924
- {
5925
- className: `flex items-center shrink-0 ${isTextPrefix ? "px-3 bg-muted/50 text-muted-foreground text-sm" : "px-3 text-muted-foreground"}`,
5926
- children: prefix
5927
- }
5928
- ),
5929
- enhancedChild,
5930
- suffix && /* @__PURE__ */ jsxRuntime.jsx(
5931
- "div",
5932
- {
5933
- className: isTextSuffix ? "flex items-center px-3 bg-muted/50 text-muted-foreground text-sm shrink-0" : "flex items-stretch shrink-0",
5934
- children: suffix
5935
- }
5936
- )
5937
- ]
5938
- }
5939
- );
5940
- }
5941
- InputGroup.displayName = "InputGroup";
5942
- var input_group_default = InputGroup;
5943
6010
  function MultiSelect({
5944
6011
  options,
5945
6012
  value = [],