@nccirtu/tablefy 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,19 @@
1
1
  export { DataTable } from "./components/ui/data-table/data-table";
2
2
  export { DataTableSchema } from "./components/ui/data-table/data-table-schema";
3
3
  export { TableSchema, EmptyStateBuilder } from "./lib/builders";
4
- export { AvatarGroupColumn as avatarGroupColumn } from "./columns/avatar-group-column";
5
- export { BadgeColumn as badgeColumn } from "./columns/badge-column";
6
- export { ButtonColumn as buttonColumn } from "./columns/button-column";
7
- export { CheckboxColumn as checkboxColumn } from "./columns/checkbox-column";
8
- export { DateColumn as dateColumn } from "./columns/date-column";
9
- export { DropdownColumn as dropdownColumn } from "./columns/dropdown-column";
10
- export { IconColumn as iconColumn } from "./columns/icon-column";
11
- export { InputColumn as inputColumn } from "./columns/input-column";
12
- export { ProgressColumn as progressColumn } from "./columns/progress-column";
13
- export { SelectColumn as selectColumn } from "./columns/select-column";
14
- export { TextColumn as textColumn } from "./columns/text-column";
4
+ export { AvatarGroupColumn, AvatarGroupColumn as avatarGroupColumn, } from "./columns/avatar-group-column";
5
+ export { BadgeColumn, BadgeColumn as badgeColumn, } from "./columns/badge-column";
6
+ export { ButtonColumn, ButtonColumn as buttonColumn, } from "./columns/button-column";
7
+ export { CheckboxColumn, CheckboxColumn as checkboxColumn, } from "./columns/checkbox-column";
8
+ export { DateColumn, DateColumn as dateColumn } from "./columns/date-column";
9
+ export { DropdownColumn, DropdownColumn as dropdownColumn, } from "./columns/dropdown-column";
10
+ export { IconColumn, IconColumn as iconColumn } from "./columns/icon-column";
11
+ export { ImageColumn } from "./columns/image-column";
12
+ export { InputColumn, InputColumn as inputColumn, } from "./columns/input-column";
13
+ export { LinkColumn } from "./columns/link-column";
14
+ export { NumberColumn } from "./columns/number-column";
15
+ export { ProgressColumn, ProgressColumn as progressColumn, } from "./columns/progress-column";
16
+ export { SelectColumn, SelectColumn as selectColumn, } from "./columns/select-column";
17
+ export { TextColumn, TextColumn as textColumn } from "./columns/text-column";
18
+ export { ActionsColumn } from "./columns/actions-column";
15
19
  export type { DataTableConfig, EmptyStateConfig, FilterConfig, HeaderAction, PaginationConfig, SearchConfig, } from "./lib/types";
package/dist/index.d.ts CHANGED
@@ -1,15 +1,19 @@
1
1
  export { DataTable } from "./components/ui/data-table/data-table";
2
2
  export { DataTableSchema } from "./components/ui/data-table/data-table-schema";
3
3
  export { TableSchema, EmptyStateBuilder } from "./lib/builders";
