@shipfox/react-ui 0.17.0 → 0.18.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.
@@ -1,15 +1,14 @@
1
- export type KpiVariant = 'neutral' | 'success' | 'warning' | 'error' | 'info';
2
- export interface KpiCardProps {
1
+ import type { ComponentProps, ReactNode } from 'react';
2
+ export type KpiVariant = 'neutral' | 'success' | 'warning' | 'error' | 'info' | 'purple';
3
+ export interface KpiCardProps extends Omit<ComponentProps<'div'>, 'title'> {
3
4
  label: string;
4
- value: string | number;
5
+ value: string | number | ReactNode;
5
6
  variant?: KpiVariant;
6
- className?: string;
7
+ isLoading?: boolean;
7
8
  }
8
- export declare function KpiCard({ label, value, variant, className }: KpiCardProps): import("react/jsx-runtime").JSX.Element;
9
- export interface KpiCardsGroupProps {
9
+ export declare function KpiCard({ label, value, variant, isLoading, className, ...props }: KpiCardProps): import("react/jsx-runtime").JSX.Element;
10
+ export interface KpiCardsGroupProps extends ComponentProps<'div'> {
10
11
  cards: KpiCardProps[];
11
- className?: string;
12
12
  }
13
- export declare function KpiCardsGroup({ cards, className }: KpiCardsGroupProps): import("react/jsx-runtime").JSX.Element;
14
- export declare const defaultKpiCards: KpiCardProps[];
13
+ export declare function KpiCardsGroup({ cards, className, ...props }: KpiCardsGroupProps): import("react/jsx-runtime").JSX.Element;
15
14
  //# sourceMappingURL=kpi-card.d.ts.map
@@ -1,4 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Card } from '../../../components/card/index.js';
3
+ import { Skeleton } from '../../../components/skeleton/index.js';
2
4
  import { Text } from '../../../components/typography/index.js';
3
5
  import { cn } from '../../../utils/cn.js';
4
6
  const variantDotStyles = {
@@ -6,23 +8,28 @@ const variantDotStyles = {
6
8
  success: 'bg-green-500',
7
9
  warning: 'bg-orange-500',
8
10
  error: 'bg-red-500',
9
- info: 'bg-blue-500'
11
+ info: 'bg-blue-500',
12
+ purple: 'bg-purple-500'
10
13
  };
11
- export function KpiCard({ label, value, variant = 'neutral', className }) {
12
- return /*#__PURE__*/ _jsxs("div", {
13
- className: cn('flex flex-col gap-4 p-12 rounded-8', 'bg-background-neutral-base border border-border-neutral-base', 'min-w-120 flex-1', className),
14
+ export function KpiCard({ label, value, variant = 'neutral', isLoading, className, ...props }) {
15
+ return /*#__PURE__*/ _jsxs(Card, {
16
+ className: cn('flex flex-col gap-4 p-12 min-w-120 flex-1', className),
17
+ ...props,
14
18
  children: [
15
- /*#__PURE__*/ _jsx("p", {
16
- className: "text-xs text-foreground-neutral-subtle",
19
+ /*#__PURE__*/ _jsx(Text, {
20
+ size: "xs",
21
+ className: "text-foreground-neutral-subtle",
17
22
  children: label
18
23
  }),
19
24
  /*#__PURE__*/ _jsxs("div", {
20
25
  className: "flex items-center gap-6",
21
26
  children: [
22
27
  /*#__PURE__*/ _jsx("span", {
23
- className: cn('size-8 rounded-2 shrink-0', variantDotStyles[variant])
28
+ className: cn('shrink-0 size-8 rounded-2', variantDotStyles[variant])
24
29
  }),
25
- /*#__PURE__*/ _jsx(Text, {
30
+ isLoading ? /*#__PURE__*/ _jsx(Skeleton, {
31
+ className: "w-48 h-20 rounded-4"
32
+ }) : /*#__PURE__*/ _jsx(Text, {
26
33
  size: "sm",
27
34
  className: "font-medium text-foreground-neutral-base",
28
35
  children: value
@@ -32,46 +39,21 @@ export function KpiCard({ label, value, variant = 'neutral', className }) {
32
39
  ]
33
40
  });
34
41
  }
35
- export function KpiCardsGroup({ cards, className }) {
42
+ export function KpiCardsGroup({ cards, className, ...props }) {
36
43
  return /*#__PURE__*/ _jsx("div", {
37
- className: cn(// Base layout
38
- 'flex gap-12 md:gap-16', // Mobile: Swipeable with scroll-snap
39
- 'overflow-x-auto scrollbar-none pb-4 md:pb-0', // Scroll snap for smooth swiping
40
- 'snap-x snap-mandatory', // Hide scrollbar but allow scrolling
41
- '[&::-webkit-scrollbar]:hidden', // Smooth scrolling
42
- 'scroll-smooth', className),
44
+ className: cn('flex gap-12 md:gap-16 overflow-x-auto pb-4 md:pb-0 snap-x snap-mandatory [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none] scroll-smooth', className),
45
+ ...props,
43
46
  children: /*#__PURE__*/ _jsx("div", {
44
- className: "flex gap-16 pl-12 md:pl-0 md:w-full",
45
- children: cards.map((card, index)=>/*#__PURE__*/ _jsx(KpiCard, {
46
- ...card,
47
- className: cn(// Mobile: Show ~2 cards per view with peek of next
48
- 'shrink-0 w-[calc((100vw-56px)/2)] md:w-auto', 'snap-start', // Desktop: Flex grow
49
- 'md:flex-1')
50
- }, `${card.label}-${index}`))
47
+ className: "flex gap-16 pl-0 w-full",
48
+ children: cards.map((card, index)=>{
49
+ const { key: _key, ...cardProps } = card;
50
+ return /*#__PURE__*/ _jsx(KpiCard, {
51
+ ...cardProps,
52
+ className: cn('shrink-0 w-[calc((100vw-56px)/2)] snap-start md:flex-1 md:w-0', card.className)
53
+ }, `${card.label}-${index}`);
54
+ })
51
55
  })
52
56
  });
53
57
  }
54
- export const defaultKpiCards = [
55
- {
56
- label: 'Total',
57
- value: '1211',
58
- variant: 'neutral'
59
- },
60
- {
61
- label: 'Success',
62
- value: '1200',
63
- variant: 'success'
64
- },
65
- {
66
- label: 'Neutral',
67
- value: '11',
68
- variant: 'neutral'
69
- },
70
- {
71
- label: 'Failure rate',
72
- value: '0%',
73
- variant: 'success'
74
- }
75
- ];
76
58
 
77
59
  //# sourceMappingURL=kpi-card.js.map
@@ -1,12 +1,7 @@
1
- /**
2
- * Dashboard Component Exports
3
- *
4
- * Comprehensive export file for all dashboard-related components and utilities.
5
- */
6
1
  export type { BarChartProps, ChartColor, LineChartProps } from './components/charts';
7
2
  export { BarChart, LineChart } from './components/charts';
8
3
  export { DashboardAlert } from './components/dashboard-alert';
9
- export type { KpiCardProps } from './components/kpi-card';
4
+ export type { KpiCardProps, KpiCardsGroupProps, KpiVariant } from './components/kpi-card';
10
5
  export { KpiCard, KpiCardsGroup } from './components/kpi-card';
11
6
  export type { MobileSidebarProps } from './components/mobile-sidebar';
12
7
  export { MobileSidebar } from './components/mobile-sidebar';
@@ -1,24 +1,13 @@
1
- /**
2
- * Dashboard Component Exports
3
- *
4
- * Comprehensive export file for all dashboard-related components and utilities.
5
- */ // Chart Components
6
1
  export { BarChart, LineChart } from './components/charts/index.js';
7
- // Shared Components
8
2
  export { DashboardAlert } from './components/dashboard-alert.js';
9
3
  export { KpiCard, KpiCardsGroup } from './components/kpi-card.js';
10
4
  export { MobileSidebar } from './components/mobile-sidebar.js';
11
5
  export { defaultSidebarItems, Sidebar } from './components/sidebar.js';
12
- // Context API
13
6
  export { DashboardProvider, DEFAULT_COLUMN_ID_TO_ACCESSOR_KEY, updateViewColumnsFromVisibility, useDashboardContext, viewColumnsToVisibilityState } from './context/index.js';
14
- // Main Dashboard Component
15
7
  export { Dashboard } from './dashboard.js';
16
- // Filter Components
17
8
  export { ExpressionFilterBar } from './filters/index.js';
18
- // Page Components
19
9
  export { AnalyticsPage, JobsPage } from './pages/index.js';
20
10
  export { TableWrapper } from './table/index.js';
21
- // Generic Reusable Components
22
11
  export { FilterButton, PageToolbar, ToolbarActions, ToolbarSearch, ViewDropdown } from './toolbar/index.js';
23
12
 
24
13
  //# sourceMappingURL=index.js.map
@@ -1,20 +1,2 @@
1
- /**
2
- * Analytics Page Component
3
- *
4
- * Refactored analytics page using DashboardContext and generic components.
5
- */
6
- /**
7
- * Analytics Page
8
- *
9
- * Main analytics page with KPI cards, charts, and jobs table.
10
- * Uses DashboardContext for state management and generic reusable components.
11
- *
12
- * @example
13
- * ```tsx
14
- * <DashboardProvider>
15
- * <AnalyticsPage />
16
- * </DashboardProvider>
17
- * ```
18
- */
19
1
  export declare function AnalyticsPage(): import("react/jsx-runtime").JSX.Element;
20
2
  //# sourceMappingURL=analytics-page.d.ts.map
@@ -1,9 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * Analytics Page Component
4
- *
5
- * Refactored analytics page using DashboardContext and generic components.
6
- */ import { jobColumns } from '../../../components/table/table.stories.columns.js';
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Button } from '../../../components/button/index.js';
3
+ import { CountUp } from '../../../components/count-up/count-up.js';
4
+ import { Icon } from '../../../components/icon/index.js';
5
+ import { SearchInline } from '../../../components/search/search-inline.js';
6
+ import { jobColumns } from '../../../components/table/table.stories.columns.js';
7
7
  import { jobsData } from '../../../components/table/table.stories.data.js';
8
8
  import { useMediaQuery } from '../../../hooks/useMediaQuery.js';
9
9
  import { useMemo } from 'react';
@@ -17,7 +17,6 @@ import { useDashboardContext } from '../context/index.js';
17
17
  import { ExpressionFilterBar } from '../filters/index.js';
18
18
  import { TableWrapper } from '../table/index.js';
19
19
  import { PageToolbar, ToolbarActions } from '../toolbar/index.js';
20
- // Sample data for the performance chart
21
20
  const performanceData = [
22
21
  {
23
22
  label: '1',
@@ -62,7 +61,6 @@ const performanceData = [
62
61
  dataD: 160
63
62
  }
64
63
  ];
65
- // Generate sample data for duration distribution
66
64
  function generateDurationData() {
67
65
  const count = 40;
68
66
  const data = [];
@@ -77,54 +75,85 @@ function generateDurationData() {
77
75
  return data;
78
76
  }
79
77
  const durationData = generateDurationData();
80
- /**
81
- * KPI Cards configuration
82
- */ const kpiCards = [
78
+ const KPI_VALUE_REGEX = /^([^\d]*)([\d.,]+)([^\d]*)$/;
79
+ function parseKpiValue(value) {
80
+ if (typeof value === 'number') {
81
+ return {
82
+ prefix: '',
83
+ numericValue: value,
84
+ suffix: '',
85
+ isNumeric: true
86
+ };
87
+ }
88
+ const match = value.match(KPI_VALUE_REGEX);
89
+ if (match) {
90
+ const [, prefix, numericStr, suffix] = match;
91
+ const numericValue = parseFloat(numericStr.replace(/,/g, ''));
92
+ if (!Number.isNaN(numericValue)) {
93
+ return {
94
+ prefix,
95
+ numericValue,
96
+ suffix,
97
+ isNumeric: true
98
+ };
99
+ }
100
+ }
101
+ return {
102
+ prefix: '',
103
+ numericValue: 0,
104
+ suffix: '',
105
+ isNumeric: false
106
+ };
107
+ }
108
+ function renderKpiValue(value) {
109
+ const parsed = parseKpiValue(value);
110
+ if (parsed.isNumeric) {
111
+ return /*#__PURE__*/ _jsxs(_Fragment, {
112
+ children: [
113
+ parsed.prefix,
114
+ /*#__PURE__*/ _jsx(CountUp, {
115
+ to: parsed.numericValue,
116
+ from: 0,
117
+ duration: 0.5,
118
+ className: "inline"
119
+ }),
120
+ parsed.suffix
121
+ ]
122
+ });
123
+ }
124
+ return value;
125
+ }
126
+ const kpiCards = [
83
127
  {
84
128
  label: 'Total',
85
- value: '1211',
86
- variant: 'neutral'
129
+ value: renderKpiValue('1211'),
130
+ variant: 'info'
87
131
  },
88
132
  {
89
133
  label: 'Success',
90
- value: '1200',
134
+ value: renderKpiValue('1200'),
91
135
  variant: 'success'
92
136
  },
93
137
  {
94
138
  label: 'Neutral',
95
- value: '11',
139
+ value: renderKpiValue('11'),
96
140
  variant: 'neutral'
97
141
  },
98
142
  {
99
143
  label: 'Failure rate',
100
- value: '0%',
144
+ value: renderKpiValue('0%'),
101
145
  variant: 'success'
102
146
  }
103
147
  ];
104
- /**
105
- * Analytics Page
106
- *
107
- * Main analytics page with KPI cards, charts, and jobs table.
108
- * Uses DashboardContext for state management and generic reusable components.
109
- *
110
- * @example
111
- * ```tsx
112
- * <DashboardProvider>
113
- * <AnalyticsPage />
114
- * </DashboardProvider>
115
- * ```
116
- */ export function AnalyticsPage() {
148
+ export function AnalyticsPage() {
117
149
  const { searchQuery, setSearchQuery, timePeriod, setTimePeriod, lastUpdated, columnVisibility, updateColumnVisibility, activeSidebarItem, setActiveSidebarItem, resourceType, setResourceType } = useDashboardContext();
118
- // Responsive breakpoints
119
150
  const isDesktop = useMediaQuery('(min-width: 1024px)');
120
- // Get the active sidebar item label for the title
121
151
  const pageTitle = useMemo(()=>{
122
152
  const activeItem = defaultSidebarItems.find((item)=>item.id === activeSidebarItem);
123
- return activeItem?.label || 'Reliability'; // Default to Reliability
153
+ return activeItem?.label || 'Reliability';
124
154
  }, [
125
155
  activeSidebarItem
126
156
  ]);
127
- // Filter data based on search query
128
157
  const filteredData = useMemo(()=>jobsData.filter((job)=>job.name.toLowerCase().includes(searchQuery.toLowerCase())), [
129
158
  searchQuery
130
159
  ]);
@@ -143,7 +172,7 @@ const durationData = generateDurationData();
143
172
  })
144
173
  }),
145
174
  /*#__PURE__*/ _jsxs("div", {
146
- className: "flex flex-1 overflow-hidden bg-background-neutral-base",
175
+ className: "flex flex-1 overflow-hidden",
147
176
  children: [
148
177
  isDesktop && /*#__PURE__*/ _jsx(Sidebar, {
149
178
  items: defaultSidebarItems,
@@ -241,9 +270,26 @@ const durationData = generateDurationData();
241
270
  title: "Analytics breakdown",
242
271
  columns: jobColumns,
243
272
  data: filteredData,
244
- searchQuery: searchQuery,
245
- onSearchChange: setSearchQuery,
246
- onSearchClear: ()=>setSearchQuery(''),
273
+ headerActions: /*#__PURE__*/ _jsxs(_Fragment, {
274
+ children: [
275
+ /*#__PURE__*/ _jsx(SearchInline, {
276
+ placeholder: "Search...",
277
+ value: searchQuery,
278
+ onChange: (e)=>setSearchQuery(e.target.value),
279
+ onClear: ()=>setSearchQuery(''),
280
+ className: "flex-1 md:w-240"
281
+ }),
282
+ /*#__PURE__*/ _jsx(Button, {
283
+ variant: "secondary",
284
+ "aria-label": "Insert column left",
285
+ className: "shrink-0",
286
+ children: /*#__PURE__*/ _jsx(Icon, {
287
+ name: "insertColumnLeft",
288
+ className: "size-16 text-foreground-neutral-subtle"
289
+ })
290
+ })
291
+ ]
292
+ }),
247
293
  columnVisibility: columnVisibility,
248
294
  onColumnVisibilityChange: updateColumnVisibility
249
295
  })
@@ -1,20 +1,2 @@
1
- /**
2
- * Jobs Page Component
3
- *
4
- * Refactored jobs page using DashboardContext and generic components.
5
- */
6
- /**
7
- * Jobs Page
8
- *
9
- * Simple jobs page with table showing job breakdown.
10
- * Uses DashboardContext for state management and generic reusable components.
11
- *
12
- * @example
13
- * ```tsx
14
- * <DashboardProvider>
15
- * <JobsPage />
16
- * </DashboardProvider>
17
- * ```
18
- */
19
1
  export declare function JobsPage(): import("react/jsx-runtime").JSX.Element;
20
2
  //# sourceMappingURL=jobs-page.d.ts.map
@@ -1,29 +1,15 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * Jobs Page Component
4
- *
5
- * Refactored jobs page using DashboardContext and generic components.
6
- */ import { jobColumns } from '../../../components/table/table.stories.columns.js';
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Button } from '../../../components/button/index.js';
3
+ import { Icon } from '../../../components/icon/index.js';
4
+ import { SearchInline } from '../../../components/search/search-inline.js';
5
+ import { jobColumns } from '../../../components/table/table.stories.columns.js';
7
6
  import { jobsData } from '../../../components/table/table.stories.data.js';
8
7
  import { useMemo } from 'react';
9
8
  import { useDashboardContext } from '../context/index.js';
10
9
  import { TableWrapper } from '../table/index.js';
11
10
  import { PageToolbar } from '../toolbar/index.js';
12
- /**
13
- * Jobs Page
14
- *
15
- * Simple jobs page with table showing job breakdown.
16
- * Uses DashboardContext for state management and generic reusable components.
17
- *
18
- * @example
19
- * ```tsx
20
- * <DashboardProvider>
21
- * <JobsPage />
22
- * </DashboardProvider>
23
- * ```
24
- */ export function JobsPage() {
11
+ export function JobsPage() {
25
12
  const { searchQuery, setSearchQuery, timePeriod, setTimePeriod, lastUpdated, columnVisibility, updateColumnVisibility } = useDashboardContext();
26
- // Filter data based on search query
27
13
  const filteredData = useMemo(()=>jobsData.filter((job)=>job.name.toLowerCase().includes(searchQuery.toLowerCase())), [
28
14
  searchQuery
29
15
  ]);
@@ -37,14 +23,31 @@ import { PageToolbar } from '../toolbar/index.js';
37
23
  lastUpdated: lastUpdated
38
24
  }),
39
25
  /*#__PURE__*/ _jsx("div", {
40
- className: "flex-1 px-12 pb-12 pt-4 md:px-24 md:pb-24 bg-background-neutral-base overflow-auto",
26
+ className: "flex-1 px-12 pb-12 pt-4 md:px-24 md:pb-24 overflow-auto",
41
27
  children: /*#__PURE__*/ _jsx(TableWrapper, {
42
28
  title: "Jobs breakdown",
43
29
  columns: jobColumns,
44
30
  data: filteredData,
45
- searchQuery: searchQuery,
46
- onSearchChange: setSearchQuery,
47
- onSearchClear: ()=>setSearchQuery(''),
31
+ headerActions: /*#__PURE__*/ _jsxs(_Fragment, {
32
+ children: [
33
+ /*#__PURE__*/ _jsx(SearchInline, {
34
+ placeholder: "Search...",
35
+ value: searchQuery,
36
+ onChange: (e)=>setSearchQuery(e.target.value),
37
+ onClear: ()=>setSearchQuery(''),
38
+ className: "flex-1 md:w-240"
39
+ }),
40
+ /*#__PURE__*/ _jsx(Button, {
41
+ variant: "secondary",
42
+ "aria-label": "Insert column left",
43
+ className: "shrink-0",
44
+ children: /*#__PURE__*/ _jsx(Icon, {
45
+ name: "insertColumnLeft",
46
+ className: "size-16 text-foreground-neutral-subtle"
47
+ })
48
+ })
49
+ ]
50
+ }),
48
51
  columnVisibility: columnVisibility,
49
52
  onColumnVisibilityChange: updateColumnVisibility
50
53
  })
@@ -18,23 +18,6 @@ export interface TableWrapperProps<TData, TValue> extends Omit<ComponentProps<'d
18
18
  * Data to display in the table
19
19
  */
20
20
  data: TData[];
21
- /**
22
- * Search query value
23
- */
24
- searchQuery?: string;
25
- /**
26
- * Search input change handler
27
- */
28
- onSearchChange?: (value: string) => void;
29
- /**
30
- * Search clear handler
31
- */
32
- onSearchClear?: () => void;
33
- /**
34
- * Search placeholder text
35
- * @default 'Search...'
36
- */
37
- searchPlaceholder?: string;
38
21
  /**
39
22
  * Column visibility state
40
23
  */
@@ -72,14 +55,20 @@ export interface TableWrapperProps<TData, TValue> extends Omit<ComponentProps<'d
72
55
  */
73
56
  emptyState?: ReactNode;
74
57
  /**
75
- * Additional header actions
58
+ * Header actions to display in the card header
76
59
  */
77
60
  headerActions?: ReactNode;
78
61
  /**
79
- * Show default search and column action
80
- * @default true
62
+ * Loading state - displays skeleton when true
63
+ */
64
+ isLoading?: boolean;
65
+ /**
66
+ * Optional scoped container element for dropdown portals.
67
+ *
68
+ * When provided, dropdowns (like pagination select) will be rendered inside this container
69
+ * instead of the document body. This is useful for scoped CSS styling.
81
70
  */
82
- showDefaultActions?: boolean;
71
+ scopedContainer?: HTMLElement | null;
83
72
  }
84
73
  /**
85
74
  * Generic Table Wrapper
@@ -93,12 +82,20 @@ export interface TableWrapperProps<TData, TValue> extends Omit<ComponentProps<'d
93
82
  * title="Jobs breakdown"
94
83
  * columns={jobColumns}
95
84
  * data={jobsData}
96
- * searchQuery={searchQuery}
97
- * onSearchChange={setSearchQuery}
85
+ * headerActions={
86
+ * <>
87
+ * <SearchInline
88
+ * placeholder="Search..."
89
+ * value={searchQuery}
90
+ * onChange={(e) => setSearchQuery(e.target.value)}
91
+ * />
92
+ * <Button variant="secondary">Action</Button>
93
+ * </>
94
+ * }
98
95
  * columnVisibility={columnVisibility}
99
96
  * onColumnVisibilityChange={updateColumnVisibility}
100
97
  * />
101
98
  * ```
102
99
  */
103
- export declare function TableWrapper<TData, TValue>({ title, columns, data, searchQuery, onSearchChange, onSearchClear, searchPlaceholder, columnVisibility, onColumnVisibilityChange, pagination, pageSize, pageSizeOptions, showSelectedCount, onRowClick, emptyState, headerActions, showDefaultActions, className, ...props }: TableWrapperProps<TData, TValue>): import("react/jsx-runtime").JSX.Element;
100
+ export declare function TableWrapper<TData, TValue>({ title, columns, data, columnVisibility, onColumnVisibilityChange, pagination, pageSize, pageSizeOptions, showSelectedCount, onRowClick, emptyState, headerActions, isLoading, scopedContainer, className, ...props }: TableWrapperProps<TData, TValue>): import("react/jsx-runtime").JSX.Element;
104
101
  //# sourceMappingURL=table-wrapper.d.ts.map
@@ -2,12 +2,9 @@
2
2
  * Generic Table Wrapper Component
3
3
  *
4
4
  * A reusable wrapper for dashboard tables with header, search, and actions.
5
- */ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
6
- import { Button } from '../../../components/button/index.js';
7
- import { Icon } from '../../../components/icon/index.js';
8
- import { SearchInline } from '../../../components/search/search-inline.js';
5
+ */ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
+ import { Card, CardAction, CardContent, CardHeader, CardTitle } from '../../../components/card/index.js';
9
7
  import { DataTable } from '../../../components/table/data-table.js';
10
- import { Header as TypographyHeader } from '../../../components/typography/index.js';
11
8
  import { cn } from '../../../utils/cn.js';
12
9
  /**
13
10
  * Generic Table Wrapper
@@ -21,70 +18,60 @@ import { cn } from '../../../utils/cn.js';
21
18
  * title="Jobs breakdown"
22
19
  * columns={jobColumns}
23
20
  * data={jobsData}
24
- * searchQuery={searchQuery}
25
- * onSearchChange={setSearchQuery}
21
+ * headerActions={
22
+ * <>
23
+ * <SearchInline
24
+ * placeholder="Search..."
25
+ * value={searchQuery}
26
+ * onChange={(e) => setSearchQuery(e.target.value)}
27
+ * />
28
+ * <Button variant="secondary">Action</Button>
29
+ * </>
30
+ * }
26
31
  * columnVisibility={columnVisibility}
27
32
  * onColumnVisibilityChange={updateColumnVisibility}
28
33
  * />
29
34
  * ```
30
- */ export function TableWrapper({ title, columns, data, searchQuery = '', onSearchChange, onSearchClear, searchPlaceholder = 'Search...', columnVisibility, onColumnVisibilityChange, pagination = true, pageSize = 10, pageSizeOptions = [
35
+ */ export function TableWrapper({ title, columns, data, columnVisibility, onColumnVisibilityChange, pagination = true, pageSize = 10, pageSizeOptions = [
31
36
  10,
32
37
  20,
33
38
  50,
34
39
  100
35
- ], showSelectedCount = false, onRowClick, emptyState, headerActions, showDefaultActions = true, className, ...props }) {
36
- return /*#__PURE__*/ _jsxs("div", {
37
- className: cn('rounded-t-8 overflow-hidden', className),
40
+ ], showSelectedCount = false, onRowClick, emptyState, headerActions, isLoading, scopedContainer, className, ...props }) {
41
+ return /*#__PURE__*/ _jsxs(Card, {
42
+ className: cn('rounded-t-8 overflow-hidden p-0 gap-0 border-none', className),
38
43
  ...props,
39
44
  children: [
40
- /*#__PURE__*/ _jsxs("div", {
41
- className: "flex flex-col md:flex-row md:items-center md:justify-between gap-12 md:gap-0 p-12 border-t border-x border-border-neutral-base rounded-t-8 bg-background-neutral-base",
45
+ /*#__PURE__*/ _jsxs(CardHeader, {
46
+ className: "flex flex-col md:flex-row md:items-center md:justify-between gap-12 md:gap-0 p-12 rounded-t-8 border-t border-x border-border-neutral-base",
42
47
  children: [
43
- typeof title === 'string' ? /*#__PURE__*/ _jsx(TypographyHeader, {
48
+ typeof title === 'string' ? /*#__PURE__*/ _jsx(CardTitle, {
44
49
  variant: "h3",
45
- className: "text-foreground-neutral-base",
46
50
  children: title
47
51
  }) : title,
48
- (showDefaultActions || headerActions) && /*#__PURE__*/ _jsxs("div", {
52
+ headerActions && /*#__PURE__*/ _jsx(CardAction, {
49
53
  className: "flex items-center gap-8 md:gap-16 w-full md:w-auto",
50
- children: [
51
- showDefaultActions && /*#__PURE__*/ _jsxs(_Fragment, {
52
- children: [
53
- /*#__PURE__*/ _jsx(SearchInline, {
54
- placeholder: searchPlaceholder,
55
- value: searchQuery,
56
- onChange: (e)=>onSearchChange?.(e.target.value),
57
- onClear: ()=>onSearchClear?.(),
58
- className: "flex-1 md:w-240"
59
- }),
60
- /*#__PURE__*/ _jsx(Button, {
61
- variant: "secondary",
62
- "aria-label": "Insert column left",
63
- className: "shrink-0",
64
- children: /*#__PURE__*/ _jsx(Icon, {
65
- name: "insertColumnLeft",
66
- className: "size-16 text-foreground-neutral-subtle"
67
- })
68
- })
69
- ]
70
- }),
71
- headerActions
72
- ]
54
+ children: headerActions
73
55
  })
74
56
  ]
75
57
  }),
76
- /*#__PURE__*/ _jsx(DataTable, {
77
- columns: columns,
78
- data: data,
79
- pagination: pagination,
80
- pageSize: pageSize,
81
- pageSizeOptions: pageSizeOptions,
82
- showSelectedCount: showSelectedCount,
83
- onRowClick: onRowClick,
84
- emptyState: emptyState,
85
- columnVisibility: columnVisibility,
86
- onColumnVisibilityChange: onColumnVisibilityChange,
87
- className: "rounded-t-none"
58
+ /*#__PURE__*/ _jsx(CardContent, {
59
+ className: "p-0",
60
+ children: /*#__PURE__*/ _jsx(DataTable, {
61
+ columns: columns,
62
+ data: data,
63
+ isLoading: isLoading,
64
+ pagination: pagination,
65
+ pageSize: pageSize,
66
+ pageSizeOptions: pageSizeOptions,
67
+ showSelectedCount: showSelectedCount,
68
+ onRowClick: onRowClick,
69
+ emptyState: emptyState,
70
+ columnVisibility: columnVisibility,
71
+ onColumnVisibilityChange: onColumnVisibilityChange,
72
+ scopedContainer: scopedContainer,
73
+ className: "rounded-t-none"
74
+ })
88
75
  })
89
76
  ]
90
77
  });