@andreagiugni/tailwind-dashboard-ui 0.2.0 → 0.4.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.d.cts CHANGED
@@ -137,30 +137,24 @@ interface DropzoneProps {
137
137
  /** Drag-and-drop file upload area — dependency-free (native HTML5 drag/drop). */
138
138
  declare const Dropzone: React.FC<DropzoneProps>;
139
139
 
140
- interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {
141
- }
142
- declare const Table: React.FC<TableProps>;
143
- interface TableSectionProps extends React.HTMLAttributes<HTMLTableSectionElement> {
144
- }
145
- declare const TableHeader: React.FC<TableSectionProps>;
146
- declare const TableBody: React.FC<TableSectionProps>;
147
- interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
148
- }
149
- declare const TableRow: React.FC<TableRowProps>;
150
- interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
151
- isHeader?: boolean;
152
- }
153
- declare const TableCell: React.FC<TableCellProps>;
154
-
140
+ type PaginationAlign = "left" | "center" | "right" | "full";
155
141
  interface PaginationProps {
156
142
  currentPage: number;
157
143
  totalPages: number;
158
144
  onPageChange: (page: number) => void;
145
+ /**
146
+ * How the controls are laid out within the available width:
147
+ * - `left` / `center` / `right`: the compact group is left/center/right aligned.
148
+ * - `full`: stretches full width with Previous/Next pinned to the edges and the
149
+ * page indices centered between them.
150
+ * When omitted the controls shrink to their content (legacy behavior).
151
+ */
152
+ align?: PaginationAlign;
159
153
  }
160
154
  declare const Pagination: React.FC<PaginationProps>;
161
155
 
162
156
  type SortDirection = "asc" | "desc";