4
- export { AvatarGroupColumn as avatarGroupColumn } from "./columns/avatar-group-column";
5
- export { BadgeColumn as badgeColumn } from "./columns/badge-column";
6
- export { ButtonColumn as buttonColumn } from "./columns/button-column";
7
- export { CheckboxColumn as checkboxColumn } from "./columns/checkbox-column";
8
- export { DateColumn as dateColumn } from "./columns/date-column";
9
- export { DropdownColumn as dropdownColumn } from "./columns/dropdown-column";
10
- export { IconColumn as iconColumn } from "./columns/icon-column";
11
- export { InputColumn as inputColumn } from "./columns/input-column";
12
- export { ProgressColumn as progressColumn } from "./columns/progress-column";
13
- export { SelectColumn as selectColumn } from "./columns/select-column";
14
- export { TextColumn as textColumn } from "./columns/text-column";
4
+ export { AvatarGroupColumn, AvatarGroupColumn as avatarGroupColumn, } from "./columns/avatar-group-column";
5
+ export { BadgeColumn, BadgeColumn as badgeColumn, } from "./columns/badge-column";
6
+ export { ButtonColumn, ButtonColumn as buttonColumn, } from "./columns/button-column";
7
+ export { CheckboxColumn, CheckboxColumn as checkboxColumn, } from "./columns/checkbox-column";
8
+ export { DateColumn, DateColumn as dateColumn } from "./columns/date-column";
9
+ export { DropdownColumn, DropdownColumn as dropdownColumn, } from "./columns/dropdown-column";
10
+ export { IconColumn, IconColumn as iconColumn } from "./columns/icon-column";
11
+ export { ImageColumn } from "./columns/image-column";
12
+ export { InputColumn, InputColumn as inputColumn, } from "./columns/input-column";
13
+ export { LinkColumn } from "./columns/link-column";
14
+ export { NumberColumn } from "./columns/number-column";
15
+ export { ProgressColumn, ProgressColumn as progressColumn, } from "./columns/progress-column";
16
+ export { SelectColumn, SelectColumn as selectColumn, } from "./columns/select-column";
17
+ export { TextColumn, TextColumn as textColumn } from "./columns/text-column";
18
+ export { ActionsColumn } from "./columns/actions-column";
15
19
  export type { DataTableConfig, EmptyStateConfig, FilterConfig, HeaderAction, PaginationConfig, SearchConfig, } from "./lib/types";
package/dist/index.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useState, useLayoutEffect } from 'react';
3
3
  import { useReactTable, getCoreRowModel, getSortedRowModel, getFilteredRowModel, getPaginationRowModel, flexRender } from '@tanstack/react-table';
4
- import { Search, X, ChevronDown, ChevronDownIcon, CheckIcon, ChevronUpIcon, ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight, ArrowUpDown, Calendar } from 'lucide-react';
4
+ import { Search, X, ChevronDown, ChevronDownIcon, CheckIcon, ChevronUpIcon, ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight, ArrowUpDown, Calendar, ExternalLink, MoreHorizontal } from 'lucide-react';
5
5
  import * as ReactDOM from 'react-dom';
6
6
  import ReactDOM__default from 'react-dom';
7
7
 
@@ -7307,12 +7307,12 @@ var DropdownMenuItemIndicator = React.forwardRef((props, forwardedRef) => {
7307
7307
  });
7308
7308
  DropdownMenuItemIndicator.displayName = INDICATOR_NAME$1;
7309
7309
  var SEPARATOR_NAME$1 = "DropdownMenuSeparator";
