flikkui 0.2.0-beta.2 → 0.2.0-beta.5
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 +92 -0
- package/dist/components/ai/PromptInput/PromptInput.js +23 -15
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.d.ts +27 -0
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.js +62 -0
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.d.ts +10 -0
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.js +12 -0
- package/dist/components/ai/PromptSuggestions/PromptSuggestion.types.d.ts +53 -0
- package/dist/components/ai/PromptSuggestions/index.d.ts +4 -2
- package/dist/components/ai/index.d.ts +2 -12
- package/dist/components/charts/ActivityRings/ActivityRings.js +70 -58
- package/dist/components/charts/ActivityRings/ActivityRings.theme.js +0 -1
- package/dist/components/charts/ActivityRings/ActivityRings.types.d.ts +17 -0
- package/dist/components/charts/BarChart/BarChart.js +8 -4
- package/dist/components/charts/BarChart/BarChart.types.d.ts +14 -0
- package/dist/components/charts/DonutChart/DonutChart.js +11 -8
- package/dist/components/charts/DonutChart/DonutChart.theme.d.ts +3 -0
- package/dist/components/charts/DonutChart/DonutChart.theme.js +5 -4
- package/dist/components/charts/DonutChart/donut-utils.d.ts +5 -0
- package/dist/components/charts/DonutChart/donut-utils.js +26 -1
- package/dist/components/charts/Heatmap/Heatmap.theme.js +2 -2
- package/dist/components/charts/shared/ChartAxis/XAxis.d.ts +2 -2
- package/dist/components/charts/shared/ChartAxis/XAxis.js +4 -4
- package/dist/components/charts/shared/ChartAxis/YAxis.d.ts +2 -2
- package/dist/components/charts/shared/ChartAxis/YAxis.js +8 -7
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.d.ts +1 -1
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.js +2 -2
- package/dist/components/charts/theme/chart.theme.d.ts +1 -1
- package/dist/components/charts/theme/chart.theme.js +39 -39
- package/dist/components/core/Accordion/Accordion.d.ts +1 -1
- package/dist/components/core/Accordion/Accordion.js +2 -2
- package/dist/components/core/Accordion/Accordion.types.d.ts +8 -0
- package/dist/components/core/Badge/Badge.js +11 -15
- package/dist/components/core/Badge/Badge.theme.js +7 -21
- package/dist/components/core/Badge/Badge.types.d.ts +9 -1
- package/dist/components/core/Button/Button.js +2 -2
- package/dist/components/core/Button/Button.theme.js +1 -1
- package/dist/components/core/Button/Button.types.d.ts +8 -0
- package/dist/components/core/Card/Card.js +8 -2
- package/dist/components/core/Card/Card.theme.js +1 -1
- package/dist/components/core/Card/Card.types.d.ts +24 -1
- package/dist/components/core/Drawer/Drawer.d.ts +1 -1
- package/dist/components/core/Drawer/Drawer.js +10 -40
- package/dist/components/core/Drawer/Drawer.theme.js +2 -1
- package/dist/components/core/Drawer/Drawer.types.d.ts +8 -0
- package/dist/components/core/Dropdown/Dropdown.d.ts +1 -1
- package/dist/components/core/Dropdown/Dropdown.js +2 -2
- package/dist/components/core/Dropdown/Dropdown.types.d.ts +8 -0
- package/dist/components/core/Metric/Metric.d.ts +1 -1
- package/dist/components/core/Metric/Metric.js +9 -5
- package/dist/components/core/Metric/Metric.theme.d.ts +1 -1
- package/dist/components/core/Metric/Metric.theme.js +38 -28
- package/dist/components/core/Metric/Metric.types.d.ts +27 -8
- package/dist/components/core/Modal/Modal.d.ts +1 -1
- package/dist/components/core/Modal/Modal.js +17 -40
- package/dist/components/core/Modal/Modal.theme.js +8 -3
- package/dist/components/core/Modal/Modal.types.d.ts +18 -0
- package/dist/components/core/Modal/index.d.ts +1 -1
- package/dist/components/core/Notification/Notification.js +2 -0
- package/dist/components/core/Pill/Pill.d.ts +6 -11
- package/dist/components/core/Pill/Pill.theme.d.ts +2 -2
- package/dist/components/core/Pill/Pill.types.d.ts +9 -22
- package/dist/components/core/Pill/index.d.ts +1 -1
- package/dist/components/core/Popover/Popover.d.ts +1 -1
- package/dist/components/core/Popover/Popover.js +2 -2
- package/dist/components/core/Popover/Popover.types.d.ts +8 -0
- package/dist/components/core/Progress/Progress.d.ts +28 -0
- package/dist/components/core/Progress/Progress.js +114 -0
- package/dist/components/core/Progress/Progress.theme.d.ts +5 -0
- package/dist/components/core/Progress/Progress.theme.js +33 -0
- package/dist/components/core/Progress/Progress.types.d.ts +92 -0
- package/dist/components/core/Progress/index.d.ts +2 -0
- package/dist/components/core/Table/Table.animations.d.ts +5 -16
- package/dist/components/core/Table/Table.animations.js +46 -0
- package/dist/components/core/Table/Table.d.ts +0 -27
- package/dist/components/core/Table/Table.js +58 -156
- package/dist/components/core/Table/Table.theme.js +28 -19
- package/dist/components/core/Table/Table.types.d.ts +95 -8
- package/dist/components/core/Table/Table.utils.d.ts +7 -0
- package/dist/components/core/Table/Table.utils.js +11 -1
- package/dist/components/core/Table/{components/TableActions/TableActions.d.ts → TableActions.d.ts} +3 -3
- package/dist/components/core/Table/{components/TableActions/TableActions.js → TableActions.js} +14 -24
- package/dist/components/core/Table/{components/TableActions/TableActionsMenu.d.ts → TableActionsMenu.d.ts} +1 -1
- package/dist/components/core/Table/{components/TableActions/TableActionsMenu.js → TableActionsMenu.js} +4 -4
- package/dist/components/core/Table/{components/core/TableBody.d.ts → TableBody.d.ts} +1 -1
- package/dist/components/core/Table/{components/core/TableBody.js → TableBody.js} +14 -20
- package/dist/components/core/Table/{components/core/TableCell.d.ts → TableCell.d.ts} +1 -9
- package/dist/components/core/Table/{components/core/TableCell.js → TableCell.js} +5 -13
- package/dist/components/core/Table/TableColumnManager.d.ts +3 -0
- package/dist/components/core/Table/TableColumnManager.js +34 -0
- package/dist/components/core/Table/{components/DeclarativeComponents.d.ts → TableDeclarative.d.ts} +1 -1
- package/dist/components/core/Table/{components/DeclarativeComponents.js → TableDeclarative.js} +6 -56
- package/dist/components/core/Table/TableFilter.d.ts +3 -0
- package/dist/components/core/Table/TableFilter.js +122 -0
- package/dist/components/core/Table/{components/core/TableHeader.d.ts → TableHeader.d.ts} +1 -1
- package/dist/components/core/Table/{components/core/TableHeader.js → TableHeader.js} +15 -29
- package/dist/components/core/Table/TablePagination.d.ts +7 -0
- package/dist/components/core/Table/{components/TablePagination/TablePagination.js → TablePagination.js} +5 -16
- package/dist/components/core/Table/TableRow.d.ts +8 -0
- package/dist/components/core/Table/TableRow.js +45 -0
- package/dist/components/core/Table/TableSelectionHeader.d.ts +7 -0
- package/dist/components/core/Table/{components/TableSelectionHeader/TableSelectionHeader.js → TableSelectionHeader.js} +4 -5
- package/dist/components/core/Table/hooks/index.d.ts +10 -0
- package/dist/components/core/Table/hooks/useTableColumns.d.ts +16 -0
- package/dist/components/core/Table/hooks/useTableColumns.js +67 -0
- package/dist/components/core/Table/hooks/useTableExpansion.d.ts +8 -0
- package/dist/components/core/Table/hooks/useTableExpansion.js +15 -0
- package/dist/components/core/Table/hooks/useTableFilter.d.ts +12 -0
- package/dist/components/core/Table/hooks/useTableFilter.js +37 -0
- package/dist/components/core/Table/hooks/useTablePagination.d.ts +12 -0
- package/dist/components/core/Table/hooks/useTablePagination.js +13 -0
- package/dist/components/core/Table/hooks/useTableSelection.d.ts +17 -0
- package/dist/components/core/Table/hooks/useTableSelection.js +40 -0
- package/dist/components/core/Table/index.d.ts +9 -8
- package/dist/components/core/Table/index.js +7 -5
- package/dist/components/core/Tabs/Tabs.js +2 -2
- package/dist/components/core/Tabs/Tabs.types.d.ts +8 -0
- package/dist/components/core/Tag/Tag.animations.d.ts +3 -0
- package/dist/components/core/Tag/Tag.animations.js +31 -0
- package/dist/components/core/Tag/Tag.d.ts +14 -0
- package/dist/components/core/Tag/Tag.js +45 -0
- package/dist/components/core/Tag/Tag.theme.d.ts +2 -0
- package/dist/components/core/Tag/Tag.theme.js +21 -0
- package/dist/components/core/Tag/Tag.types.d.ts +40 -0
- package/dist/components/core/Tag/index.d.ts +3 -0
- package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
- package/dist/components/core/Tooltip/Tooltip.js +3 -3
- package/dist/components/core/Tooltip/Tooltip.theme.js +1 -1
- package/dist/components/core/Tooltip/Tooltip.types.d.ts +17 -0
- package/dist/components/core/index.d.ts +2 -1
- package/dist/components/core/index.js +12 -5
- package/dist/components/effects/CustomCursor/CustomCursor.d.ts +0 -13
- package/dist/components/effects/CustomCursor/CustomCursor.js +26 -2
- package/dist/components/effects/CustomCursor/CustomCursor.theme.js +12 -1
- package/dist/components/effects/CustomCursor/CustomCursor.types.d.ts +14 -1
- package/dist/components/forms/Combobox/Combobox.d.ts +25 -0
- package/dist/components/forms/Combobox/Combobox.js +412 -0
- package/dist/components/forms/Combobox/Combobox.theme.d.ts +6 -0
- package/dist/components/forms/Combobox/Combobox.theme.js +60 -0
- package/dist/components/forms/Combobox/Combobox.types.d.ts +111 -0
- package/dist/components/forms/Combobox/index.d.ts +3 -0
- package/dist/components/forms/FileUpload/FileUpload.js +2 -0
- package/dist/components/forms/Input/Input.js +25 -28
- package/dist/components/forms/Input/inputMasks.d.ts +15 -0
- package/dist/components/forms/Input/inputMasks.js +72 -1
- package/dist/components/forms/InputTag/InputTag.d.ts +40 -0
- package/dist/components/forms/InputTag/InputTag.js +491 -0
- package/dist/components/forms/InputTag/InputTag.theme.d.ts +2 -0
- package/dist/components/forms/InputTag/InputTag.theme.js +16 -0
- package/dist/components/forms/InputTag/InputTag.types.d.ts +107 -0
- package/dist/components/forms/InputTag/index.d.ts +3 -0
- package/dist/components/forms/Select/Select.d.ts +101 -2
- package/dist/components/forms/Select/Select.js +128 -132
- package/dist/components/forms/Select/Select.theme.js +10 -14
- package/dist/components/forms/Select/Select.types.d.ts +6 -2
- package/dist/components/forms/Select/index.d.ts +7 -4
- package/dist/components/forms/Select/useSelectState.d.ts +66 -0
- package/dist/components/forms/Select/useSelectState.js +134 -0
- package/dist/components/forms/SelectExpand/SelectExpand.animations.d.ts +20 -0
- package/dist/components/forms/SelectExpand/SelectExpand.animations.js +74 -0
- package/dist/components/forms/SelectExpand/SelectExpand.d.ts +9 -0
- package/dist/components/forms/SelectExpand/SelectExpand.js +223 -0
- package/dist/components/forms/SelectExpand/SelectExpand.theme.d.ts +5 -0
- package/dist/components/forms/SelectExpand/SelectExpand.theme.js +74 -0
- package/dist/components/forms/SelectExpand/SelectExpand.types.d.ts +126 -0
- package/dist/components/forms/SelectExpand/index.d.ts +4 -0
- package/dist/components/forms/Switch/Switch.js +3 -3
- package/dist/components/forms/Switch/Switch.theme.d.ts +1 -1
- package/dist/components/forms/Switch/Switch.theme.js +2 -2
- package/dist/components/forms/TimePicker/TimePicker.animations.d.ts +0 -46
- package/dist/components/forms/TimePicker/TimePicker.d.ts +15 -6
- package/dist/components/forms/TimePicker/TimePicker.js +285 -124
- package/dist/components/forms/TimePicker/TimePicker.theme.d.ts +1 -1
- package/dist/components/forms/TimePicker/TimePicker.theme.js +39 -22
- package/dist/components/forms/TimePicker/TimePicker.types.d.ts +88 -34
- package/dist/components/forms/TimePicker/TimePickerContent.d.ts +7 -10
- package/dist/components/forms/TimePicker/TimePickerContent.js +149 -16
- package/dist/components/forms/TimePicker/TimePickerTrigger.d.ts +3 -3
- package/dist/components/forms/TimePicker/TimePickerTrigger.js +22 -19
- package/dist/components/forms/TimePicker/WheelColumn.d.ts +14 -0
- package/dist/components/forms/TimePicker/WheelColumn.js +90 -0
- package/dist/components/forms/TimePicker/index.d.ts +4 -1
- package/dist/components/forms/TimePicker/useWheelPicker.d.ts +37 -0
- package/dist/components/forms/TimePicker/useWheelPicker.js +138 -0
- package/dist/components/forms/forms.theme.d.ts +14 -0
- package/dist/components/forms/forms.theme.js +31 -0
- package/dist/components/forms/index.d.ts +9 -3
- package/dist/components/forms/index.js +73 -2
- package/dist/hooks/index.d.ts +0 -4
- package/dist/icons/Icon.d.ts +7 -0
- package/dist/icons/Icon.js +6 -2
- package/dist/index.js +21 -19
- package/dist/styles.css +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/optimisticErrors.js +1 -70
- package/package.json +1 -1
- package/dist/components/ai/EditingIndicator/EditingIndicator.animations.d.ts +0 -31
- package/dist/components/ai/EditingIndicator/EditingIndicator.animations.js +0 -115
- package/dist/components/ai/EditingIndicator/EditingIndicator.d.ts +0 -35
- package/dist/components/ai/EditingIndicator/EditingIndicator.js +0 -94
- package/dist/components/ai/EditingIndicator/EditingIndicator.theme.d.ts +0 -2
- package/dist/components/ai/EditingIndicator/EditingIndicator.theme.js +0 -13
- package/dist/components/ai/EditingIndicator/EditingIndicator.types.d.ts +0 -54
- package/dist/components/ai/EditingIndicator/index.d.ts +0 -9
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.d.ts +0 -3
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.js +0 -126
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.theme.d.ts +0 -2
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.theme.js +0 -8
- package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.types.d.ts +0 -45
- package/dist/components/ai/GenerativeRenderer/index.d.ts +0 -3
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.animations.d.ts +0 -17
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.animations.js +0 -56
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.d.ts +0 -38
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.js +0 -110
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.theme.d.ts +0 -2
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.theme.js +0 -13
- package/dist/components/ai/PresenceIndicator/PresenceIndicator.types.d.ts +0 -53
- package/dist/components/ai/PresenceIndicator/index.d.ts +0 -8
- package/dist/components/ai/PresenceProvider/PresenceContext.d.ts +0 -24
- package/dist/components/ai/PresenceProvider/PresenceContext.js +0 -34
- package/dist/components/ai/PresenceProvider/PresenceProvider.d.ts +0 -32
- package/dist/components/ai/PresenceProvider/PresenceProvider.js +0 -321
- package/dist/components/ai/PresenceProvider/PresenceProvider.types.d.ts +0 -140
- package/dist/components/ai/PresenceProvider/adapters/MockAdapter.d.ts +0 -102
- package/dist/components/ai/PresenceProvider/adapters/MockAdapter.js +0 -331
- package/dist/components/ai/PresenceProvider/adapters/PresenceAdapter.d.ts +0 -93
- package/dist/components/ai/PresenceProvider/adapters/SupabaseAdapter.d.ts +0 -134
- package/dist/components/ai/PresenceProvider/adapters/WebSocketAdapter.d.ts +0 -149
- package/dist/components/ai/PresenceProvider/adapters/index.d.ts +0 -11
- package/dist/components/ai/PresenceProvider/index.d.ts +0 -10
- package/dist/components/ai/PromptSuggestions/PromptSuggestions.d.ts +0 -27
- package/dist/components/ai/PromptSuggestions/PromptSuggestions.js +0 -61
- package/dist/components/ai/PromptSuggestions/PromptSuggestions.types.d.ts +0 -65
- package/dist/components/ai/VersionSlider/VersionSlider.d.ts +0 -3
- package/dist/components/ai/VersionSlider/VersionSlider.js +0 -97
- package/dist/components/ai/VersionSlider/VersionSlider.theme.d.ts +0 -2
- package/dist/components/ai/VersionSlider/VersionSlider.theme.js +0 -18
- package/dist/components/ai/VersionSlider/VersionSlider.types.d.ts +0 -77
- package/dist/components/ai/VersionSlider/index.d.ts +0 -3
- package/dist/components/core/Pill/Pill.animations.js +0 -25
- package/dist/components/core/Pill/Pill.js +0 -145
- package/dist/components/core/Pill/Pill.theme.js +0 -65
- package/dist/components/core/RetryBoundary/RetryBoundary.d.ts +0 -35
- package/dist/components/core/RetryBoundary/RetryBoundary.js +0 -154
- package/dist/components/core/RetryBoundary/RetryBoundary.theme.d.ts +0 -2
- package/dist/components/core/RetryBoundary/RetryBoundary.theme.js +0 -7
- package/dist/components/core/RetryBoundary/RetryBoundary.types.d.ts +0 -51
- package/dist/components/core/RetryBoundary/index.d.ts +0 -3
- package/dist/components/core/Table/components/TableActions/TableActions.types.d.ts +0 -40
- package/dist/components/core/Table/components/TableActions/index.d.ts +0 -3
- package/dist/components/core/Table/components/TableActionsMenu.d.ts +0 -6
- package/dist/components/core/Table/components/TablePagination/TablePagination.d.ts +0 -17
- package/dist/components/core/Table/components/TablePagination/TablePagination.types.d.ts +0 -21
- package/dist/components/core/Table/components/TablePagination/index.d.ts +0 -2
- package/dist/components/core/Table/components/TableSelectionHeader/TableSelectionHeader.d.ts +0 -15
- package/dist/components/core/Table/components/TableSelectionHeader/index.d.ts +0 -3
- package/dist/components/core/Table/components/core/TableRow.d.ts +0 -3
- package/dist/components/core/Table/components/core/TableRow.js +0 -44
- package/dist/components/core/Table/components/core/index.d.ts +0 -4
- package/dist/components/forms/OptimisticForm/OptimisticForm.d.ts +0 -33
- package/dist/components/forms/OptimisticForm/OptimisticForm.js +0 -87
- package/dist/components/forms/OptimisticForm/OptimisticForm.theme.d.ts +0 -2
- package/dist/components/forms/OptimisticForm/OptimisticForm.theme.js +0 -8
- package/dist/components/forms/OptimisticForm/OptimisticForm.types.d.ts +0 -74
- package/dist/components/forms/OptimisticForm/index.d.ts +0 -3
- package/dist/hooks/useOptimisticMutation.d.ts +0 -109
- package/dist/hooks/useOptimisticMutation.js +0 -171
- package/dist/hooks/usePresence.d.ts +0 -88
- package/dist/utils/presenceUtils.d.ts +0 -66
- package/dist/utils/presenceUtils.js +0 -107
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
2
|
import { TableRow } from './TableRow.js';
|
|
3
|
-
import { getRowId } from '
|
|
3
|
+
import { getRowId } from './Table.utils.js';
|
|
4
|
+
import { useTableExpansion } from './hooks/useTableExpansion.js';
|
|
5
|
+
import { useTableSelection } from './hooks/useTableSelection.js';
|
|
4
6
|
|
|
5
7
|
function TableBodyComponent({ data, columns, rowKey, expandedRowRender, expandedRows = [], onExpandedRowsChange, selectable, selectionType, selectedRows = [], onSelectionChange, freezeFirstColumn, freezeLastColumn, theme, }) {
|
|
6
|
-
const handleExpandChange = (
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const newSelectedRows = selectionType === 'checkbox'
|
|
18
|
-
? selected
|
|
19
|
-
? [...selectedRows, rowId]
|
|
20
|
-
: selectedRows.filter(id => id !== rowId)
|
|
21
|
-
: selected ? [rowId] : [];
|
|
22
|
-
onSelectionChange(newSelectedRows);
|
|
23
|
-
};
|
|
8
|
+
const { handleExpandChange } = useTableExpansion({
|
|
9
|
+
expandedRows,
|
|
10
|
+
onExpandedRowsChange,
|
|
11
|
+
});
|
|
12
|
+
const { handleSelectionChange } = useTableSelection({
|
|
13
|
+
data,
|
|
14
|
+
rowKey,
|
|
15
|
+
selectionType,
|
|
16
|
+
selectedRows,
|
|
17
|
+
onSelectionChange,
|
|
18
|
+
});
|
|
24
19
|
return (React__default.createElement("tbody", null, data.map((row, index) => {
|
|
25
20
|
const rowId = getRowId(row, index, rowKey);
|
|
26
21
|
return (React__default.createElement(TableRow, { key: rowId, row: row, rowId: rowId, columns: columns, expandedRowRender: expandedRowRender, isExpanded: expandedRows.includes(rowId), onExpandChange: (expanded) => handleExpandChange(rowId, expanded), selectable: selectable, selectionType: selectionType, isSelected: selectedRows.includes(rowId), onSelectionChange: (selected) => handleSelectionChange(rowId, selected), freezeFirstColumn: freezeFirstColumn, freezeLastColumn: freezeLastColumn, theme: theme }));
|
|
27
22
|
})));
|
|
28
23
|
}
|
|
29
|
-
// Export with proper type annotation
|
|
30
24
|
const TableBody = TableBodyComponent;
|
|
31
25
|
|
|
32
26
|
export { TableBody };
|
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { InternalTableCellProps } from '
|
|
2
|
+
import { InternalTableCellProps } from './Table.types';
|
|
3
3
|
/**
|
|
4
4
|
* Internal TableCell component used by the data-driven API
|
|
5
5
|
* Handles both header and data cells with proper theming and accessibility
|
|
6
6
|
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Dynamic cell type (th/td) based on isHeader prop
|
|
9
|
-
* - Frozen column support with visual indicators
|
|
10
|
-
* - Custom cell rendering via column.cell function
|
|
11
|
-
* - Tooltip support for truncated content
|
|
12
|
-
* - Alignment and width customization
|
|
13
|
-
* - Full accessibility with proper ARIA attributes
|
|
14
|
-
*
|
|
15
7
|
* @internal This component is used internally by the Table component
|
|
16
8
|
*/
|
|
17
9
|
declare function TableCellComponent<T extends Record<string, any>>({ column, row, rowId, isHeader, isFrozen, isLastFrozen, theme, children, }: InternalTableCellProps<T>): React.ReactElement;
|
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
|
-
import { cn } from '
|
|
2
|
+
import { cn } from '../../../utils/cn.js';
|
|
3
|
+
import { UTILITY_COLUMN_ID, alignmentClasses } from './Table.utils.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Internal TableCell component used by the data-driven API
|
|
6
7
|
* Handles both header and data cells with proper theming and accessibility
|
|
7
8
|
*
|
|
8
|
-
* Features:
|
|
9
|
-
* - Dynamic cell type (th/td) based on isHeader prop
|
|
10
|
-
* - Frozen column support with visual indicators
|
|
11
|
-
* - Custom cell rendering via column.cell function
|
|
12
|
-
* - Tooltip support for truncated content
|
|
13
|
-
* - Alignment and width customization
|
|
14
|
-
* - Full accessibility with proper ARIA attributes
|
|
15
|
-
*
|
|
16
9
|
* @internal This component is used internally by the Table component
|
|
17
10
|
*/
|
|
18
11
|
function TableCellComponent({ column, row, rowId, isHeader = false, isFrozen = false, isLastFrozen = false, theme, children, }) {
|
|
19
12
|
const Cell = isHeader ? 'th' : 'td';
|
|
13
|
+
const isUtilityColumn = column.id === UTILITY_COLUMN_ID;
|
|
20
14
|
// For header cells, render the column header content
|
|
21
15
|
if (isHeader) {
|
|
22
|
-
const cellClasses = cn(theme === null || theme === void 0 ? void 0 : theme.headerStyle, isFrozen && (theme === null || theme === void 0 ? void 0 : theme.frozenColumnStyle), isLastFrozen && (theme === null || theme === void 0 ? void 0 : theme.lastFrozenColumnStyle), column.align &&
|
|
16
|
+
const cellClasses = cn(theme === null || theme === void 0 ? void 0 : theme.headerStyle, isFrozen && (theme === null || theme === void 0 ? void 0 : theme.frozenColumnStyle), isLastFrozen && (theme === null || theme === void 0 ? void 0 : theme.lastFrozenColumnStyle), column.align && alignmentClasses[column.align], isUtilityColumn && 'whitespace-nowrap');
|
|
23
17
|
return (React__default.createElement(Cell, { className: cellClasses, "data-frozen": isFrozen ? 'true' : isLastFrozen ? 'last' : undefined, style: { width: column.width }, role: "columnheader", "aria-label": typeof column.header === 'string' ? column.header : column.id }, children || column.header));
|
|
24
18
|
}
|
|
25
19
|
// For data cells, extract value using accessor (string key or function)
|
|
@@ -34,12 +28,10 @@ function TableCellComponent({ column, row, rowId, isHeader = false, isFrozen = f
|
|
|
34
28
|
: column.tooltip
|
|
35
29
|
? String(value)
|
|
36
30
|
: undefined;
|
|
37
|
-
const cellClasses = cn(theme === null || theme === void 0 ? void 0 : theme.cellStyle, isFrozen && (theme === null || theme === void 0 ? void 0 : theme.frozenColumnStyle), isLastFrozen && (theme === null || theme === void 0 ? void 0 : theme.lastFrozenColumnStyle), column.align &&
|
|
31
|
+
const cellClasses = cn(theme === null || theme === void 0 ? void 0 : theme.cellStyle, isFrozen && (theme === null || theme === void 0 ? void 0 : theme.frozenColumnStyle), isLastFrozen && (theme === null || theme === void 0 ? void 0 : theme.lastFrozenColumnStyle), column.align && alignmentClasses[column.align], column.ellipsis && 'truncate', isUtilityColumn && 'whitespace-nowrap');
|
|
38
32
|
return (React__default.createElement(Cell, { className: cellClasses, "data-frozen": isFrozen ? 'true' : isLastFrozen ? 'last' : undefined, style: { width: column.width }, title: tooltipContent, role: "cell" }, children || content));
|
|
39
33
|
}
|
|
40
|
-
// Set display name for dev tools
|
|
41
34
|
TableCellComponent.displayName = 'TableCell';
|
|
42
|
-
// Memoize component to prevent unnecessary re-renders when props haven't changed
|
|
43
35
|
const TableCell = React__default.memo(TableCellComponent);
|
|
44
36
|
|
|
45
37
|
export { TableCell };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { Popover } from '../Popover/Popover.js';
|
|
3
|
+
import '../Popover/PopoverContext.js';
|
|
4
|
+
import { Cog6ToothIcon } from '@heroicons/react/24/outline';
|
|
5
|
+
import { Button } from '../Button/Button.js';
|
|
6
|
+
import { Checkbox } from '../../forms/Checkbox/Checkbox.js';
|
|
7
|
+
import { Sortable, SortableItem } from '../Sortable/Sortable.js';
|
|
8
|
+
|
|
9
|
+
function TableColumnManagerComponent({ columns, visibleColumns, columnOrder, onToggleColumn, onResetToDefault, onColumnReorder, }) {
|
|
10
|
+
const orderedColumns = columnOrder.length > 0
|
|
11
|
+
? columnOrder.map(colId => columns.find(col => col.id === colId)).filter(Boolean)
|
|
12
|
+
: columns;
|
|
13
|
+
const renderColumnItem = (column) => {
|
|
14
|
+
const isVisible = visibleColumns.includes(column.id);
|
|
15
|
+
const isLocked = column.locked === true;
|
|
16
|
+
const displayName = typeof column.header === 'string' ? column.header : column.id;
|
|
17
|
+
return (React__default.createElement(Checkbox, { id: `column-checkbox-${column.id}`, name: `column-${column.id}`, value: column.id, checked: isVisible, onChange: () => onToggleColumn(column.id), "aria-label": `Toggle visibility for ${displayName} column`, label: displayName, state: isLocked ? 'disabled' : 'default' }));
|
|
18
|
+
};
|
|
19
|
+
return (React__default.createElement(Popover, { placement: "bottom-end", offset: 8 },
|
|
20
|
+
React__default.createElement(Popover.Trigger, null,
|
|
21
|
+
React__default.createElement(Button, { color: "neutral", variant: "filled", "aria-label": "Manage column visibility" },
|
|
22
|
+
React__default.createElement(Cog6ToothIcon, { className: "size-5", "aria-hidden": "true" }),
|
|
23
|
+
"Manage Columns")),
|
|
24
|
+
React__default.createElement(Popover.Content, { className: "p-0" },
|
|
25
|
+
React__default.createElement("div", { className: "w-64 p-3 overflow-hidden bg-white", role: "dialog", "aria-labelledby": "column-manager-title", "aria-describedby": "column-manager-description", "aria-modal": "true" },
|
|
26
|
+
React__default.createElement("div", { id: "column-manager-title", className: "text-xs uppercase font-bold mb-3 text-[var(--color-text-placeholder)]" }, "Manage Columns"),
|
|
27
|
+
React__default.createElement("div", { id: "column-manager-description", className: "sr-only" }, "Use checkboxes to control which columns are visible in the table. Locked columns cannot be hidden."),
|
|
28
|
+
React__default.createElement("div", { className: "space-y-0.5", role: "group", "aria-label": "Column visibility options" }, onColumnReorder ? (React__default.createElement(Sortable, { onReorder: onColumnReorder, showDragHandle: true, className: "space-y-0.5" }, orderedColumns.map((column) => (React__default.createElement(SortableItem, { key: column.id, id: column.id, disabled: column.locked === true, className: `bg-white hover:bg-[var(--color-background-tertiary)] rounded-lg p-1.5 transition-colors ${column.locked ? 'bg-[var(--color-background-secondary)]' : ''}` }, renderColumnItem(column)))))) : (orderedColumns.map((column) => (React__default.createElement("div", { key: column.id, className: `bg-white hover:bg-[var(--color-background-tertiary)] rounded-lg p-1.5 transition-colors ${column.locked ? 'bg-[var(--color-background-secondary)]' : ''}` }, renderColumnItem(column)))))),
|
|
29
|
+
React__default.createElement("div", { className: "mt-3 flex justify-end" },
|
|
30
|
+
React__default.createElement(Button, { color: "neutral", variant: "filled", className: "w-full", onClick: onResetToDefault }, "Reset to Default"))))));
|
|
31
|
+
}
|
|
32
|
+
const TableColumnManager = TableColumnManagerComponent;
|
|
33
|
+
|
|
34
|
+
export { TableColumnManager };
|
package/dist/components/core/Table/{components/DeclarativeComponents.d.ts → TableDeclarative.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { TableHeaderProps, TableBodyProps, TableRowProps, TableCellProps, TableHeaderCellProps } from '
|
|
2
|
+
import { TableHeaderProps, TableBodyProps, TableRowProps, TableCellProps, TableHeaderCellProps } from './Table.types';
|
|
3
3
|
export declare const Header: React.NamedExoticComponent<TableHeaderProps>;
|
|
4
4
|
export declare const Body: React.NamedExoticComponent<TableBodyProps>;
|
|
5
5
|
export declare const Row: React.NamedExoticComponent<TableRowProps>;
|
package/dist/components/core/Table/{components/DeclarativeComponents.js → TableDeclarative.js}
RENAMED
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import React__default, { useContext } from 'react';
|
|
2
|
-
import { TableContext } from '
|
|
3
|
-
import { cn } from '
|
|
2
|
+
import { TableContext } from './Table.js';
|
|
3
|
+
import { cn } from '../../../utils/cn.js';
|
|
4
|
+
import { alignmentClasses } from './Table.utils.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Declarative Table Header component
|
|
7
|
-
* Used within the declarative API for flexible table composition
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* <Table>
|
|
11
|
-
* <Table.Header freezeHeader>
|
|
12
|
-
* <Table.Row>
|
|
13
|
-
* <Table.HeaderCell>Name</Table.HeaderCell>
|
|
14
|
-
* </Table.Row>
|
|
15
|
-
* </Table.Header>
|
|
16
|
-
* </Table>
|
|
17
8
|
*/
|
|
18
9
|
const HeaderComponent = ({ children, freezeHeader, className = '' }) => {
|
|
19
10
|
const contextValue = useContext(TableContext);
|
|
@@ -23,37 +14,19 @@ const HeaderComponent = ({ children, freezeHeader, className = '' }) => {
|
|
|
23
14
|
: (contextValue.freezeHeader ? theme === null || theme === void 0 ? void 0 : theme.frozenHeaderStyle : ''), className);
|
|
24
15
|
return (React__default.createElement("thead", { className: headerClasses, "data-freeze": freezeHeader ? 'true' : undefined }, children));
|
|
25
16
|
};
|
|
26
|
-
// Set display name for dev tools
|
|
27
17
|
HeaderComponent.displayName = 'Table.Header';
|
|
28
|
-
// Memoize component to prevent unnecessary re-renders
|
|
29
18
|
const Header = React__default.memo(HeaderComponent);
|
|
30
19
|
/**
|
|
31
20
|
* Declarative Table Body component
|
|
32
|
-
* Container for table rows in the declarative API
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* <Table.Body>
|
|
36
|
-
* <Table.Row>
|
|
37
|
-
* <Table.Cell>Data</Table.Cell>
|
|
38
|
-
* </Table.Row>
|
|
39
|
-
* </Table.Body>
|
|
40
21
|
*/
|
|
41
22
|
const BodyComponent = ({ children, className = '', }) => {
|
|
42
23
|
const { theme } = useContext(TableContext);
|
|
43
24
|
return (React__default.createElement("tbody", { className: cn(theme === null || theme === void 0 ? void 0 : theme.bodyStyle, className) }, children));
|
|
44
25
|
};
|
|
45
|
-
// Set display name for dev tools
|
|
46
26
|
BodyComponent.displayName = 'Table.Body';
|
|
47
|
-
// Memoize component to prevent unnecessary re-renders
|
|
48
27
|
const Body = React__default.memo(BodyComponent);
|
|
49
28
|
/**
|
|
50
29
|
* Declarative Table Row component
|
|
51
|
-
* Supports selection, expansion, and custom styling
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* <Table.Row isSelected onSelectToggle={() => setSelected(!selected)}>
|
|
55
|
-
* <Table.Cell>Data</Table.Cell>
|
|
56
|
-
* </Table.Row>
|
|
57
30
|
*/
|
|
58
31
|
const RowComponent = ({ children, isExpandable = false, isExpanded = false, onExpandToggle, isSelected = false, onSelectToggle, className = '', }) => {
|
|
59
32
|
const { theme } = useContext(TableContext);
|
|
@@ -65,53 +38,30 @@ const RowComponent = ({ children, isExpandable = false, isExpanded = false, onEx
|
|
|
65
38
|
};
|
|
66
39
|
return (React__default.createElement("tr", { className: rowClasses, "data-selected": isSelected ? 'true' : undefined, "data-expanded": isExpandable && isExpanded ? 'true' : undefined, onClick: onSelectToggle ? handleRowClick : undefined, role: "row", "aria-selected": isSelected, "aria-expanded": isExpandable ? isExpanded : undefined }, children));
|
|
67
40
|
};
|
|
68
|
-
// Set display name for dev tools
|
|
69
41
|
RowComponent.displayName = 'Table.Row';
|
|
70
|
-
// Memoize component to prevent unnecessary re-renders
|
|
71
42
|
const Row = React__default.memo(RowComponent);
|
|
72
43
|
/**
|
|
73
44
|
* Declarative Table Cell component
|
|
74
|
-
* Standard data cell with alignment, width, and frozen column support
|
|
75
|
-
*
|
|
76
|
-
* @example
|
|
77
|
-
* <Table.Cell align="right" width="200px" isFrozen>
|
|
78
|
-
* $1,234.56
|
|
79
|
-
* </Table.Cell>
|
|
80
45
|
*/
|
|
81
46
|
const CellComponent = ({ children, isFrozen = false, isLastFrozen = false, align, width, className = '', colSpan, }) => {
|
|
82
47
|
const { theme } = useContext(TableContext);
|
|
83
|
-
const cellClasses = cn(theme === null || theme === void 0 ? void 0 : theme.cellStyle, isFrozen && (theme === null || theme === void 0 ? void 0 : theme.frozenColumnStyle), isLastFrozen && (theme === null || theme === void 0 ? void 0 : theme.lastFrozenColumnStyle), align &&
|
|
48
|
+
const cellClasses = cn(theme === null || theme === void 0 ? void 0 : theme.cellStyle, isFrozen && (theme === null || theme === void 0 ? void 0 : theme.frozenColumnStyle), isLastFrozen && (theme === null || theme === void 0 ? void 0 : theme.lastFrozenColumnStyle), align && alignmentClasses[align], className);
|
|
84
49
|
return (React__default.createElement("td", { className: cellClasses, "data-frozen": isFrozen ? 'true' : isLastFrozen ? 'last' : undefined, style: { width }, colSpan: colSpan, role: "cell" }, children));
|
|
85
50
|
};
|
|
86
|
-
// Set display name for dev tools
|
|
87
51
|
CellComponent.displayName = 'Table.Cell';
|
|
88
|
-
// Memoize component to prevent unnecessary re-renders
|
|
89
52
|
const Cell = React__default.memo(CellComponent);
|
|
90
53
|
/**
|
|
91
54
|
* Declarative Table Header Cell component
|
|
92
|
-
* Header cell with sorting functionality and alignment options
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* <Table.HeaderCell
|
|
96
|
-
* isSortable
|
|
97
|
-
* sortDirection="asc"
|
|
98
|
-
* onSort={() => handleSort('name')}
|
|
99
|
-
* align="left"
|
|
100
|
-
* >
|
|
101
|
-
* Name
|
|
102
|
-
* </Table.HeaderCell>
|
|
103
55
|
*/
|
|
104
56
|
const HeaderCellComponent = ({ children, isFrozen = false, isLastFrozen = false, isSortable = false, sortDirection, onSort, align = 'left', width, className = '', }) => {
|
|
105
57
|
const { theme } = useContext(TableContext);
|
|
106
|
-
const headerCellClasses = cn(theme === null || theme === void 0 ? void 0 : theme.headerStyle, isFrozen && (theme === null || theme === void 0 ? void 0 : theme.frozenColumnStyle), isLastFrozen && (theme === null || theme === void 0 ? void 0 : theme.lastFrozenColumnStyle), align &&
|
|
58
|
+
const headerCellClasses = cn(theme === null || theme === void 0 ? void 0 : theme.headerStyle, isFrozen && (theme === null || theme === void 0 ? void 0 : theme.frozenColumnStyle), isLastFrozen && (theme === null || theme === void 0 ? void 0 : theme.lastFrozenColumnStyle), align && alignmentClasses[align], isSortable && 'cursor-pointer', className);
|
|
107
59
|
return (React__default.createElement("th", { className: headerCellClasses, "data-frozen": isFrozen ? 'true' : isLastFrozen ? 'last' : undefined, onClick: isSortable && onSort ? onSort : undefined, style: { width }, role: "columnheader", "aria-sort": sortDirection ? (sortDirection === 'asc' ? 'ascending' : 'descending') : undefined },
|
|
108
60
|
React__default.createElement("div", { className: "flex items-center" },
|
|
109
61
|
children,
|
|
110
|
-
isSortable && sortDirection && (React__default.createElement("span", { className: "ml-1" }, sortDirection === 'asc' ? '
|
|
62
|
+
isSortable && sortDirection && (React__default.createElement("span", { className: "ml-1" }, sortDirection === 'asc' ? '\u2191' : '\u2193')))));
|
|
111
63
|
};
|
|
112
|
-
// Set display name for dev tools
|
|
113
64
|
HeaderCellComponent.displayName = 'Table.HeaderCell';
|
|
114
|
-
// Memoize component to prevent unnecessary re-renders
|
|
115
65
|
const HeaderCell = React__default.memo(HeaderCellComponent);
|
|
116
66
|
|
|
117
67
|
export { Body, Cell, Header, HeaderCell, Row };
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import React__default, { useState } from 'react';
|
|
2
|
+
import { Button } from '../Button/Button.js';
|
|
3
|
+
import { Input } from '../../forms/Input/Input.js';
|
|
4
|
+
import '../../forms/Input/Input.theme.js';
|
|
5
|
+
import { Select } from '../../forms/Select/Select.js';
|
|
6
|
+
import '../../forms/Select/Select.theme.js';
|
|
7
|
+
import { FunnelIcon, XMarkIcon, PlusIcon } from '@heroicons/react/24/outline';
|
|
8
|
+
import { cn } from '../../../utils/cn.js';
|
|
9
|
+
|
|
10
|
+
const operatorOptions = [
|
|
11
|
+
{ id: 'contains', label: 'Contains', value: 'contains' },
|
|
12
|
+
{ id: 'equals', label: 'Equals', value: 'equals' },
|
|
13
|
+
{ id: 'startsWith', label: 'Starts with', value: 'startsWith' },
|
|
14
|
+
{ id: 'endsWith', label: 'Ends with', value: 'endsWith' },
|
|
15
|
+
{ id: 'greaterThan', label: 'Greater than', value: 'greaterThan' },
|
|
16
|
+
{ id: 'lessThan', label: 'Less than', value: 'lessThan' },
|
|
17
|
+
];
|
|
18
|
+
function TableFilter({ columns, filterConfig, onFilterChange, className, }) {
|
|
19
|
+
const filterableColumns = columns.filter(col => col.filterable);
|
|
20
|
+
const [activeFilters, setActiveFilters] = useState(() => filterConfig.map((fc, i) => ({
|
|
21
|
+
id: `filter-${i}`,
|
|
22
|
+
columnId: fc.columnId,
|
|
23
|
+
operator: fc.operator || 'contains',
|
|
24
|
+
value: String(fc.value || ''),
|
|
25
|
+
})));
|
|
26
|
+
if (filterableColumns.length === 0)
|
|
27
|
+
return null;
|
|
28
|
+
const columnOptions = filterableColumns.map(col => ({
|
|
29
|
+
id: col.id,
|
|
30
|
+
label: typeof col.header === 'string' ? col.header : col.id,
|
|
31
|
+
value: col.id,
|
|
32
|
+
}));
|
|
33
|
+
const getFilterOperatorOptions = (column) => {
|
|
34
|
+
if (!column)
|
|
35
|
+
return operatorOptions;
|
|
36
|
+
if (column.filterType === 'number') {
|
|
37
|
+
return operatorOptions;
|
|
38
|
+
}
|
|
39
|
+
// Text filters: no greaterThan/lessThan
|
|
40
|
+
return operatorOptions.filter(op => op.value !== 'greaterThan' && op.value !== 'lessThan');
|
|
41
|
+
};
|
|
42
|
+
const syncFilters = (filters) => {
|
|
43
|
+
const newFilterConfig = filters
|
|
44
|
+
.filter(f => f.columnId && f.value)
|
|
45
|
+
.map(f => ({
|
|
46
|
+
columnId: f.columnId,
|
|
47
|
+
value: f.value,
|
|
48
|
+
operator: f.operator,
|
|
49
|
+
}));
|
|
50
|
+
onFilterChange(newFilterConfig);
|
|
51
|
+
};
|
|
52
|
+
const handleAddFilter = () => {
|
|
53
|
+
const defaultColumn = filterableColumns[0];
|
|
54
|
+
if (!defaultColumn)
|
|
55
|
+
return;
|
|
56
|
+
setActiveFilters(prev => [
|
|
57
|
+
...prev,
|
|
58
|
+
{
|
|
59
|
+
id: `filter-${Date.now()}`,
|
|
60
|
+
columnId: defaultColumn.id,
|
|
61
|
+
operator: 'contains',
|
|
62
|
+
value: '',
|
|
63
|
+
},
|
|
64
|
+
]);
|
|
65
|
+
};
|
|
66
|
+
const handleRemoveFilter = (filterId) => {
|
|
67
|
+
setActiveFilters(prev => {
|
|
68
|
+
const updated = prev.filter(f => f.id !== filterId);
|
|
69
|
+
syncFilters(updated);
|
|
70
|
+
return updated;
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
const handleFilterColumnChange = (filterId, columnId) => {
|
|
74
|
+
setActiveFilters(prev => {
|
|
75
|
+
const updated = prev.map(f => f.id === filterId ? { ...f, columnId, value: '' } : f);
|
|
76
|
+
syncFilters(updated);
|
|
77
|
+
return updated;
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
const handleFilterOperatorChange = (filterId, operator) => {
|
|
81
|
+
setActiveFilters(prev => {
|
|
82
|
+
const updated = prev.map(f => f.id === filterId ? { ...f, operator } : f);
|
|
83
|
+
syncFilters(updated);
|
|
84
|
+
return updated;
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
const handleFilterValueChange = (filterId, value) => {
|
|
88
|
+
setActiveFilters(prev => {
|
|
89
|
+
const updated = prev.map(f => f.id === filterId ? { ...f, value } : f);
|
|
90
|
+
syncFilters(updated);
|
|
91
|
+
return updated;
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
const handleClearAll = () => {
|
|
95
|
+
setActiveFilters([]);
|
|
96
|
+
onFilterChange([]);
|
|
97
|
+
};
|
|
98
|
+
const getSelectedColumn = (columnId) => filterableColumns.find(col => col.id === columnId);
|
|
99
|
+
return (React__default.createElement("div", { className: cn('space-y-2', className) },
|
|
100
|
+
activeFilters.map((filter) => {
|
|
101
|
+
const selectedColumn = getSelectedColumn(filter.columnId);
|
|
102
|
+
const filteredOperatorOptions = getFilterOperatorOptions(selectedColumn);
|
|
103
|
+
return (React__default.createElement("div", { key: filter.id, className: "flex items-center gap-2" },
|
|
104
|
+
React__default.createElement(FunnelIcon, { className: "size-4 flex-shrink-0 text-[var(--color-text-muted)]" }),
|
|
105
|
+
React__default.createElement(Select, { value: filter.columnId, onChange: (value) => handleFilterColumnChange(filter.id, value), options: columnOptions, size: "sm", className: "w-36" }),
|
|
106
|
+
React__default.createElement(Select, { value: filter.operator, onChange: (value) => handleFilterOperatorChange(filter.id, value), options: filteredOperatorOptions, size: "sm", className: "w-32" }),
|
|
107
|
+
(selectedColumn === null || selectedColumn === void 0 ? void 0 : selectedColumn.filterType) === 'select' && selectedColumn.filterOptions ? (React__default.createElement(Select, { value: filter.value, onChange: (value) => handleFilterValueChange(filter.id, value), options: selectedColumn.filterOptions.map(opt => ({
|
|
108
|
+
id: opt.value,
|
|
109
|
+
label: opt.label,
|
|
110
|
+
value: opt.value,
|
|
111
|
+
})), size: "sm", className: "w-40" })) : (React__default.createElement(Input, { value: filter.value, onChange: (e) => handleFilterValueChange(filter.id, e.target.value), placeholder: "Filter value...", size: "sm", type: (selectedColumn === null || selectedColumn === void 0 ? void 0 : selectedColumn.filterType) === 'number' ? 'number' : 'text', className: "w-40" })),
|
|
112
|
+
React__default.createElement(Button, { color: "neutral", variant: "ghost", size: "sm", iconOnly: true, onClick: () => handleRemoveFilter(filter.id), "aria-label": "Remove filter" },
|
|
113
|
+
React__default.createElement(XMarkIcon, { className: "size-4" }))));
|
|
114
|
+
}),
|
|
115
|
+
React__default.createElement("div", { className: "flex items-center gap-2" },
|
|
116
|
+
React__default.createElement(Button, { color: "neutral", variant: "ghost", size: "sm", onClick: handleAddFilter },
|
|
117
|
+
React__default.createElement(PlusIcon, { className: "size-4" }),
|
|
118
|
+
"Add Filter"),
|
|
119
|
+
activeFilters.length > 0 && (React__default.createElement(Button, { color: "neutral", variant: "ghost", size: "sm", onClick: handleClearAll }, "Clear All")))));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export { TableFilter };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { InternalTableHeaderProps } from '
|
|
2
|
+
import { InternalTableHeaderProps } from './Table.types';
|
|
3
3
|
export declare const TableHeader: <T extends Record<string, any>>(props: InternalTableHeaderProps<T>) => React.ReactElement;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import React__default from 'react';
|
|
1
|
+
import React__default, { useCallback } from 'react';
|
|
2
2
|
import { TableCell } from './TableCell.js';
|
|
3
|
-
import { Checkbox } from '
|
|
4
|
-
import { getRowId } from '
|
|
3
|
+
import { Checkbox } from '../../forms/Checkbox/Checkbox.js';
|
|
4
|
+
import { getRowId, UTILITY_COLUMN_WIDTH, UTILITY_COLUMN_ID } from './Table.utils.js';
|
|
5
5
|
|
|
6
|
-
function TableHeaderComponent({ columns, sortConfig = [], onSortChange,
|
|
7
|
-
const handleSort = (columnId) => {
|
|
6
|
+
function TableHeaderComponent({ columns, sortConfig = [], onSortChange, freezeHeader, freezeFirstColumn, freezeLastColumn, expandable, expandedRowRender, selectable, selectionType, selectedRows = [], onSelectionChange, theme, data = [], rowKey, }) {
|
|
7
|
+
const handleSort = useCallback((columnId) => {
|
|
8
8
|
if (!onSortChange)
|
|
9
9
|
return;
|
|
10
10
|
const currentSort = sortConfig.find(sort => sort.columnId === columnId);
|
|
11
11
|
const newSortConfig = [...sortConfig.filter(sort => sort.columnId !== columnId)];
|
|
12
12
|
if (!currentSort) {
|
|
13
|
-
// Add new sort
|
|
14
13
|
newSortConfig.push({
|
|
15
14
|
columnId,
|
|
16
15
|
direction: 'asc',
|
|
@@ -18,58 +17,45 @@ function TableHeaderComponent({ columns, sortConfig = [], onSortChange, filterCo
|
|
|
18
17
|
});
|
|
19
18
|
}
|
|
20
19
|
else if (currentSort.direction === 'asc') {
|
|
21
|
-
// Change to desc
|
|
22
20
|
newSortConfig.push({
|
|
23
21
|
columnId,
|
|
24
22
|
direction: 'desc',
|
|
25
23
|
priority: currentSort.priority,
|
|
26
24
|
});
|
|
27
25
|
}
|
|
28
|
-
// If desc, remove sort
|
|
29
26
|
onSortChange(newSortConfig);
|
|
30
|
-
};
|
|
31
|
-
const handleSelectAll = (checked) => {
|
|
27
|
+
}, [sortConfig, onSortChange]);
|
|
28
|
+
const handleSelectAll = useCallback((checked) => {
|
|
32
29
|
if (!onSelectionChange || selectionType !== 'checkbox')
|
|
33
30
|
return;
|
|
34
31
|
if (checked) {
|
|
35
|
-
// Select all rows - generate row IDs using the same logic as TableBody
|
|
36
32
|
const allRowIds = data.map((row, index) => getRowId(row, index, rowKey));
|
|
37
33
|
onSelectionChange(allRowIds);
|
|
38
34
|
}
|
|
39
35
|
else {
|
|
40
|
-
// Deselect all
|
|
41
36
|
onSelectionChange([]);
|
|
42
37
|
}
|
|
43
|
-
};
|
|
44
|
-
// Calculate select all checkbox state
|
|
38
|
+
}, [data, rowKey, selectionType, onSelectionChange]);
|
|
45
39
|
const dataLength = data.length;
|
|
46
40
|
const isAllSelected = selectedRows.length === dataLength && dataLength > 0;
|
|
47
41
|
const isIndeterminate = selectedRows.length > 0 && selectedRows.length < dataLength;
|
|
48
42
|
return (React__default.createElement("thead", { className: freezeHeader ? theme === null || theme === void 0 ? void 0 : theme.frozenHeaderStyle : '' },
|
|
49
43
|
React__default.createElement("tr", null,
|
|
50
|
-
selectable && (React__default.createElement(TableCell, { column: {
|
|
51
|
-
id:
|
|
44
|
+
(selectable || (expandable && expandedRowRender)) && (React__default.createElement(TableCell, { column: {
|
|
45
|
+
id: UTILITY_COLUMN_ID,
|
|
52
46
|
header: '',
|
|
53
47
|
accessor: () => '',
|
|
54
|
-
width:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
expandable && expandedRowRender && (React__default.createElement(TableCell, { column: {
|
|
58
|
-
id: 'expand',
|
|
59
|
-
header: '',
|
|
60
|
-
accessor: () => '',
|
|
61
|
-
width: '48px',
|
|
62
|
-
align: 'center'
|
|
63
|
-
}, row: {}, rowId: "", isHeader: true, theme: theme })),
|
|
48
|
+
width: UTILITY_COLUMN_WIDTH,
|
|
49
|
+
}, row: {}, rowId: "", isHeader: true, theme: theme },
|
|
50
|
+
React__default.createElement("div", { className: "flex items-center gap-2" }, selectable && selectionType === 'checkbox' && (React__default.createElement(Checkbox, { id: "table-select-all", name: "table-select-all", value: "select-all", checked: isAllSelected, indeterminate: isIndeterminate, onChange: handleSelectAll, "aria-label": "Select all rows" }))))),
|
|
64
51
|
columns.map((column, index) => {
|
|
65
52
|
const currentSort = sortConfig.find(sort => sort.columnId === column.id);
|
|
66
53
|
const isSortable = column.sortable && onSortChange;
|
|
67
|
-
return (React__default.createElement(TableCell, { key: column.id, column: column, row: {}, rowId: "header", isHeader: true, isFrozen: freezeFirstColumn && index === 0, isLastFrozen: freezeLastColumn && index === columns.length - 1, theme: theme }, isSortable ? (React__default.createElement("button", { onClick: () => handleSort(column.id), className: "flex items-center gap-1 w-full text-left hover:text-primary
|
|
54
|
+
return (React__default.createElement(TableCell, { key: column.id, column: column, row: {}, rowId: "header", isHeader: true, isFrozen: freezeFirstColumn && index === 0, isLastFrozen: freezeLastColumn && index === columns.length - 1, theme: theme }, isSortable ? (React__default.createElement("button", { onClick: () => handleSort(column.id), className: "flex items-center gap-1 w-full text-left hover:text-[var(--color-primary)] transition-colors", "aria-label": `Sort by ${typeof column.header === 'string' ? column.header : column.id}` },
|
|
68
55
|
column.header,
|
|
69
|
-
currentSort && (React__default.createElement("span", { className: "text-xs" }, currentSort.direction === 'asc' ? '
|
|
56
|
+
currentSort && (React__default.createElement("span", { className: "text-xs" }, currentSort.direction === 'asc' ? '\u2191' : '\u2193')))) : (column.header)));
|
|
70
57
|
}))));
|
|
71
58
|
}
|
|
72
|
-
// Export with proper type annotation
|
|
73
59
|
const TableHeader = TableHeaderComponent;
|
|
74
60
|
|
|
75
61
|
export { TableHeader };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TablePaginationProps } from "./Table.types";
|
|
3
|
+
/**
|
|
4
|
+
* TablePagination provides a standardized pagination interface for tables
|
|
5
|
+
* Combines the core Pagination component with page size selection controls
|
|
6
|
+
*/
|
|
7
|
+
export declare const TablePagination: React.FC<TablePaginationProps>;
|
|
@@ -1,34 +1,23 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
|
-
import { Pagination } from '
|
|
3
|
-
import { Select } from '
|
|
4
|
-
import '
|
|
5
|
-
import { cn } from '
|
|
2
|
+
import { Pagination } from '../Pagination/Pagination.js';
|
|
3
|
+
import { Select } from '../../forms/Select/Select.js';
|
|
4
|
+
import '../../forms/Select/Select.theme.js';
|
|
5
|
+
import { cn } from '../../../utils/cn.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* TablePagination provides a standardized pagination interface for tables
|
|
9
9
|
* Combines the core Pagination component with page size selection controls
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* <Table.Pagination
|
|
13
|
-
* currentPage={currentPage}
|
|
14
|
-
* totalItems={data.length}
|
|
15
|
-
* pageSize={pageSize}
|
|
16
|
-
* onPageChange={setCurrentPage}
|
|
17
|
-
* onPageSizeChange={setPageSize}
|
|
18
|
-
* pageSizeOptions={[10, 25, 50, 100]}
|
|
19
|
-
* />
|
|
20
10
|
*/
|
|
21
11
|
const TablePagination = ({ currentPage, totalItems, pageSize, pageSizeOptions = [10, 25, 50, 100], onPageChange, onPageSizeChange, showPageSizeSelector = true, className, }) => {
|
|
22
12
|
const totalPages = Math.ceil(totalItems / pageSize);
|
|
23
13
|
const startItem = (currentPage - 1) * pageSize + 1;
|
|
24
14
|
const endItem = Math.min(currentPage * pageSize, totalItems);
|
|
25
|
-
// Create options for the Select component
|
|
26
15
|
const pageSizeSelectOptions = pageSizeOptions.map((option) => ({
|
|
27
16
|
id: option,
|
|
28
17
|
label: option.toString(),
|
|
29
18
|
value: option,
|
|
30
19
|
}));
|
|
31
|
-
return (React__default.createElement("div", { className: cn("flex items-center justify-between px-4 py-3 border-t border-border bg-white", className) },
|
|
20
|
+
return (React__default.createElement("div", { className: cn("flex items-center justify-between px-4 py-3 border-t border-[var(--color-border)] bg-white", className) },
|
|
32
21
|
React__default.createElement("div", { className: "flex items-center gap-4" },
|
|
33
22
|
showPageSizeSelector && (React__default.createElement("div", { className: "flex items-center gap-2" },
|
|
34
23
|
React__default.createElement("span", { className: "text-sm text-[var(--color-text-muted)]" }, "Rows per page:"),
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { InternalTableRowProps } from "./Table.types";
|
|
3
|
+
declare function TableRowComponent<T extends Record<string, any>>({ row, rowId, columns, expandedRowRender, isExpanded, onExpandChange, selectable, selectionType, isSelected, onSelectionChange, freezeFirstColumn, freezeLastColumn, theme, }: InternalTableRowProps<T>): React.JSX.Element;
|
|
4
|
+
declare namespace TableRowComponent {
|
|
5
|
+
var displayName: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const TableRow: typeof TableRowComponent;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { AnimatePresence, motion } from 'motion/react';
|
|
3
|
+
import { TableCell } from './TableCell.js';
|
|
4
|
+
import { Button } from '../Button/Button.js';
|
|
5
|
+
import { Checkbox } from '../../forms/Checkbox/Checkbox.js';
|
|
6
|
+
import { Radio } from '../../forms/Radio/Radio.js';
|
|
7
|
+
import { MinusIcon, PlusIcon } from '@heroicons/react/24/outline';
|
|
8
|
+
import { UTILITY_COLUMN_WIDTH, UTILITY_COLUMN_ID } from './Table.utils.js';
|
|
9
|
+
import { tableExpandAnimations, tableExpandContentAnimations } from './Table.animations.js';
|
|
10
|
+
|
|
11
|
+
function TableRowComponent({ row, rowId, columns, expandedRowRender, isExpanded = false, onExpandChange, selectable, selectionType, isSelected = false, onSelectionChange, freezeFirstColumn, freezeLastColumn, theme, }) {
|
|
12
|
+
const rowClasses = [
|
|
13
|
+
(theme === null || theme === void 0 ? void 0 : theme.rowStyle) || "",
|
|
14
|
+
isSelected ? (theme === null || theme === void 0 ? void 0 : theme.selectedRowStyle) || "" : "",
|
|
15
|
+
]
|
|
16
|
+
.filter(Boolean)
|
|
17
|
+
.join(" ");
|
|
18
|
+
const handleExpandClick = (e) => {
|
|
19
|
+
e.stopPropagation();
|
|
20
|
+
onExpandChange === null || onExpandChange === void 0 ? void 0 : onExpandChange(!isExpanded);
|
|
21
|
+
};
|
|
22
|
+
const colSpan = columns.length + (selectable || !!expandedRowRender ? 1 : 0);
|
|
23
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
24
|
+
React__default.createElement("tr", { className: rowClasses, "data-selected": isSelected, role: "row", "aria-selected": selectable ? isSelected : undefined, "aria-expanded": Boolean(expandedRowRender) ? isExpanded : undefined },
|
|
25
|
+
(selectable || expandedRowRender) && (React__default.createElement(TableCell, { column: {
|
|
26
|
+
id: UTILITY_COLUMN_ID,
|
|
27
|
+
header: "",
|
|
28
|
+
accessor: () => "",
|
|
29
|
+
width: UTILITY_COLUMN_WIDTH,
|
|
30
|
+
}, row: row, rowId: rowId, theme: theme },
|
|
31
|
+
React__default.createElement("div", { className: "flex items-center gap-2" },
|
|
32
|
+
selectable &&
|
|
33
|
+
(selectionType === "checkbox" ? (React__default.createElement(Checkbox, { id: `table-checkbox-${rowId}`, name: `table-selection-${rowId}`, value: String(rowId), checked: isSelected, onChange: (checked) => onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(checked), onClick: (e) => e.stopPropagation(), "aria-label": "Select row" })) : (React__default.createElement("div", { onClick: (e) => e.stopPropagation() },
|
|
34
|
+
React__default.createElement(Radio, { id: `table-radio-${rowId}`, name: "table-selection", value: String(rowId), checked: isSelected, onChange: (checked) => onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(checked), "aria-label": "Select row" })))),
|
|
35
|
+
expandedRowRender && (React__default.createElement(Button, { color: "neutral", variant: "outline", size: "sm", iconOnly: true, onClick: handleExpandClick, "aria-label": isExpanded ? "Collapse row" : "Expand row" }, isExpanded ? (React__default.createElement(MinusIcon, { className: "size-4", strokeWidth: 2 })) : (React__default.createElement(PlusIcon, { className: "size-4", strokeWidth: 2 }))))))),
|
|
36
|
+
columns.map((column, index) => (React__default.createElement(TableCell, { key: column.id, column: column, row: row, rowId: rowId, isFrozen: freezeFirstColumn && index === 0, isLastFrozen: freezeLastColumn && index === columns.length - 1, theme: theme })))),
|
|
37
|
+
React__default.createElement(AnimatePresence, { initial: false }, isExpanded && expandedRowRender && (React__default.createElement(motion.tr, { key: `${rowId}-expanded`, initial: "collapsed", animate: "expanded", exit: "collapsed" },
|
|
38
|
+
React__default.createElement("td", { colSpan: colSpan, className: "p-0 border-b border-[var(--color-border)] dark:border-[var(--color-neutral-700)]" },
|
|
39
|
+
React__default.createElement(motion.div, { variants: tableExpandAnimations, style: { overflow: "hidden" } },
|
|
40
|
+
React__default.createElement(motion.div, { variants: tableExpandContentAnimations }, expandedRowRender(row)))))))));
|
|
41
|
+
}
|
|
42
|
+
TableRowComponent.displayName = "TableRow";
|
|
43
|
+
const TableRow = React__default.memo(TableRowComponent);
|
|
44
|
+
|
|
45
|
+
export { TableRow };
|