163
- interface DataTableColumn<T> {
157
+ interface TableColumn<T> {
164
158
  /** Key into the row object — also the value used for sorting/searching. */
165
159
  key: Extract<keyof T, string>;
166
160
  /** Column header label. */
@@ -174,25 +168,37 @@ interface DataTableColumn<T> {
174
168
  /** Extra classes applied to this column's header and body cells. */
175
169
  className?: string;
176
170
  }
177
- interface DataTableProps<T> {
171
+ interface TableProps<T = Record<string, unknown>> extends Omit<React.TableHTMLAttributes<HTMLTableElement>, "children"> {
172
+ /**
173
+ * Composable content (Table / TableHeader / TableBody / TableRow / TableCell).
174
+ * Used when `columns` is **not** provided.
175
+ */
176
+ children?: React.ReactNode;
178
177
  /** The array of row objects to display. */
179
- data: T[];
180
- /** Column definitions (label, sortable, custom render, …). */
181
- columns: DataTableColumn<T>[];
182
- /** Rows shown per page. Default: 10. */
178
+ data?: T[];
179
+ /** Column definitions. Providing this switches Table into data-driven mode. */
180
+ columns?: TableColumn<T>[];
181
+ /** Maximum number of rows shown per page. Default: 10. */
183
182
  rowsPerPage?: number;
184
183
  /** Options for the "Show N entries" selector. Default: [5, 10, 25, 50]. Pass [] to hide it. */
185
184
  rowsPerPageOptions?: number[];
186
185
  /** Render pagination controls + the entry counter. Default: true. */
187
186
  pagination?: boolean;
187
+ /**
188
+ * Alignment of the pagination controls: `left` / `center` / `right`, or `full`
189
+ * (full width with Previous/Next pinned to the edges and the page indices
190
+ * centered). Default: `right`.
191
+ */
192
+ paginationAlign?: PaginationAlign;
188
193
  /** Render the "Show N entries" selector (only when pagination is on). Default: true. */
189
194
  showSizeSelector?: boolean;
190
- /** Render the search field. Default: true. */
191
- searchable?: boolean;
195
+ /**
196
+ * Fields matched when searching. The search input is shown **only** when this
197
+ * is a non-empty array — omit it (or pass `[]`) to hide the search box.
198
+ */
199
+ searchKeys?: Extract<keyof T, string>[];
192
200
  /** Placeholder for the search field. Default: "Search...". */
193
201
  searchPlaceholder?: string;
194
- /** Keys matched when searching. Defaults to every column key. */
195
- searchKeys?: Extract<keyof T, string>[];
196
202
  /** Column sorted on first render. */
197
203
  defaultSortKey?: Extract<keyof T, string>;
198
204
  /** Initial sort direction. Default: "asc". */
@@ -203,10 +209,19 @@ interface DataTableProps<T> {
203
209
  onRowClick?: (row: T, index: number) => void;
204
210
  /** Shown when no rows match. Default: "No matching records". */
205
211
  emptyContent?: React.ReactNode;
206
- /** Extra classes for the outer wrapper. */
207
- className?: string;
208
212
  }
209
- declare function DataTable<T extends Record<string, unknown>>({ data, columns, rowsPerPage, rowsPerPageOptions, pagination, showSizeSelector, searchable, searchPlaceholder, searchKeys, defaultSortKey, defaultSortDirection, getRowId, onRowClick, emptyContent, className, }: DataTableProps<T>): React.JSX.Element;
213
+ interface TableSectionProps extends React.HTMLAttributes<HTMLTableSectionElement> {
214
+ }
215
+ declare const TableHeader: React.FC<TableSectionProps>;
216
+ declare const TableBody: React.FC<TableSectionProps>;
217
+ interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
218
+ }
219
+ declare const TableRow: React.FC<TableRowProps>;
220
+ interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
221
+ isHeader?: boolean;
222
+ }
223
+ declare const TableCell: React.FC<TableCellProps>;
224
+ declare function Table<T extends Record<string, unknown> = Record<string, unknown>>({ children, data, columns, rowsPerPage, rowsPerPageOptions, pagination, paginationAlign, showSizeSelector, searchKeys, searchPlaceholder, defaultSortKey, defaultSortDirection, getRowId, onRowClick, emptyContent, className, ...rest }: TableProps<T>): React.JSX.Element;
210
225
 
211
226
  interface BreadcrumbItem {
212
227
  label: string;
@@ -609,4 +624,4 @@ interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>,
609
624
  }
610
625
  declare const Slider: React.FC<SliderProps>;
611
626
 
612
- export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, type AccordionSelectionMode, Alert, type AlertProps, type AlertVariant, Avatar, type AvatarProps, type AvatarSize, type AvatarStatus, AvatarText, type AvatarTextProps, Badge, type BadgeColor, type BadgeProps, type BadgeSize, type BadgeVariant, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipColor, type ChipProps, type ChipSize, type ChipVariant, Code, type CodeColor, type CodeProps, type CodeSize, ColorOverrideProps, DataTable, type DataTableColumn, type DataTableProps, DatePicker, type DatePickerProps, DateTimePicker, type DateTimePickerProps, Drawer, type DrawerPlacement, type DrawerProps, Dropdown, DropdownItem, type DropdownItemProps, type DropdownItemVariant, type DropdownProps, Dropzone, type DropzoneProps, FileInput, type FileInputProps, Form, type FormProps, Input, type InputProps, Label, type LabelProps, Modal, type ModalProps, type ModalVariant, MultiSelect, type MultiSelectProps, Pagination, type PaginationProps, PasswordInput, type PasswordInputProps, Popover, type PopoverPlacement, type PopoverProps, Progress, type ProgressColor, type ProgressProps, type ProgressSize, Radio, type RadioProps, RadioSm, type RadioSmProps, Ribbon, type RibbonColor, type RibbonPosition, type RibbonProps, type RibbonVariant, Select, type SelectProps, Skeleton, type SkeletonProps, Slider, type SliderColor, type SliderProps, Snippet, type SnippetProps, type SnippetSize, type SortDirection, Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize, Switch, type SwitchProps, Tab, type TabProps, Table, TableBody, TableCell, type TableCellProps, TableHeader, type TableProps, TableRow, type TableRowProps, type TableSectionProps, Tabs, type TabsProps, type TabsVariant, TextArea, type TextAreaProps, ThemeToggleButton, type ThemeToggleButtonProps, Toast, type ToastProps, type ToastVariant, Tooltip, type TooltipPlacement, type TooltipProps, cn };
627
+ export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, type AccordionSelectionMode, Alert, type AlertProps, type AlertVariant, Avatar, type AvatarProps, type AvatarSize, type AvatarStatus, AvatarText, type AvatarTextProps, Badge, type BadgeColor, type BadgeProps, type BadgeSize, type BadgeVariant, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipColor, type ChipProps, type ChipSize, type ChipVariant, Code, type CodeColor, type CodeProps, type CodeSize, ColorOverrideProps, DatePicker, type DatePickerProps, DateTimePicker, type DateTimePickerProps, Drawer, type DrawerPlacement, type DrawerProps, Dropdown, DropdownItem, type DropdownItemProps, type DropdownItemVariant, type DropdownProps, Dropzone, type DropzoneProps, FileInput, type FileInputProps, Form, type FormProps, Input, type InputProps, Label, type LabelProps, Modal, type ModalProps, type ModalVariant, MultiSelect, type MultiSelectProps, Pagination, type PaginationAlign, type PaginationProps, PasswordInput, type PasswordInputProps, Popover, type PopoverPlacement, type PopoverProps, Progress, type ProgressColor, type ProgressProps, type ProgressSize, Radio, type RadioProps, RadioSm, type RadioSmProps, Ribbon, type RibbonColor, type RibbonPosition, type RibbonProps, type RibbonVariant, Select, type SelectProps, Skeleton, type SkeletonProps, Slider, type SliderColor, type SliderProps, Snippet, type SnippetProps, type SnippetSize, type SortDirection, Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize, Switch, type SwitchProps, Tab, type TabProps, Table, TableBody, TableCell, type TableCellProps, type TableColumn, TableHeader, type TableProps, TableRow, type TableRowProps, type TableSectionProps, Tabs, type TabsProps, type TabsVariant, TextArea, type TextAreaProps, ThemeToggleButton, type ThemeToggleButtonProps, Toast, type ToastProps, type ToastVariant, Tooltip, type TooltipPlacement, type TooltipProps, cn };
package/dist/index.d.ts CHANGED
@@ -137,30 +137,24 @@ interface DropzoneProps {
137
137
  /** Drag-and-drop file upload area — dependency-free (native HTML5 drag/drop). */
138
138
  declare const Dropzone: React.FC<DropzoneProps>;
139
139
 
140
- interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {
141
- }
142
- declare const Table: React.FC<TableProps>;
143
- interface TableSectionProps extends React.HTMLAttributes<HTMLTableSectionElement> {
144
- }
145
- declare const TableHeader: React.FC<TableSectionProps>;
146
- declare const TableBody: React.FC<TableSectionProps>;
147
- interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
148
- }
149
- declare const TableRow: React.FC<TableRowProps>;
150
- interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
151
- isHeader?: boolean;
152
- }
153
- declare const TableCell: React.FC<TableCellProps>;
154
-
140
+ type PaginationAlign = "left" | "center" | "right" | "full";
155
141
  interface PaginationProps {
156
142
  currentPage: number;
157
143
  totalPages: number;
158
144
  onPageChange: (page: number) => void;
145
+ /**
146
+ * How the controls are laid out within the available width:
147
+ * - `left` / `center` / `right`: the compact group is left/center/right aligned.
148
+ * - `full`: stretches full width with Previous/Next pinned to the edges and the
149
+ * page indices centered between them.
150
+ * When omitted the controls shrink to their content (legacy behavior).
151
+ */
152
+ align?: PaginationAlign;
159
153
  }