7310
- var DropdownMenuSeparator = React.forwardRef((props, forwardedRef) => {
7310
+ var DropdownMenuSeparator$1 = React.forwardRef((props, forwardedRef) => {
7311
7311
  const { __scopeDropdownMenu, ...separatorProps } = props;
7312
7312
  const menuScope = useMenuScope(__scopeDropdownMenu);
7313
7313
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { ...menuScope, ...separatorProps, ref: forwardedRef });
7314
7314
  });
7315
- DropdownMenuSeparator.displayName = SEPARATOR_NAME$1;
7315
+ DropdownMenuSeparator$1.displayName = SEPARATOR_NAME$1;
7316
7316
  var ARROW_NAME$2 = "DropdownMenuArrow";
7317
7317
  var DropdownMenuArrow = React.forwardRef(
7318
7318
  (props, forwardedRef) => {
@@ -7359,6 +7359,7 @@ var Trigger$2 = DropdownMenuTrigger$1;
7359
7359
  var Portal2 = DropdownMenuPortal;
7360
7360
  var Content2$2 = DropdownMenuContent$1;
7361
7361
  var Item2 = DropdownMenuItem$1;
7362
+ var Separator2 = DropdownMenuSeparator$1;
7362
7363
 
7363
7364
  // packages/core/number/src/number.ts
7364
7365
  function clamp(value, [min, max]) {
@@ -9103,6 +9104,9 @@ function DropdownMenuContent({ className, align = "start", sideOffset = 4, ...pr
9103
9104
  function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
9104
9105
  return (jsxRuntimeExports.jsx(Item2, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: className, ...props }));
9105
9106
  }
9107
+ function DropdownMenuSeparator({ className, ...props }) {
9108
+ return (jsxRuntimeExports.jsx(Separator2, { "data-slot": "dropdown-menu-separator", className: className, ...props }));
9109
+ }
9106
9110
 
9107
9111
  function DataTableHeader({ title, description, actions = [], search, searchValue = "", onSearchChange, table, selectedCount = 0, className, }) {
9108
9112
  // Actions aufteilen in normale und Bulk-Actions
@@ -10024,6 +10028,68 @@ class IconColumn extends BaseColumn {
10024
10028
  }
10025
10029
  }
10026
10030
 
10031
+ class ImageColumn extends BaseColumn {
10032
+ constructor(accessor) {
10033
+ super(accessor);
10034
+ this.config.size = 'md';
10035
+ this.config.rounded = 'md';
10036
+ }
10037
+ static make(accessor) {
10038
+ return new ImageColumn(accessor);
10039
+ }
10040
+ size(size) {
10041
+ this.config.size = size;
10042
+ return this;
10043
+ }
10044
+ rounded(rounded) {
10045
+ this.config.rounded = rounded;
10046
+ return this;
10047
+ }
10048
+ circular() {
10049
+ return this.rounded('full');
10050
+ }
10051
+ square() {
10052
+ return this.rounded('none');
10053
+ }
10054
+ fallback(url) {
10055
+ this.config.fallback = url;
10056
+ return this;
10057
+ }
10058
+ alt(fn) {
10059
+ this.config.alt = fn;
10060
+ return this;
10061
+ }
10062
+ build() {
10063
+ const config = this.config;
10064
+ const { accessor, label, size, rounded, fallback, alt } = config;
10065
+ const sizeClasses = {
10066
+ sm: 'h-8 w-8',
10067
+ md: 'h-10 w-10',
10068
+ lg: 'h-12 w-12',
10069
+ };
10070
+ const roundedClasses = {
10071
+ none: 'rounded-none',
10072
+ sm: 'rounded-sm',
10073
+ md: 'rounded-md',
10074
+ lg: 'rounded-lg',
10075
+ full: 'rounded-full',
10076
+ };
10077
+ return {
10078
+ accessorKey: accessor,
10079
+ header: () => jsxRuntimeExports.jsx("span", { className: cn('text-muted-foreground font-medium', this.config.headerClassName), children: label || '' }),
10080
+ cell: ({ getValue, row }) => {
10081
+ const src = getValue();
10082
+ const altText = alt ? alt(row.original) : 'Bild';
10083
+ return (jsxRuntimeExports.jsx("img", { src: src || fallback || '/placeholder.png', alt: altText, className: cn('object-cover', sizeClasses[size || 'md'], roundedClasses[rounded || 'md'], this.config.cellClassName), onError: (e) => {
10084
+ if (fallback) {
10085
+ e.target.src = fallback;
10086
+ }
10087
+ } }));
10088
+ },
10089
+ };
10090
+ }
10091
+ }
10092
+
10027
10093
  const InputColumn = (config) => {
10028
10094
  const accessorKey = config.accessorKey || "input";
10029
10095
  return {
@@ -10036,6 +10102,182 @@ const InputColumn = (config) => {
10036
10102
  };
10037
10103
  };
10038
10104
 
10105
+ class LinkColumn extends BaseColumn {
10106
+ constructor(accessor) {
10107
+ super(accessor);
10108
+ const config = this.config;
10109
+ config.external = false;
10110
+ config.showExternalIcon = false;
10111
+ config.underline = 'hover';
10112
+ config.openInNewTab = false;
10113
+ }
10114
+ static make(accessor) {
10115
+ return new LinkColumn(accessor);
10116
+ }
10117
+ // URL setzen (statisch oder dynamisch)
10118
+ href(href) {
10119
+ this.config.href = href;
10120
+ return this;
10121
+ }
10122
+ // URL aus einem anderen Feld nehmen
10123
+ urlFromField(field) {
10124
+ this.config.href = (row) => String(row[field]);
10125
+ return this;
10126
+ }
10127
+ // Externer Link (zeigt Icon)
10128
+ external(external = true) {
10129
+ const config = this.config;
10130
+ config.external = external;
10131
+ config.showExternalIcon = external;
10132
+ config.openInNewTab = external;
10133
+ return this;
10134
+ }
10135
+ // Icon vor dem Text
10136
+ icon(icon) {
10137
+ this.config.icon = icon;
10138
+ return this;
10139
+ }
10140
+ // External-Icon anzeigen
10141
+ showExternalIcon(show = true) {
10142
+ this.config.showExternalIcon = show;
10143
+ return this;
10144
+ }
10145
+ // Unterstreichung
10146
+ underline(style) {
10147
+ this.config.underline = style;
10148
+ return this;
10149
+ }
10150
+ // In neuem Tab öffnen
10151
+ openInNewTab(open = true) {
10152
+ this.config.openInNewTab = open;
10153
+ return this;
10154
+ }
10155
+ // Click-Handler (für programmatische Navigation)
10156
+ onClick(handler) {
10157
+ this.config.onClick = handler;
10158
+ return this;
10159
+ }
10160
+ build() {
10161
+ const config = this.config;
10162
+ const { accessor, label, sortable, href, icon, showExternalIcon, underline, openInNewTab, onClick } = config;
10163
+ const underlineClasses = {
10164
+ always: 'underline',
10165
+ hover: 'hover:underline',
10166
+ never: 'no-underline',
10167
+ };
10168
+ return {
10169
+ accessorKey: accessor,
10170
+ header: ({ column }) => {
10171
+ const displayLabel = label || String(accessor);
10172
+ if (!sortable) {
10173
+ return (jsxRuntimeExports.jsx("span", { className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
10174
+ }
10175
+ return (jsxRuntimeExports.jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsxRuntimeExports.jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
10176
+ },
10177
+ cell: ({ getValue, row }) => {
10178
+ const value = getValue();
10179
+ if (!value) {
10180
+ return jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: "\u2014" });
10181
+ }
10182
+ // URL berechnen
10183
+ const url = typeof href === 'function' ? href(row.original) : href || value;
10184
+ const handleClick = (e) => {
10185
+ if (onClick) {
10186
+ e.preventDefault();
10187
+ onClick(row.original);
10188
+ }
10189
+ };
10190
+ // Alignment ohne text-muted-foreground für Links
10191
+ const alignmentClass = this.config.align === 'center' ? 'text-center' : this.config.align === 'right' ? 'text-right' : 'text-left';
10192
+ return (jsxRuntimeExports.jsxs("a", { href: url, target: openInNewTab ? '_blank' : undefined, rel: openInNewTab ? 'noopener noreferrer' : undefined, onClick: onClick ? handleClick : undefined, className: cn('inline-flex items-center gap-1.5 text-sm text-blue-500', underlineClasses[underline || 'hover'], 'hover:text-blue-500/80', alignmentClass, this.config.cellClassName), children: [icon, jsxRuntimeExports.jsx("span", { children: value }), showExternalIcon && jsxRuntimeExports.jsx(ExternalLink, { className: "text-muted-foreground h-3 w-3" })] }));
10193
+ },
10194
+ };
10195
+ }
10196
+ }
10197
+
10198
+ class NumberColumn extends BaseColumn {
10199
+ constructor(accessor) {
10200
+ super(accessor);
10201
+ this.config.align = 'right'; // Zahlen standardmäßig rechtsbündig
10202
+ this.config.decimals = 0;
10203
+ this.config.locale = 'de-DE';
10204
+ }
10205
+ static make(accessor) {
10206
+ return new NumberColumn(accessor);
10207
+ }
10208
+ decimals(decimals) {
10209
+ this.config.decimals = decimals;
10210
+ return this;
10211
+ }
10212
+ locale(locale) {
10213
+ this.config.locale = locale;
10214
+ return this;
10215
+ }
10216
+ // Währungsformatierung
10217
+ money(currency = 'EUR') {
10218
+ this.config.currency = currency;
10219
+ this.config.decimals = 2;
10220
+ return this;
10221
+ }
10222
+ // Prozentformatierung
10223
+ percent() {
10224
+ this.config.percent = true;
10225
+ return this;
10226
+ }
10227
+ prefix(prefix) {
10228
+ this.config.prefix = prefix;
10229
+ return this;
10230
+ }
10231
+ suffix(suffix) {
10232
+ this.config.suffix = suffix;
10233
+ return this;
10234
+ }
10235
+ build() {
10236
+ const config = this.config;
10237
+ const { accessor, label, sortable, decimals, locale, currency, percent, prefix, suffix } = config;
10238
+ return {
10239
+ accessorKey: accessor,
10240
+ header: ({ column }) => {
10241
+ const displayLabel = label || String(accessor);
10242
+ if (!sortable) {
10243
+ return (jsxRuntimeExports.jsx("span", { className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: displayLabel }));
10244
+ }
10245
+ return (jsxRuntimeExports.jsxs(Button, { variant: "table_header", size: "table_header", onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'), className: cn('text-muted-foreground font-medium', this.getAlignmentClass(), this.config.headerClassName), children: [displayLabel, jsxRuntimeExports.jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" })] }));
10246
+ },
10247
+ cell: ({ getValue }) => {
10248
+ const value = getValue();
10249
+ if (value === null || value === undefined) {
10250
+ return jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: "\u2014" });
10251
+ }
10252
+ let formatted;
10253
+ if (currency) {
10254
+ formatted = new Intl.NumberFormat(locale, {
10255
+ style: 'currency',
10256
+ currency,
10257
+ minimumFractionDigits: decimals,
10258
+ maximumFractionDigits: decimals,
10259
+ }).format(value);
10260
+ }
10261
+ else if (percent) {
10262
+ formatted = new Intl.NumberFormat(locale, {
10263
+ style: 'percent',
10264
+ minimumFractionDigits: decimals,
10265
+ maximumFractionDigits: decimals,
10266
+ }).format(value / 100);
10267
+ }
10268
+ else {
10269
+ formatted = new Intl.NumberFormat(locale, {
10270
+ minimumFractionDigits: decimals,
10271
+ maximumFractionDigits: decimals,
10272
+ }).format(value);
10273
+ }
10274
+ const displayValue = `${prefix || ''}${formatted}${suffix || ''}`;
10275
+ return jsxRuntimeExports.jsx("span", { className: cn('tabular-nums', this.getAlignmentClass(), this.config.cellClassName), children: displayValue });
10276
+ },
10277
+ };
10278
+ }
10279
+ }
10280
+
10039
10281
  function Progress({ className, value, ...props }) {
10040
10282
  return (jsxRuntimeExports.jsx(Root, { "data-slot": "progress", className: className, ...props, children: jsxRuntimeExports.jsx(Indicator, { "data-slot": "progress-indicator", className: "bg-primary size-full flex-1 transition-all", style: { transform: `translateX(-${100 - (value || 0)}%)` } }) }));
10041
10283
  }
@@ -10256,5 +10498,73 @@ class TextColumn extends BaseColumn {
10256
10498
  }
10257
10499
  }
10258
10500
 
10259
- export { DataTable, DataTableSchema, EmptyStateBuilder, TableSchema, AvatarGroupColumn as avatarGroupColumn, BadgeColumn as badgeColumn, ButtonColumn as buttonColumn, CheckboxColumn as checkboxColumn, DateColumn as dateColumn, DropdownColumn as dropdownColumn, IconColumn as iconColumn, InputColumn as inputColumn, ProgressColumn as progressColumn, SelectColumn as selectColumn, TextColumn as textColumn };
10501
+ class ActionsColumn {
10502
+ config = {
10503
+ actions: [],
10504
+ label: 'Aktionen',
10505
+ };
10506
+ static make() {
10507
+ return new ActionsColumn();
10508
+ }
10509
+ label(label) {
10510
+ this.config.label = label;
10511
+ return this;
10512
+ }
10513
+ triggerIcon(icon) {
10514
+ this.config.triggerIcon = icon;
10515
+ return this;
10516
+ }
10517
+ // Action hinzufügen
10518
+ action(action) {
10519
+ this.config.actions.push(action);
10520
+ return this;
10521
+ }
10522
+ // Shortcuts für gängige Actions
10523
+ view(onClick) {
10524
+ return this.action({ label: 'Anzeigen', onClick });
10525
+ }
10526
+ edit(onClick) {
10527
+ return this.action({ label: 'Bearbeiten', onClick });
10528
+ }
10529
+ delete(onClick) {
10530
+ return this.action({
10531
+ label: 'Löschen',
10532
+ onClick,
10533
+ variant: 'destructive',
10534
+ separator: true,
10535
+ });
10536
+ }
10537
+ link(label, href) {
10538
+ return this.action({ label, href });
10539
+ }
10540
+ separator() {
10541
+ if (this.config.actions.length > 0) {
10542
+ this.config.actions[this.config.actions.length - 1].separator = true;
10543
+ }
10544
+ return this;
10545
+ }
10546
+ build() {
10547
+ const { actions, label, triggerIcon } = this.config;
10548
+ return {
10549
+ id: 'actions',
10550
+ header: () => jsxRuntimeExports.jsx("span", { className: "sr-only", children: label }),
10551
+ cell: ({ row }) => {
10552
+ const data = row.original;
10553
+ const visibleActions = actions.filter((action) => !action.hidden || !action.hidden(data));
10554
+ if (visibleActions.length === 0)
10555
+ return null;
10556
+ return (jsxRuntimeExports.jsxs(DropdownMenu, { children: [jsxRuntimeExports.jsx(DropdownMenuTrigger, { asChild: true, children: jsxRuntimeExports.jsxs(Button, { variant: "ghost", className: "h-10 w-10 p-0", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: label }), triggerIcon || jsxRuntimeExports.jsx(MoreHorizontal, { className: "h-8 w-8" })] }) }), jsxRuntimeExports.jsx(DropdownMenuContent, { align: "end", children: visibleActions.map((action, index) => (jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs(DropdownMenuItem, { disabled: action.disabled?.(data), className: cn(action.variant === 'destructive' && 'text-destructive focus:text-destructive'), onClick: () => {
10557
+ if (action.href) {
10558
+ window.location.href = action.href(data);
10559
+ }
10560
+ else if (action.onClick) {
10561
+ action.onClick(data);
10562
+ }
10563
+ }, children: [action.icon && jsxRuntimeExports.jsx("span", { className: "mr-2", children: action.icon }), action.label] }), action.separator && index < visibleActions.length - 1 && jsxRuntimeExports.jsx(DropdownMenuSeparator, {})] }, index))) })] }));
10564
+ },
10565
+ };
10566
+ }
10567
+ }
10568
+
10569
+ export { ActionsColumn, AvatarGroupColumn, BadgeColumn, ButtonColumn, CheckboxColumn, DataTable, DataTableSchema, DateColumn, DropdownColumn, EmptyStateBuilder, IconColumn, ImageColumn, InputColumn, LinkColumn, NumberColumn, ProgressColumn, SelectColumn, TableSchema, TextColumn, AvatarGroupColumn as avatarGroupColumn, BadgeColumn as badgeColumn, ButtonColumn as buttonColumn, CheckboxColumn as checkboxColumn, DateColumn as dateColumn, DropdownColumn as dropdownColumn, IconColumn as iconColumn, InputColumn as inputColumn, ProgressColumn as progressColumn, SelectColumn as selectColumn, TextColumn as textColumn };
10260
10570
  //# sourceMappingURL=index.esm.js.map