@prediktif/ui 0.1.20 → 0.1.21

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/README.md CHANGED
@@ -139,7 +139,7 @@ Open [http://localhost:3000](http://localhost:3000) in your browser.
139
139
 
140
140
  ### 2. Adding a New Composed Component
141
141
 
142
- 1. Create your component in `src/components/composed/my-component.tsx`:
142
+ 1. **Create the component** in `src/components/composed/my-component.tsx`:
143
143
  ```tsx
144
144
  export interface MyComponentProps {
145
145
  label: string;
@@ -149,12 +149,30 @@ Open [http://localhost:3000](http://localhost:3000) in your browser.
149
149
  return <div className="p-4 rounded-md border">{label}</div>;
150
150
  }
151
151
  ```
152
- 2. Export the component in `src/components/composed/index.ts`:
152
+
153
+ 2. **Export the component** in `src/components/composed/index.ts`:
153
154
  ```ts
154
155
  export * from "./header-title";
155
156
  export * from "./my-component";
156
157
  ```
157
- 3. (Optional) Create a documentation page in `src/app/(docs)/components/my-component/page.tsx` for visual testing.
158
+
159
+ 3. **Register in navigation** (`src/lib/docs-config.ts`):
160
+ ```ts
161
+ {
162
+ title: "Components",
163
+ url: "/components",
164
+ items: [
165
+ // ...
166
+ { title: "My Component", url: "/components/my-component" },
167
+ ]
168
+ }
169
+ ```
170
+
171
+ 4. **Create the documentation detail page** in `src/app/(docs)/components/my-component/page.tsx`:
172
+ - Include `<ComponentHeader>`, `<ComponentSection title="Preview">`, `<ComponentCodeExample>`, `<ComponentPropsTable>`, and `<ComponentPagination />`.
173
+
174
+ 5. **Add a preview card** to `src/app/(docs)/components/page.tsx`:
175
+ - Add `<Card>` with `<CardHeader>`, `<CardTitle>`, `<CardDescription className="truncate">`, and `<CardContent className="max-h-32 overflow-y-scroll">` wrapping `<ComponentPreview>`.
158
176
 
159
177
  ---
160
178
 
package/dist/index.d.mts CHANGED
@@ -221,10 +221,7 @@ interface DataTableHeaderFilterProps<TData extends RowData> {
221
221
  declare function smartFilterFn<TData extends RowData>(row: Row<DataTableFeatures, TData>, columnId: string, filterValue: unknown): boolean;
222
222
  declare function DataTableHeaderFilter<TData extends RowData>({ table, columnFilters, }: DataTableHeaderFilterProps<TData>): react.JSX.Element | null;
223
223
 
224
- interface DataTableHeaderRefreshProps {
225
- onRefresh?: () => void;
226
- }
227
- declare function DataTableHeaderRefresh({ onRefresh, }: DataTableHeaderRefreshProps): react.JSX.Element;
224
+ declare function DataTableHeaderRefresh(): react.JSX.Element;
228
225
 
229
226
  interface DataTableHeaderSearchProps {
230
227
  value?: string;
@@ -254,8 +251,6 @@ interface DataTableProps<TData extends RowData> {
254
251
  renderCreateDialog?: (open: boolean, onOpenChange: (open: boolean) => void) => ReactNode;
255
252
  /** Label text for the add button (defaults to "Add") */
256
253
  addLabel?: string;
257
- /** Callback triggered when user clicks the refresh button */
258
- onRefresh?: () => void;
259
254
  /** Callback triggered when user downloads data */
260
255
  onDownload?: () => void;
261
256
  /** Base filename used when exporting data (defaults to "data-export") */
@@ -282,7 +277,7 @@ interface DataTableProps<TData extends RowData> {
282
277
  * data refresh, pagination, row actions, add/create modal dialog binding,
283
278
  * and standard hardcoded global empty state via StateEmpty.
284
279
  */
285
- declare function DataTable<TData extends RowData>({ columns, data, initialColumnVisibility, renderCreateDialog, addLabel, onRefresh, onDownload, exportFilename, showSearchInput, showRefreshButton, showSortButton, showFilterButton, showDownloadButton, showColumnToggleButton, showAddButton, }: DataTableProps<TData>): react.JSX.Element;
280
+ declare function DataTable<TData extends RowData>({ columns, data, initialColumnVisibility, renderCreateDialog, addLabel, onDownload, exportFilename, showSearchInput, showRefreshButton, showSortButton, showFilterButton, showDownloadButton, showColumnToggleButton, showAddButton, }: DataTableProps<TData>): react.JSX.Element;
286
281
 
287
282
  interface HeaderTabItem {
288
283
  title: string;
@@ -326,4 +321,4 @@ interface StateEmptyProps {
326
321
  }
327
322
  declare const StateEmpty: react.NamedExoticComponent<StateEmptyProps>;
328
323
 
329
- export { AppSidebar, type AppSidebarProps, type ColumnMetaCustom, DataTable, DataTableContentBody, type DataTableContentBodyProps, DataTableContentHeader, type DataTableContentHeaderProps, type DataTableFeatures, DataTableFooterEntries, type DataTableFooterEntriesProps, DataTableFooterPagination, type DataTableFooterPaginationProps, DataTableHeaderAdd, type DataTableHeaderAddProps, DataTableHeaderDownload, type DataTableHeaderDownloadProps, DataTableHeaderFilter, type DataTableHeaderFilterProps, DataTableHeaderRefresh, type DataTableHeaderRefreshProps, DataTableHeaderSearch, type DataTableHeaderSearchProps, DataTableHeaderSort, type DataTableHeaderSortProps, DataTableHeaderToggle, type DataTableHeaderToggleProps, type DataTableProps, type FilterSelectOption, type FilterVariant, type HeaderTabItem, HeaderTabs, type HeaderTabsProps, HeaderTitle, type HeaderTitleProps, type NavItem, type OrganizationItem, type RowActionItem, RowActions, type RowActionsProps, StateEmpty, type StateEmptyProps, exportToCSV, exportToPDF, exportToXLSX, features, getTableExportData, printTable, smartFilterFn };
324
+ export { AppSidebar, type AppSidebarProps, type ColumnMetaCustom, DataTable, DataTableContentBody, type DataTableContentBodyProps, DataTableContentHeader, type DataTableContentHeaderProps, type DataTableFeatures, DataTableFooterEntries, type DataTableFooterEntriesProps, DataTableFooterPagination, type DataTableFooterPaginationProps, DataTableHeaderAdd, type DataTableHeaderAddProps, DataTableHeaderDownload, type DataTableHeaderDownloadProps, DataTableHeaderFilter, type DataTableHeaderFilterProps, DataTableHeaderRefresh, DataTableHeaderSearch, type DataTableHeaderSearchProps, DataTableHeaderSort, type DataTableHeaderSortProps, DataTableHeaderToggle, type DataTableHeaderToggleProps, type DataTableProps, type FilterSelectOption, type FilterVariant, type HeaderTabItem, HeaderTabs, type HeaderTabsProps, HeaderTitle, type HeaderTitleProps, type NavItem, type OrganizationItem, type RowActionItem, RowActions, type RowActionsProps, StateEmpty, type StateEmptyProps, exportToCSV, exportToPDF, exportToXLSX, features, getTableExportData, printTable, smartFilterFn };
package/dist/index.d.ts CHANGED
@@ -221,10 +221,7 @@ interface DataTableHeaderFilterProps<TData extends RowData> {
221
221
  declare function smartFilterFn<TData extends RowData>(row: Row<DataTableFeatures, TData>, columnId: string, filterValue: unknown): boolean;
222
222
  declare function DataTableHeaderFilter<TData extends RowData>({ table, columnFilters, }: DataTableHeaderFilterProps<TData>): react.JSX.Element | null;
223
223
 
224
- interface DataTableHeaderRefreshProps {
225
- onRefresh?: () => void;
226
- }
227
- declare function DataTableHeaderRefresh({ onRefresh, }: DataTableHeaderRefreshProps): react.JSX.Element;
224
+ declare function DataTableHeaderRefresh(): react.JSX.Element;
228
225
 
229
226
  interface DataTableHeaderSearchProps {
230
227
  value?: string;
@@ -254,8 +251,6 @@ interface DataTableProps<TData extends RowData> {
254
251
  renderCreateDialog?: (open: boolean, onOpenChange: (open: boolean) => void) => ReactNode;
255
252
  /** Label text for the add button (defaults to "Add") */
256
253
  addLabel?: string;
257
- /** Callback triggered when user clicks the refresh button */
258
- onRefresh?: () => void;
259
254
  /** Callback triggered when user downloads data */
260
255
  onDownload?: () => void;
261
256
  /** Base filename used when exporting data (defaults to "data-export") */
@@ -282,7 +277,7 @@ interface DataTableProps<TData extends RowData> {
282
277
  * data refresh, pagination, row actions, add/create modal dialog binding,
283
278
  * and standard hardcoded global empty state via StateEmpty.
284
279
  */
285
- declare function DataTable<TData extends RowData>({ columns, data, initialColumnVisibility, renderCreateDialog, addLabel, onRefresh, onDownload, exportFilename, showSearchInput, showRefreshButton, showSortButton, showFilterButton, showDownloadButton, showColumnToggleButton, showAddButton, }: DataTableProps<TData>): react.JSX.Element;
280
+ declare function DataTable<TData extends RowData>({ columns, data, initialColumnVisibility, renderCreateDialog, addLabel, onDownload, exportFilename, showSearchInput, showRefreshButton, showSortButton, showFilterButton, showDownloadButton, showColumnToggleButton, showAddButton, }: DataTableProps<TData>): react.JSX.Element;
286
281
 
287
282
  interface HeaderTabItem {
288
283
  title: string;
@@ -326,4 +321,4 @@ interface StateEmptyProps {
326
321
  }
327
322
  declare const StateEmpty: react.NamedExoticComponent<StateEmptyProps>;
328
323
 
329
- export { AppSidebar, type AppSidebarProps, type ColumnMetaCustom, DataTable, DataTableContentBody, type DataTableContentBodyProps, DataTableContentHeader, type DataTableContentHeaderProps, type DataTableFeatures, DataTableFooterEntries, type DataTableFooterEntriesProps, DataTableFooterPagination, type DataTableFooterPaginationProps, DataTableHeaderAdd, type DataTableHeaderAddProps, DataTableHeaderDownload, type DataTableHeaderDownloadProps, DataTableHeaderFilter, type DataTableHeaderFilterProps, DataTableHeaderRefresh, type DataTableHeaderRefreshProps, DataTableHeaderSearch, type DataTableHeaderSearchProps, DataTableHeaderSort, type DataTableHeaderSortProps, DataTableHeaderToggle, type DataTableHeaderToggleProps, type DataTableProps, type FilterSelectOption, type FilterVariant, type HeaderTabItem, HeaderTabs, type HeaderTabsProps, HeaderTitle, type HeaderTitleProps, type NavItem, type OrganizationItem, type RowActionItem, RowActions, type RowActionsProps, StateEmpty, type StateEmptyProps, exportToCSV, exportToPDF, exportToXLSX, features, getTableExportData, printTable, smartFilterFn };
324
+ export { AppSidebar, type AppSidebarProps, type ColumnMetaCustom, DataTable, DataTableContentBody, type DataTableContentBodyProps, DataTableContentHeader, type DataTableContentHeaderProps, type DataTableFeatures, DataTableFooterEntries, type DataTableFooterEntriesProps, DataTableFooterPagination, type DataTableFooterPaginationProps, DataTableHeaderAdd, type DataTableHeaderAddProps, DataTableHeaderDownload, type DataTableHeaderDownloadProps, DataTableHeaderFilter, type DataTableHeaderFilterProps, DataTableHeaderRefresh, DataTableHeaderSearch, type DataTableHeaderSearchProps, DataTableHeaderSort, type DataTableHeaderSortProps, DataTableHeaderToggle, type DataTableHeaderToggleProps, type DataTableProps, type FilterSelectOption, type FilterVariant, type HeaderTabItem, HeaderTabs, type HeaderTabsProps, HeaderTitle, type HeaderTitleProps, type NavItem, type OrganizationItem, type RowActionItem, RowActions, type RowActionsProps, StateEmpty, type StateEmptyProps, exportToCSV, exportToPDF, exportToXLSX, features, getTableExportData, printTable, smartFilterFn };
package/dist/index.js CHANGED
@@ -1335,9 +1335,10 @@ function formatSegment(segment, subHref, navMainItems = [], navSecondaryItems =
1335
1335
  }
1336
1336
  function isRouteActive(url, pathname) {
1337
1337
  if (!pathname) return false;
1338
- if (url === "/") return pathname === "/";
1339
- const rootPrefix = `/${url.split("/")[1]}`;
1340
- return pathname === url || pathname.startsWith(rootPrefix);
1338
+ const cleanUrl = url.replace(/\/$/, "") || "/";
1339
+ const cleanPath = pathname.replace(/\/$/, "") || "/";
1340
+ if (cleanUrl === "/") return cleanPath === "/";
1341
+ return cleanPath === cleanUrl || cleanPath.startsWith(`${cleanUrl}/`);
1341
1342
  }
1342
1343
  var AppSidebar = (0, import_react.memo)(function AppSidebar2({
1343
1344
  name = "",
@@ -1532,6 +1533,7 @@ var AppSidebar = (0, import_react.memo)(function AppSidebar2({
1532
1533
  // src/components/composed/data-table/data-table.tsx
1533
1534
  var import_react_table4 = require("@tanstack/react-table");
1534
1535
  var import_lucide_react18 = require("lucide-react");
1536
+ var import_navigation3 = require("next/navigation");
1535
1537
  var import_react6 = require("react");
1536
1538
 
1537
1539
  // src/components/composed/state-empty.tsx
@@ -3015,18 +3017,12 @@ var import_lucide_react13 = require("lucide-react");
3015
3017
  var import_navigation2 = require("next/navigation");
3016
3018
  var import_react4 = require("react");
3017
3019
  var import_jsx_runtime26 = require("react/jsx-runtime");
3018
- function DataTableHeaderRefresh({
3019
- onRefresh
3020
- }) {
3020
+ function DataTableHeaderRefresh() {
3021
3021
  const router = (0, import_navigation2.useRouter)();
3022
3022
  const [isRefreshing, setIsRefreshing] = (0, import_react4.useState)(false);
3023
3023
  const handleRefresh = () => {
3024
3024
  setIsRefreshing(true);
3025
- if (onRefresh) {
3026
- onRefresh();
3027
- } else {
3028
- router.refresh();
3029
- }
3025
+ router.refresh();
3030
3026
  setTimeout(() => {
3031
3027
  setIsRefreshing(false);
3032
3028
  }, 750);
@@ -3284,7 +3280,6 @@ function DataTable({
3284
3280
  initialColumnVisibility,
3285
3281
  renderCreateDialog,
3286
3282
  addLabel,
3287
- onRefresh,
3288
3283
  onDownload,
3289
3284
  exportFilename = "data-export",
3290
3285
  showSearchInput = true,
@@ -3295,6 +3290,7 @@ function DataTable({
3295
3290
  showColumnToggleButton = true,
3296
3291
  showAddButton = true
3297
3292
  }) {
3293
+ const router = (0, import_navigation3.useRouter)();
3298
3294
  const [createOpen, setCreateOpen] = (0, import_react6.useState)(false);
3299
3295
  const [sorting, setSorting] = (0, import_react6.useState)([]);
3300
3296
  const [columnFilters, setColumnFilters] = (0, import_react6.useState)([]);
@@ -3330,7 +3326,6 @@ function DataTable({
3330
3326
  });
3331
3327
  if (data.length === 0) {
3332
3328
  const hasCreateAction = Boolean(renderCreateDialog);
3333
- const hasRefreshAction = Boolean(onRefresh);
3334
3329
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "space-y-2", children: [
3335
3330
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3336
3331
  StateEmpty,
@@ -3339,8 +3334,8 @@ function DataTable({
3339
3334
  icon: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react18.FolderOpenIcon, { className: "size-6 text-muted-foreground" }),
3340
3335
  title: "No Data Available",
3341
3336
  description: "There are currently no records to display. Create a new record to get started.",
3342
- buttonText: hasCreateAction ? addLabel != null ? addLabel : "Add Record" : hasRefreshAction ? "Refresh" : void 0,
3343
- render: hasCreateAction ? () => setCreateOpen(true) : hasRefreshAction ? onRefresh : void 0
3337
+ buttonText: hasCreateAction ? addLabel != null ? addLabel : "Add Record" : "Refresh",
3338
+ render: hasCreateAction ? () => setCreateOpen(true) : () => router.refresh()
3344
3339
  }
3345
3340
  ),
3346
3341
  renderCreateDialog == null ? void 0 : renderCreateDialog(createOpen, setCreateOpen)
@@ -3356,7 +3351,7 @@ function DataTable({
3356
3351
  }
3357
3352
  ) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", {}),
3358
3353
  /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-row items-center gap-1", children: [
3359
- showRefreshButton && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(DataTableHeaderRefresh, { onRefresh }),
3354
+ showRefreshButton && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(DataTableHeaderRefresh, {}),
3360
3355
  showSortButton && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(DataTableHeaderSort, { table, sorting }),
3361
3356
  showFilterButton && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3362
3357
  DataTableHeaderFilter,
@@ -3397,7 +3392,7 @@ function DataTable({
3397
3392
 
3398
3393
  // src/components/composed/header-tabs.tsx
3399
3394
  var import_link2 = __toESM(require("next/link"));
3400
- var import_navigation3 = require("next/navigation");
3395
+ var import_navigation4 = require("next/navigation");
3401
3396
  var import_react7 = require("react");
3402
3397
 
3403
3398
  // src/components/ui/tabs.tsx
@@ -3490,7 +3485,7 @@ var HeaderTabs = (0, import_react7.memo)(function HeaderTabs2({
3490
3485
  children
3491
3486
  }) {
3492
3487
  var _a, _b;
3493
- const pathname = (0, import_navigation3.usePathname)();
3488
+ const pathname = (0, import_navigation4.usePathname)();
3494
3489
  const matchedItem = pathname ? items.find(
3495
3490
  (item) => item.url === pathname || pathname.endsWith(item.url) || pathname.split("/").includes(item.value)
3496
3491
  ) : void 0;
package/dist/index.mjs CHANGED
@@ -1277,9 +1277,10 @@ function formatSegment(segment, subHref, navMainItems = [], navSecondaryItems =
1277
1277
  }
1278
1278
  function isRouteActive(url, pathname) {
1279
1279
  if (!pathname) return false;
1280
- if (url === "/") return pathname === "/";
1281
- const rootPrefix = `/${url.split("/")[1]}`;
1282
- return pathname === url || pathname.startsWith(rootPrefix);
1280
+ const cleanUrl = url.replace(/\/$/, "") || "/";
1281
+ const cleanPath = pathname.replace(/\/$/, "") || "/";
1282
+ if (cleanUrl === "/") return cleanPath === "/";
1283
+ return cleanPath === cleanUrl || cleanPath.startsWith(`${cleanUrl}/`);
1283
1284
  }
1284
1285
  var AppSidebar = memo(function AppSidebar2({
1285
1286
  name = "",
@@ -1477,6 +1478,7 @@ import {
1477
1478
  useTable
1478
1479
  } from "@tanstack/react-table";
1479
1480
  import { FolderOpenIcon } from "lucide-react";
1481
+ import { useRouter as useRouter2 } from "next/navigation";
1480
1482
  import { useMemo as useMemo3, useState as useState5 } from "react";
1481
1483
 
1482
1484
  // src/components/composed/state-empty.tsx
@@ -2994,18 +2996,12 @@ import { RotateCwIcon } from "lucide-react";
2994
2996
  import { useRouter } from "next/navigation";
2995
2997
  import { useState as useState4 } from "react";
2996
2998
  import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
2997
- function DataTableHeaderRefresh({
2998
- onRefresh
2999
- }) {
2999
+ function DataTableHeaderRefresh() {
3000
3000
  const router = useRouter();
3001
3001
  const [isRefreshing, setIsRefreshing] = useState4(false);
3002
3002
  const handleRefresh = () => {
3003
3003
  setIsRefreshing(true);
3004
- if (onRefresh) {
3005
- onRefresh();
3006
- } else {
3007
- router.refresh();
3008
- }
3004
+ router.refresh();
3009
3005
  setTimeout(() => {
3010
3006
  setIsRefreshing(false);
3011
3007
  }, 750);
@@ -3263,7 +3259,6 @@ function DataTable({
3263
3259
  initialColumnVisibility,
3264
3260
  renderCreateDialog,
3265
3261
  addLabel,
3266
- onRefresh,
3267
3262
  onDownload,
3268
3263
  exportFilename = "data-export",
3269
3264
  showSearchInput = true,
@@ -3274,6 +3269,7 @@ function DataTable({
3274
3269
  showColumnToggleButton = true,
3275
3270
  showAddButton = true
3276
3271
  }) {
3272
+ const router = useRouter2();
3277
3273
  const [createOpen, setCreateOpen] = useState5(false);
3278
3274
  const [sorting, setSorting] = useState5([]);
3279
3275
  const [columnFilters, setColumnFilters] = useState5([]);
@@ -3309,7 +3305,6 @@ function DataTable({
3309
3305
  });
3310
3306
  if (data.length === 0) {
3311
3307
  const hasCreateAction = Boolean(renderCreateDialog);
3312
- const hasRefreshAction = Boolean(onRefresh);
3313
3308
  return /* @__PURE__ */ jsxs20("div", { className: "space-y-2", children: [
3314
3309
  /* @__PURE__ */ jsx31(
3315
3310
  StateEmpty,
@@ -3318,8 +3313,8 @@ function DataTable({
3318
3313
  icon: /* @__PURE__ */ jsx31(FolderOpenIcon, { className: "size-6 text-muted-foreground" }),
3319
3314
  title: "No Data Available",
3320
3315
  description: "There are currently no records to display. Create a new record to get started.",
3321
- buttonText: hasCreateAction ? addLabel != null ? addLabel : "Add Record" : hasRefreshAction ? "Refresh" : void 0,
3322
- render: hasCreateAction ? () => setCreateOpen(true) : hasRefreshAction ? onRefresh : void 0
3316
+ buttonText: hasCreateAction ? addLabel != null ? addLabel : "Add Record" : "Refresh",
3317
+ render: hasCreateAction ? () => setCreateOpen(true) : () => router.refresh()
3323
3318
  }
3324
3319
  ),
3325
3320
  renderCreateDialog == null ? void 0 : renderCreateDialog(createOpen, setCreateOpen)
@@ -3335,7 +3330,7 @@ function DataTable({
3335
3330
  }
3336
3331
  ) : /* @__PURE__ */ jsx31("div", {}),
3337
3332
  /* @__PURE__ */ jsxs20("div", { className: "flex flex-row items-center gap-1", children: [
3338
- showRefreshButton && /* @__PURE__ */ jsx31(DataTableHeaderRefresh, { onRefresh }),
3333
+ showRefreshButton && /* @__PURE__ */ jsx31(DataTableHeaderRefresh, {}),
3339
3334
  showSortButton && /* @__PURE__ */ jsx31(DataTableHeaderSort, { table, sorting }),
3340
3335
  showFilterButton && /* @__PURE__ */ jsx31(
3341
3336
  DataTableHeaderFilter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prediktif/ui",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",