160
154
  declare const Pagination: React.FC<PaginationProps>;
161
155
 
162
156
  type SortDirection = "asc" | "desc";
163
- interface DataTableColumn<T> {
157
+ interface TableColumn<T> {
164
158
  /** Key into the row object — also the value used for sorting/searching. */
165
159
  key: Extract<keyof T, string>;
166
160
  /** Column header label. */
@@ -174,25 +168,37 @@ interface DataTableColumn<T> {
174
168
  /** Extra classes applied to this column's header and body cells. */
175
169
  className?: string;
176
170
  }
177
- interface DataTableProps<T> {
171
+ interface TableProps<T = Record<string, unknown>> extends Omit<React.TableHTMLAttributes<HTMLTableElement>, "children"> {
172
+ /**
173
+ * Composable content (Table / TableHeader / TableBody / TableRow / TableCell).
174
+ * Used when `columns` is **not** provided.
175
+ */
176
+ children?: React.ReactNode;
178
177
  /** The array of row objects to display. */
179
- data: T[];
180
- /** Column definitions (label, sortable, custom render, …). */
181
- columns: DataTableColumn<T>[];
182
- /** Rows shown per page. Default: 10. */
178
+ data?: T[];
179
+ /** Column definitions. Providing this switches Table into data-driven mode. */
180
+ columns?: TableColumn<T>[];
181
+ /** Maximum number of rows shown per page. Default: 10. */
183
182
  rowsPerPage?: number;
184
183
  /** Options for the "Show N entries" selector. Default: [5, 10, 25, 50]. Pass [] to hide it. */
185
184
  rowsPerPageOptions?: number[];
186
185
  /** Render pagination controls + the entry counter. Default: true. */
187
186
  pagination?: boolean;
187
+ /**
188
+ * Alignment of the pagination controls: `left` / `center` / `right`, or `full`
189
+ * (full width with Previous/Next pinned to the edges and the page indices
190
+ * centered). Default: `right`.
191
+ */
192
+ paginationAlign?: PaginationAlign;
188
193
  /** Render the "Show N entries" selector (only when pagination is on). Default: true. */
189
194
  showSizeSelector?: boolean;
190
- /** Render the search field. Default: true. */
191
- searchable?: boolean;
195
+ /**
196
+ * Fields matched when searching. The search input is shown **only** when this
197
+ * is a non-empty array — omit it (or pass `[]`) to hide the search box.
198
+ */
199
+ searchKeys?: Extract<keyof T, string>[];
192
200
  /** Placeholder for the search field. Default: "Search...". */
193
201
  searchPlaceholder?: string;
194
- /** Keys matched when searching. Defaults to every column key. */
195
- searchKeys?: Extract<keyof T, string>[];
196
202
  /** Column sorted on first render. */
197
203
  defaultSortKey?: Extract<keyof T, string>;
198
204
  /** Initial sort direction. Default: "asc". */
@@ -203,10 +209,19 @@ interface DataTableProps<T> {
203
209
  onRowClick?: (row: T, index: number) => void;
204
210
  /** Shown when no rows match. Default: "No matching records". */
205
211
  emptyContent?: React.ReactNode;
206
- /** Extra classes for the outer wrapper. */
207
- className?: string;
208
212
  }
209
- declare function DataTable<T extends Record<string, unknown>>({ data, columns, rowsPerPage, rowsPerPageOptions, pagination, showSizeSelector, searchable, searchPlaceholder, searchKeys, defaultSortKey, defaultSortDirection, getRowId, onRowClick, emptyContent, className, }: DataTableProps<T>): React.JSX.Element;
213
+ interface TableSectionProps extends React.HTMLAttributes<HTMLTableSectionElement> {
214
+ }
215
+ declare const TableHeader: React.FC<TableSectionProps>;
216
+ declare const TableBody: React.FC<TableSectionProps>;
217
+ interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
218
+ }
219
+ declare const TableRow: React.FC<TableRowProps>;
220
+ interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
221
+ isHeader?: boolean;
222
+ }
223
+ declare const TableCell: React.FC<TableCellProps>;
224
+ declare function Table<T extends Record<string, unknown> = Record<string, unknown>>({ children, data, columns, rowsPerPage, rowsPerPageOptions, pagination, paginationAlign, showSizeSelector, searchKeys, searchPlaceholder, defaultSortKey, defaultSortDirection, getRowId, onRowClick, emptyContent, className, ...rest }: TableProps<T>): React.JSX.Element;
210
225
 
211
226
  interface BreadcrumbItem {
212
227
  label: string;
@@ -609,4 +624,4 @@ interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>,
609
624
  }
610
625
  declare const Slider: React.FC<SliderProps>;
611
626
 
612
- export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, type AccordionSelectionMode, Alert, type AlertProps, type AlertVariant, Avatar, type AvatarProps, type AvatarSize, type AvatarStatus, AvatarText, type AvatarTextProps, Badge, type BadgeColor, type BadgeProps, type BadgeSize, type BadgeVariant, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipColor, type ChipProps, type ChipSize, type ChipVariant, Code, type CodeColor, type CodeProps, type CodeSize, ColorOverrideProps, DataTable, type DataTableColumn, type DataTableProps, DatePicker, type DatePickerProps, DateTimePicker, type DateTimePickerProps, Drawer, type DrawerPlacement, type DrawerProps, Dropdown, DropdownItem, type DropdownItemProps, type DropdownItemVariant, type DropdownProps, Dropzone, type DropzoneProps, FileInput, type FileInputProps, Form, type FormProps, Input, type InputProps, Label, type LabelProps, Modal, type ModalProps, type ModalVariant, MultiSelect, type MultiSelectProps, Pagination, type PaginationProps, PasswordInput, type PasswordInputProps, Popover, type PopoverPlacement, type PopoverProps, Progress, type ProgressColor, type ProgressProps, type ProgressSize, Radio, type RadioProps, RadioSm, type RadioSmProps, Ribbon, type RibbonColor, type RibbonPosition, type RibbonProps, type RibbonVariant, Select, type SelectProps, Skeleton, type SkeletonProps, Slider, type SliderColor, type SliderProps, Snippet, type SnippetProps, type SnippetSize, type SortDirection, Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize, Switch, type SwitchProps, Tab, type TabProps, Table, TableBody, TableCell, type TableCellProps, TableHeader, type TableProps, TableRow, type TableRowProps, type TableSectionProps, Tabs, type TabsProps, type TabsVariant, TextArea, type TextAreaProps, ThemeToggleButton, type ThemeToggleButtonProps, Toast, type ToastProps, type ToastVariant, Tooltip, type TooltipPlacement, type TooltipProps, cn };
627
+ export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, type AccordionSelectionMode, Alert, type AlertProps, type AlertVariant, Avatar, type AvatarProps, type AvatarSize, type AvatarStatus, AvatarText, type AvatarTextProps, Badge, type BadgeColor, type BadgeProps, type BadgeSize, type BadgeVariant, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipColor, type ChipProps, type ChipSize, type ChipVariant, Code, type CodeColor, type CodeProps, type CodeSize, ColorOverrideProps, DatePicker, type DatePickerProps, DateTimePicker, type DateTimePickerProps, Drawer, type DrawerPlacement, type DrawerProps, Dropdown, DropdownItem, type DropdownItemProps, type DropdownItemVariant, type DropdownProps, Dropzone, type DropzoneProps, FileInput, type FileInputProps, Form, type FormProps, Input, type InputProps, Label, type LabelProps, Modal, type ModalProps, type ModalVariant, MultiSelect, type MultiSelectProps, Pagination, type PaginationAlign, type PaginationProps, PasswordInput, type PasswordInputProps, Popover, type PopoverPlacement, type PopoverProps, Progress, type ProgressColor, type ProgressProps, type ProgressSize, Radio, type RadioProps, RadioSm, type RadioSmProps, Ribbon, type RibbonColor, type RibbonPosition, type RibbonProps, type RibbonVariant, Select, type SelectProps, Skeleton, type SkeletonProps, Slider, type SliderColor, type SliderProps, Snippet, type SnippetProps, type SnippetSize, type SortDirection, Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize, Switch, type SwitchProps, Tab, type TabProps, Table, TableBody, TableCell, type TableCellProps, type TableColumn, TableHeader, type TableProps, TableRow, type TableRowProps, type TableSectionProps, Tabs, type TabsProps, type TabsVariant, TextArea, type TextAreaProps, ThemeToggleButton, type ThemeToggleButtonProps, Toast, type ToastProps, type ToastVariant, Tooltip, type TooltipPlacement, type TooltipProps, cn };
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ export { Editor } from './chunk-4OETC46A.js';
7
7
  import { cn } from './chunk-ZLIYUUA4.js';
8
8
  export { cn } from './chunk-ZLIYUUA4.js';
9
9
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
10
- import React5, { useRef, useEffect, useState, useMemo, useCallback, useId } from 'react';
10
+ import React5, { useRef, useEffect, useState, useCallback, useId, useMemo } from 'react';
11
11
  import flatpickr from 'flatpickr';
12
12
  import 'flatpickr/dist/flatpickr.css';
13
13
 
@@ -25,7 +25,7 @@ function styleOverride({
25
25
  }
26
26
  var sizeClasses = {
27
27
  sm: "px-4 py-3 text-sm",
28
- md: "px-5 py-3.5 text-sm"
28
+ md: "px-5 py-2.5 text-sm"
29
29
  };
30
30
  var variantClasses = {
31
31
  primary: "bg-brand-500 text-white shadow-theme-xs hover:bg-brand-600 disabled:bg-brand-300",
@@ -546,77 +546,87 @@ var Dropzone = ({
546
546
  }
547
547
  );
548
548
  };
549
- var Table = ({ children, className, ...rest }) => /* @__PURE__ */ jsx("table", { className: cn("min-w-full", className), ...rest, children });
550
- var TableHeader = ({ children, className, ...rest }) => /* @__PURE__ */ jsx("thead", { className, ...rest, children });
551
- var TableBody = ({ children, className, ...rest }) => /* @__PURE__ */ jsx("tbody", { className, ...rest, children });
552
- var TableRow = ({ children, className, ...rest }) => /* @__PURE__ */ jsx("tr", { className, ...rest, children });
553
- var TableCell = ({
554
- children,
555
- isHeader = false,
556
- className,
557
- ...rest
558
- }) => {
559
- const Tag = isHeader ? "th" : "td";
560
- return /* @__PURE__ */ jsx(Tag, { className, ...rest, children });
549
+ var navButton = "flex h-10 items-center justify-center rounded-lg border border-gray-300 bg-white px-3.5 py-2.5 text-sm text-gray-700 shadow-theme-xs hover:bg-gray-50 disabled:opacity-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-white/[0.03]";
550
+ var justifyByAlign = {
551
+ left: "justify-start",
552
+ center: "justify-center",
553
+ right: "justify-end"
561
554
  };
562
555
  var Pagination = ({
563
556
  currentPage,
564
557
  totalPages,
565
- onPageChange
558
+ onPageChange,
559
+ align
566
560
  }) => {
567
561
  const pagesAroundCurrent = Array.from(
568
562
  { length: Math.min(3, totalPages) },
569
563
  (_, i) => i + Math.max(currentPage - 1, 1)
570
564
  );
571
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center ", children: [
572
- /* @__PURE__ */ jsx(
573
- "button",
574
- {
575
- onClick: () => onPageChange(currentPage - 1),
576
- disabled: currentPage === 1,
577
- "aria-label": "Previous",
578
- className: cn(
579
- "mr-2.5 flex items-center h-10 justify-center rounded-lg border border-gray-300 bg-white px-3.5 py-2.5 text-gray-700 shadow-theme-xs hover:bg-gray-50 disabled:opacity-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-white/[0.03] text-sm"
580
- ),
581
- children: "Previous"
582
- }
583
- ),
584
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
585
- currentPage > 3 && /* @__PURE__ */ jsx("span", { className: "px-2", children: "..." }),
586
- pagesAroundCurrent.map((page) => /* @__PURE__ */ jsx(
587
- "button",
588
- {
589
- onClick: () => onPageChange(page),
590
- "aria-current": currentPage === page ? "page" : void 0,
591
- className: cn(
592
- "flex w-10 items-center justify-center h-10 rounded-lg text-sm font-medium",
593
- currentPage === page ? (
594
- // active page keeps its color on hover (no hover restyle)
595
- "bg-brand-500 text-white"
596
- ) : (
597
- // hover effect applies only to non-active page indices
598
- "text-gray-700 hover:bg-blue-500/[0.08] hover:text-brand-500 dark:text-gray-400 dark:hover:text-brand-500"
599
- )
600
- ),
601
- children: page
602
- },
603
- page
604
- )),
605
- currentPage < totalPages - 2 && /* @__PURE__ */ jsx("span", { className: "px-2", children: "..." })
606
- ] }),
607
- /* @__PURE__ */ jsx(
565
+ const prev = /* @__PURE__ */ jsx(
566
+ "button",
567
+ {
568
+ onClick: () => onPageChange(currentPage - 1),
569
+ disabled: currentPage === 1,
570
+ "aria-label": "Previous",
571
+ className: navButton,
572
+ children: "Previous"
573
+ }
574
+ );
575
+ const indices = /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
576
+ currentPage > 3 && /* @__PURE__ */ jsx("span", { className: "px-2", children: "..." }),
577
+ pagesAroundCurrent.map((page) => /* @__PURE__ */ jsx(
608
578
  "button",
609
579
  {
610
- onClick: () => onPageChange(currentPage + 1),
611
- disabled: currentPage === totalPages,
612
- "aria-label": "Next",
580
+ onClick: () => onPageChange(page),
581
+ "aria-current": currentPage === page ? "page" : void 0,
613
582
  className: cn(
614
- "ml-2.5 flex items-center justify-center rounded-lg border border-gray-300 bg-white px-3.5 py-2.5 text-gray-700 shadow-theme-xs text-sm hover:bg-gray-50 h-10 disabled:opacity-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-white/[0.03]"
583
+ "flex w-10 items-center justify-center h-10 rounded-lg text-sm font-medium",
584
+ currentPage === page ? (
585
+ // active page keeps its color on hover (no hover restyle)
586
+ "bg-brand-500 text-white"
587
+ ) : (
588
+ // hover effect applies only to non-active page indices
589
+ "text-gray-700 hover:bg-blue-500/[0.08] hover:text-brand-500 dark:text-gray-400 dark:hover:text-brand-500"
590
+ )
615
591
  ),
616
- children: "Next"
617
- }
618
- )
592
+ children: page
593
+ },
594
+ page
595
+ )),
596
+ currentPage < totalPages - 2 && /* @__PURE__ */ jsx("span", { className: "px-2", children: "..." })
619
597
  ] });
598
+ const next = /* @__PURE__ */ jsx(
599
+ "button",
600
+ {
601
+ onClick: () => onPageChange(currentPage + 1),
602
+ disabled: currentPage === totalPages,
603
+ "aria-label": "Next",
604
+ className: navButton,
605
+ children: "Next"
606
+ }
607
+ );
608
+ if (align === "full") {
609
+ return /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between", children: [
610
+ prev,
611
+ indices,
612
+ next
613
+ ] });
614
+ }
615
+ return /* @__PURE__ */ jsxs(
616
+ "div",
617
+ {
618
+ className: cn(
619
+ "flex items-center gap-2.5",
620
+ align && "w-full",
621
+ align && justifyByAlign[align]
622
+ ),
623
+ children: [
624
+ prev,
625
+ indices,
626
+ next
627
+ ]
628
+ }
629
+ );
620
630
  };
621
631
  var Input = ({
622
632
  className,
@@ -648,6 +658,18 @@ var Input = ({
648
658
  hint && /* @__PURE__ */ jsx("p", { className: cn("mt-1.5 text-xs", error ? "text-error-500" : success ? "text-success-500" : "text-gray-500"), children: hint })
649
659
  ] });
650
660
  };
661
+ var TableHeader = ({ children, className, ...rest }) => /* @__PURE__ */ jsx("thead", { className, ...rest, children });
662
+ var TableBody = ({ children, className, ...rest }) => /* @__PURE__ */ jsx("tbody", { className, ...rest, children });
663
+ var TableRow = ({ children, className, ...rest }) => /* @__PURE__ */ jsx("tr", { className, ...rest, children });
664
+ var TableCell = ({
665
+ children,
666
+ isHeader = false,
667
+ className,
668
+ ...rest
669
+ }) => {
670
+ const Tag = isHeader ? "th" : "td";
671
+ return /* @__PURE__ */ jsx(Tag, { className, ...rest, children });
672
+ };
651
673
  var alignClass = {
652
674
  left: "text-left",
653
675
  center: "text-center",
@@ -664,16 +686,16 @@ function SortIcon({
664
686
  /* @__PURE__ */ jsx("svg", { width: "10", height: "6", viewBox: "0 0 10 6", fill: "currentColor", "aria-hidden": "true", className: active && direction === "desc" ? on : off, children: /* @__PURE__ */ jsx("path", { d: "M5 6 1 1h8z" }) })
665
687
  ] });
666
688
  }
667
- function DataTable({
689
+ function DataDrivenTable({
668
690
  data,
669
691
  columns,
670
692
  rowsPerPage = 10,
671
693
  rowsPerPageOptions = [5, 10, 25, 50],
672
694
  pagination = true,
695
+ paginationAlign = "right",
673
696
  showSizeSelector = true,
674
- searchable = true,
675
- searchPlaceholder = "Search...",
676
697
  searchKeys,
698
+ searchPlaceholder = "Search...",
677
699
  defaultSortKey,
678
700
  defaultSortDirection = "asc",
679
701
  getRowId,
@@ -686,13 +708,13 @@ function DataTable({
686
708
  const [sortKey, setSortKey] = useState(defaultSortKey);
687
709
  const [sortDir, setSortDir] = useState(defaultSortDirection);
688
710
  const [page, setPage] = useState(1);
711
+ const showSearch = !!(searchKeys && searchKeys.length > 0);
689
712
  const filtered = useMemo(() => {
690
- const keys = searchKeys ?? columns.map((c) => c.key);
691
713
  const q = search.trim().toLowerCase();
692
714
  let rows = data;
693
- if (searchable && q) {
715
+ if (showSearch && q) {
694
716
  rows = rows.filter(
695
- (row) => keys.some((k) => String(row[k] ?? "").toLowerCase().includes(q))
717
+ (row) => searchKeys.some((k) => String(row[k] ?? "").toLowerCase().includes(q))
696
718
  );
697
719
  }
698
720
  if (sortKey) {
@@ -704,7 +726,7 @@ function DataTable({
704
726
  });
705
727
  }
706
728
  return rows;
707
- }, [data, columns, search, searchable, searchKeys, sortKey, sortDir]);
729
+ }, [data, search, showSearch, searchKeys, sortKey, sortDir]);
708
730
  const total = filtered.length;
709
731
  const totalPages = pagination ? Math.max(1, Math.ceil(total / pageSize)) : 1;
710
732
  const current = Math.min(page, totalPages);
@@ -721,7 +743,8 @@ function DataTable({
721
743
  };
722
744
  const sizeOptions = rowsPerPageOptions.length ? rowsPerPageOptions : [];
723
745
  const showSelector = pagination && showSizeSelector && sizeOptions.length > 1;
724
- const showControls = searchable || showSelector;
746
+ const showControls = showSearch || showSelector;
747
+ const counterText = total === 0 ? "Showing 0 entries" : `Showing ${start + 1} to ${Math.min(start + pageSize, total)} of ${total} entries`;
725
748
  return /* @__PURE__ */ jsxs(
726
749
  "div",
727
750
  {
@@ -748,7 +771,7 @@ function DataTable({
748
771
  ),
749
772
  "entries"
750
773
  ] }) : /* @__PURE__ */ jsx("span", {}),
751
- searchable && /* @__PURE__ */ jsx(
774
+ showSearch && /* @__PURE__ */ jsx(
752
775
  Input,
753
776
  {
754
777
  type: "search",
@@ -763,7 +786,7 @@ function DataTable({
763
786
  }
764
787
  )
765
788
  ] }),
766
- /* @__PURE__ */ jsx("div", { className: "overflow-x-auto border-y border-gray-100 dark:border-white/[0.05]", children: /* @__PURE__ */ jsxs(Table, { children: [
789
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-auto border-y border-gray-100 dark:border-white/[0.05]", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full", children: [
767
790
  /* @__PURE__ */ jsx(TableHeader, { className: "border-b border-gray-100 bg-gray-50 dark:border-white/[0.05] dark:bg-white/[0.06]", children: /* @__PURE__ */ jsx(TableRow, { children: columns.map((col) => {
768
791
  const isActive = sortKey === col.key;
769
792
  return /* @__PURE__ */ jsx(
@@ -820,14 +843,83 @@ function DataTable({
820
843
  pageRows.length === 0 && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: columns.length, className: "px-5 py-6 text-center text-sm text-gray-400", children: emptyContent }) })
821
844
  ] })
822
845
  ] }) }),
823
- pagination && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 p-4", children: [
824
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: total === 0 ? "Showing 0 entries" : `Showing ${start + 1} to ${Math.min(start + pageSize, total)} of ${total} entries` }),
825
- totalPages > 1 && /* @__PURE__ */ jsx(Pagination, { currentPage: current, totalPages, onPageChange: setPage })
826
- ] })
846
+ pagination && /* @__PURE__ */ jsx("div", { className: "p-4", children: paginationAlign === "right" ? (
847
+ // Default layout: entry counter on the left, controls on the right.
848
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
849
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: counterText }),
850
+ totalPages > 1 && /* @__PURE__ */ jsx(Pagination, { currentPage: current, totalPages, onPageChange: setPage })
851
+ ] })
852
+ ) : (
853
+ // Aligned layout: controls aligned/stretched, counter underneath.
854
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
855
+ totalPages > 1 && /* @__PURE__ */ jsx(
856
+ Pagination,
857
+ {
858
+ align: paginationAlign,
859
+ currentPage: current,
860
+ totalPages,
861
+ onPageChange: setPage
862
+ }
863
+ ),
864
+ /* @__PURE__ */ jsx(
865
+ "p",
866
+ {
867
+ className: cn(
868
+ "text-sm text-gray-500 dark:text-gray-400",
869
+ paginationAlign === "center" && "text-center"
870
+ ),
871
+ children: counterText
872
+ }
873
+ )
874
+ ] })
875
+ ) })
827
876
  ]
828
877
  }
829
878
  );
830
879
  }
880
+ function Table({
881
+ children,
882
+ data,
883
+ columns,
884
+ rowsPerPage,
885
+ rowsPerPageOptions,
886
+ pagination,
887
+ paginationAlign,
888
+ showSizeSelector,
889
+ searchKeys,
890
+ searchPlaceholder,
891
+ defaultSortKey,
892
+ defaultSortDirection,
893
+ getRowId,
894
+ onRowClick,
895
+ emptyContent,
896
+ className,
897
+ ...rest
898
+ }) {
899
+ if (columns && data) {
900
+ return /* @__PURE__ */ jsx(
901
+ DataDrivenTable,
902
+ {
903
+ data,
904
+ columns,
905
+ rowsPerPage,
906
+ rowsPerPageOptions,
907
+ pagination,
908
+ paginationAlign,
909
+ showSizeSelector,
910
+ searchKeys,
911
+ searchPlaceholder,
912
+ defaultSortKey,
913
+ defaultSortDirection,
914
+ getRowId,
915
+ onRowClick,
916
+ emptyContent,
917
+ className
918
+ }
919
+ );
920
+ }
921
+ return /* @__PURE__ */ jsx("table", { className: cn("min-w-full", className), ...rest, children });
922
+ }
831
923
  var ChevronIcon = () => /* @__PURE__ */ jsx(
832
924
  "svg",
833
925
  {
@@ -3035,6 +3127,6 @@ var Slider = ({
3035
3127
  ] });
3036
3128
  };
3037
3129
 
3038
- export { Accordion, AccordionItem, Alert, Avatar, AvatarText, Badge, Breadcrumb, Button, Card, Checkbox, Chip, Code, DataTable, DatePicker, DateTimePicker, Drawer, Dropdown, DropdownItem, Dropzone, FileInput, Form, Input, Label, MultiSelect, Pagination, PasswordInput, Popover, Progress, Radio, RadioSm, Ribbon, Select, Skeleton, Slider, Snippet, Spinner, Switch, Tab, Table, TableBody, TableCell, TableHeader, TableRow, Tabs, TextArea, ThemeToggleButton, Toast, Tooltip, styleOverride };
3130
+ export { Accordion, AccordionItem, Alert, Avatar, AvatarText, Badge, Breadcrumb, Button, Card, Checkbox, Chip, Code, DatePicker, DateTimePicker, Drawer, Dropdown, DropdownItem, Dropzone, FileInput, Form, Input, Label, MultiSelect, Pagination, PasswordInput, Popover, Progress, Radio, RadioSm, Ribbon, Select, Skeleton, Slider, Snippet, Spinner, Switch, Tab, Table, TableBody, TableCell, TableHeader, TableRow, Tabs, TextArea, ThemeToggleButton, Toast, Tooltip, styleOverride };
3039
3131
  //# sourceMappingURL=index.js.map
3040
3132
  //# sourceMappingURL=index.js.map