@mostrom/app-shell 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/ralph-loop.local.md +9 -0
- package/README.md +172 -0
- package/bin/init.js +269 -0
- package/bun.lock +401 -0
- package/components.json +28 -0
- package/package.json +74 -0
- package/scripts/publish-npm.sh +202 -0
- package/src/AppShell.tsx +847 -0
- package/src/components/PageHeader.tsx +160 -0
- package/src/components/data-table/README.md +447 -0
- package/src/components/data-table/data-table-preferences.tsx +184 -0
- package/src/components/data-table/data-table-toolbar.tsx +118 -0
- package/src/components/data-table/data-table.tsx +37 -0
- package/src/components/data-table/index.ts +32 -0
- package/src/components/global-header/AllServicesButton.tsx +127 -0
- package/src/components/global-header/CategoriesButton.tsx +120 -0
- package/src/components/global-header/GlobalHeader.tsx +59 -0
- package/src/components/global-header/GlobalHeaderSearch.tsx +57 -0
- package/src/components/global-header/HeaderUtilities.tsx +243 -0
- package/src/components/global-header/ServicesMenu.tsx +246 -0
- package/src/components/layout/AppBreadcrumb.tsx +70 -0
- package/src/components/layout/AppFlashbar.tsx +95 -0
- package/src/components/layout/AppLayout.tsx +271 -0
- package/src/components/layout/AppNavigation.tsx +313 -0
- package/src/components/layout/AppSidebar.tsx +229 -0
- package/src/components/patterns/index.ts +14 -0
- package/src/components/patterns/p-alert-5.tsx +19 -0
- package/src/components/patterns/p-autocomplete-5.tsx +89 -0
- package/src/components/patterns/p-breadcrumb-1.tsx +28 -0
- package/src/components/patterns/p-button-42.tsx +37 -0
- package/src/components/patterns/p-button-51.tsx +14 -0
- package/src/components/patterns/p-button-6.tsx +5 -0
- package/src/components/patterns/p-calendar-1.tsx +18 -0
- package/src/components/patterns/p-card-1.tsx +33 -0
- package/src/components/patterns/p-card-2.tsx +26 -0
- package/src/components/patterns/p-card-5.tsx +31 -0
- package/src/components/patterns/p-collapsible-7.tsx +121 -0
- package/src/components/patterns/p-command-6.tsx +113 -0
- package/src/components/patterns/p-dialog-1.tsx +56 -0
- package/src/components/patterns/p-dropdown-menu-1.tsx +38 -0
- package/src/components/patterns/p-dropdown-menu-11.tsx +122 -0
- package/src/components/patterns/p-dropdown-menu-14.tsx +165 -0
- package/src/components/patterns/p-dropdown-menu-9.tsx +108 -0
- package/src/components/patterns/p-empty-2.tsx +34 -0
- package/src/components/patterns/p-file-upload-1.tsx +72 -0
- package/src/components/patterns/p-filters-1.tsx +666 -0
- package/src/components/patterns/p-frame-2.tsx +26 -0
- package/src/components/patterns/p-tabs-2.tsx +129 -0
- package/src/components/reui/alert.tsx +92 -0
- package/src/components/reui/autocomplete.tsx +343 -0
- package/src/components/reui/badge.tsx +87 -0
- package/src/components/reui/data-grid/data-grid-column-filter.tsx +165 -0
- package/src/components/reui/data-grid/data-grid-column-header.tsx +339 -0
- package/src/components/reui/data-grid/data-grid-column-visibility.tsx +55 -0
- package/src/components/reui/data-grid/data-grid-pagination.tsx +224 -0
- package/src/components/reui/data-grid/data-grid-table-dnd-rows.tsx +260 -0
- package/src/components/reui/data-grid/data-grid-table-dnd.tsx +253 -0
- package/src/components/reui/data-grid/data-grid-table.tsx +639 -0
- package/src/components/reui/data-grid/data-grid.tsx +209 -0
- package/src/components/reui/date-selector.tsx +1330 -0
- package/src/components/reui/filters.tsx +1869 -0
- package/src/components/reui/frame.tsx +134 -0
- package/src/components/reui/index.ts +17 -0
- package/src/components/reui/timeline.tsx +219 -0
- package/src/components/search/Autocomplete.tsx +183 -0
- package/src/components/search/AutocompleteClient.tsx +293 -0
- package/src/components/search/GlobalSearch.tsx +187 -0
- package/src/components/section-drawer/deal-drawer-content.tsx +891 -0
- package/src/components/section-drawer/index.ts +19 -0
- package/src/components/section-drawer/section-drawer.css +665 -0
- package/src/components/section-drawer/section-drawer.tsx +467 -0
- package/src/components/sectioned-list-board/README.md +78 -0
- package/src/components/sectioned-list-board/board-card-content.tsx +340 -0
- package/src/components/sectioned-list-board/date-range-filter.tsx +249 -0
- package/src/components/sectioned-list-board/index.ts +19 -0
- package/src/components/sectioned-list-board/sectioned-list-board.css +564 -0
- package/src/components/sectioned-list-board/sectioned-list-board.tsx +731 -0
- package/src/components/sectioned-list-board/sortable-card.tsx +314 -0
- package/src/components/sectioned-list-board/sortable-section.tsx +319 -0
- package/src/components/sectioned-list-board/types.ts +216 -0
- package/src/components/sectioned-list-table/README.md +80 -0
- package/src/components/sectioned-list-table/index.ts +14 -0
- package/src/components/sectioned-list-table/sectioned-list-table.css +534 -0
- package/src/components/sectioned-list-table/sectioned-list-table.tsx +740 -0
- package/src/components/sectioned-list-table/sortable-column-header.tsx +120 -0
- package/src/components/sectioned-list-table/sortable-row.tsx +420 -0
- package/src/components/sectioned-list-table/sortable-section.tsx +251 -0
- package/src/components/sectioned-list-table/table-cell-content.tsx +129 -0
- package/src/components/sectioned-list-table/types.ts +120 -0
- package/src/components/sectioned-list-table/use-column-preferences.ts +103 -0
- package/src/components/ui/actions-dropdown.tsx +109 -0
- package/src/components/ui/assignee-selector.tsx +209 -0
- package/src/components/ui/avatar.tsx +107 -0
- package/src/components/ui/breadcrumb.tsx +109 -0
- package/src/components/ui/button-group.tsx +83 -0
- package/src/components/ui/button.tsx +64 -0
- package/src/components/ui/calendar.tsx +220 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/chart.tsx +376 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/collapsible.tsx +33 -0
- package/src/components/ui/command.tsx +182 -0
- package/src/components/ui/context-menu.tsx +250 -0
- package/src/components/ui/create-button-group.tsx +128 -0
- package/src/components/ui/dialog.tsx +156 -0
- package/src/components/ui/drawer.tsx +133 -0
- package/src/components/ui/dropdown-menu.tsx +255 -0
- package/src/components/ui/empty.tsx +104 -0
- package/src/components/ui/field.tsx +248 -0
- package/src/components/ui/form.tsx +165 -0
- package/src/components/ui/index.ts +37 -0
- package/src/components/ui/input-group.tsx +168 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/kbd.tsx +28 -0
- package/src/components/ui/label.tsx +22 -0
- package/src/components/ui/navigation-menu.tsx +168 -0
- package/src/components/ui/page-header.tsx +80 -0
- package/src/components/ui/popover.tsx +87 -0
- package/src/components/ui/scroll-area.tsx +56 -0
- package/src/components/ui/select.tsx +190 -0
- package/src/components/ui/separator.tsx +26 -0
- package/src/components/ui/sheet.tsx +141 -0
- package/src/components/ui/sidebar.tsx +726 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/sonner.tsx +38 -0
- package/src/components/ui/switch.tsx +33 -0
- package/src/components/ui/tabs.tsx +91 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/toggle-group.tsx +83 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/components/ui/tooltip.tsx +57 -0
- package/src/hooks/use-copy-to-clipboard.ts +37 -0
- package/src/hooks/use-file-upload.ts +415 -0
- package/src/hooks/use-mobile.ts +19 -0
- package/src/index.ts +95 -0
- package/src/lib/utils.ts +6 -0
- package/src/styles.css +1859 -0
- package/src/urls.ts +83 -0
- package/src/vite.d.ts +22 -0
- package/src/vite.js +241 -0
- package/tsconfig.base.json +18 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { Assignee } from "@/components/ui/assignee-selector";
|
|
3
|
+
|
|
4
|
+
// Re-export Assignee from shared location
|
|
5
|
+
export type { Assignee };
|
|
6
|
+
|
|
7
|
+
export interface BoardSection<T> {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
items: T[];
|
|
11
|
+
collapsed?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface FilterOption {
|
|
15
|
+
id: string;
|
|
16
|
+
label: string;
|
|
17
|
+
value: string;
|
|
18
|
+
field: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SortOption {
|
|
22
|
+
id: string;
|
|
23
|
+
label: string;
|
|
24
|
+
field: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SortState {
|
|
28
|
+
field: string | null;
|
|
29
|
+
direction: "asc" | "desc" | null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface FilterState {
|
|
33
|
+
field: string | null;
|
|
34
|
+
value: string | null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface DateRangeState {
|
|
38
|
+
from: Date | undefined;
|
|
39
|
+
to: Date | undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface DragState {
|
|
43
|
+
isDragging: boolean;
|
|
44
|
+
dragType: "section" | "card" | null;
|
|
45
|
+
activeId: string | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type BoardTaskAction =
|
|
49
|
+
| "duplicate"
|
|
50
|
+
| "markComplete"
|
|
51
|
+
| "addSubtask"
|
|
52
|
+
| "openTaskDetails"
|
|
53
|
+
| "openInNewTab"
|
|
54
|
+
| "copyTaskLink"
|
|
55
|
+
| "delete";
|
|
56
|
+
|
|
57
|
+
/** Event fired when an item is opened (click, context menu, or keyboard) */
|
|
58
|
+
export interface ItemOpenEvent<T> {
|
|
59
|
+
item: T;
|
|
60
|
+
itemId: string;
|
|
61
|
+
sectionId: string;
|
|
62
|
+
source: "click" | "context-menu" | "keyboard";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Configuration for the built-in drawer */
|
|
66
|
+
export interface DrawerProps {
|
|
67
|
+
/** Which side the drawer opens from */
|
|
68
|
+
side?: "right" | "left";
|
|
69
|
+
/** Width of the drawer */
|
|
70
|
+
width?: number | string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type BoardBadgeColor = "red" | "blue" | "green" | "grey";
|
|
74
|
+
|
|
75
|
+
export interface BoardCardBadgeField<T> {
|
|
76
|
+
field: Extract<keyof T, string>;
|
|
77
|
+
colorMap?: Record<string, BoardBadgeColor>;
|
|
78
|
+
defaultColor?: BoardBadgeColor;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface BoardCardAvatarField<T> {
|
|
82
|
+
field: Extract<keyof T, string>;
|
|
83
|
+
/** Whether the assignee can be edited via command dialog */
|
|
84
|
+
editable?: boolean;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface BoardCardDateField<T> {
|
|
88
|
+
field: Extract<keyof T, string>;
|
|
89
|
+
editable?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface BoardCardConfig<T> {
|
|
93
|
+
titleField: Extract<keyof T, string>;
|
|
94
|
+
badgeField?: BoardCardBadgeField<T>;
|
|
95
|
+
avatarField?: BoardCardAvatarField<T>;
|
|
96
|
+
dateField?: BoardCardDateField<T>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface SectionedListBoardProps<T> {
|
|
100
|
+
/** Array of sections containing items */
|
|
101
|
+
sections: BoardSection<T>[];
|
|
102
|
+
/** Function to get unique ID from item */
|
|
103
|
+
getItemId: (item: T) => string;
|
|
104
|
+
/** Data-driven card configuration */
|
|
105
|
+
cardConfig: BoardCardConfig<T>;
|
|
106
|
+
/** Optional callback for updating non-title card fields */
|
|
107
|
+
onItemFieldChange?: (
|
|
108
|
+
sectionId: string,
|
|
109
|
+
itemId: string,
|
|
110
|
+
field: Extract<keyof T, string>,
|
|
111
|
+
value: unknown
|
|
112
|
+
) => void;
|
|
113
|
+
/** Optional function to check if item is completed */
|
|
114
|
+
isItemCompleted?: (item: T) => boolean;
|
|
115
|
+
|
|
116
|
+
// Section handlers
|
|
117
|
+
onSectionReorder?: (sections: BoardSection<T>[]) => void;
|
|
118
|
+
onToggleSection?: (sectionId: string) => void;
|
|
119
|
+
onRenameSection?: (sectionId: string, name: string) => void;
|
|
120
|
+
onAddSection?: (afterSectionId?: string) => void;
|
|
121
|
+
onDeleteSection?: (sectionId: string) => void;
|
|
122
|
+
|
|
123
|
+
// Item handlers
|
|
124
|
+
onItemReorder?: (sectionId: string, items: T[]) => void;
|
|
125
|
+
onItemMoveToSection?: (
|
|
126
|
+
item: T,
|
|
127
|
+
fromSectionId: string,
|
|
128
|
+
toSectionId: string,
|
|
129
|
+
targetIndex?: number
|
|
130
|
+
) => void;
|
|
131
|
+
onAddItem?: (sectionId: string) => void;
|
|
132
|
+
onItemTitleEdit?: (sectionId: string, itemId: string, newTitle: string) => void;
|
|
133
|
+
onItemComplete?: (sectionId: string, itemId: string, completed: boolean) => void;
|
|
134
|
+
onItemAction?: (
|
|
135
|
+
sectionId: string,
|
|
136
|
+
itemId: string,
|
|
137
|
+
action: BoardTaskAction
|
|
138
|
+
) => void;
|
|
139
|
+
|
|
140
|
+
// Filter/Sort
|
|
141
|
+
filterOptions?: FilterOption[];
|
|
142
|
+
sortOptions?: SortOption[];
|
|
143
|
+
filter?: FilterState;
|
|
144
|
+
sort?: SortState;
|
|
145
|
+
onFilterChange?: (filter: FilterState) => void;
|
|
146
|
+
onSortChange?: (sort: SortState) => void;
|
|
147
|
+
|
|
148
|
+
// Date Range Filter
|
|
149
|
+
dateRange?: DateRangeState;
|
|
150
|
+
onDateRangeChange?: (dateRange: DateRangeState) => void;
|
|
151
|
+
/** Label for the date range filter button (defaults to "Date") */
|
|
152
|
+
dateRangeLabel?: string;
|
|
153
|
+
|
|
154
|
+
/** List of available assignees for the assignee selector */
|
|
155
|
+
assignees?: Assignee[];
|
|
156
|
+
|
|
157
|
+
// Item Details Drawer
|
|
158
|
+
/** Callback fired when an item is opened (click, context menu, or keyboard) */
|
|
159
|
+
onItemOpen?: (event: ItemOpenEvent<T>) => void;
|
|
160
|
+
/** Render function for item details - when provided, enables built-in drawer */
|
|
161
|
+
renderItemDetails?: (item: T) => ReactNode;
|
|
162
|
+
/** Configuration for the built-in drawer */
|
|
163
|
+
drawerProps?: DrawerProps;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface SortableBoardSectionProps<T> {
|
|
167
|
+
sortableId: string;
|
|
168
|
+
section: BoardSection<T>;
|
|
169
|
+
getItemId: (item: T) => string;
|
|
170
|
+
cardConfig: BoardCardConfig<T>;
|
|
171
|
+
onItemFieldChange?: (itemId: string, field: Extract<keyof T, string>, value: unknown) => void;
|
|
172
|
+
onToggle: () => void;
|
|
173
|
+
onRename: (name: string) => void;
|
|
174
|
+
onAddItem: () => void;
|
|
175
|
+
onDelete: () => void;
|
|
176
|
+
onItemTitleEdit?: (itemId: string, newTitle: string) => void;
|
|
177
|
+
onItemComplete?: (itemId: string, completed: boolean) => void;
|
|
178
|
+
onItemAction?: (itemId: string, action: BoardTaskAction) => void;
|
|
179
|
+
/** Callback fired when an item is opened */
|
|
180
|
+
onItemOpen?: (event: ItemOpenEvent<T>) => void;
|
|
181
|
+
isDragDisabled: boolean;
|
|
182
|
+
isItemCompleted?: (item: T) => boolean;
|
|
183
|
+
collapseDuringDrag?: boolean;
|
|
184
|
+
dropIndicatorPosition?: "before" | "after" | null;
|
|
185
|
+
cardDropIndicatorIndex?: number | null;
|
|
186
|
+
/** List of available assignees for the assignee selector */
|
|
187
|
+
assignees?: Assignee[];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface SortableBoardCardProps<T> {
|
|
191
|
+
item: T;
|
|
192
|
+
itemId: string;
|
|
193
|
+
index: number;
|
|
194
|
+
sectionId: string;
|
|
195
|
+
cardConfig: BoardCardConfig<T>;
|
|
196
|
+
isCompleted: boolean;
|
|
197
|
+
isDragDisabled: boolean;
|
|
198
|
+
onTitleEdit?: (newTitle: string) => void;
|
|
199
|
+
onComplete?: (completed: boolean) => void;
|
|
200
|
+
onTaskAction?: (action: BoardTaskAction) => void;
|
|
201
|
+
onFieldChange?: (field: Extract<keyof T, string>, value: unknown) => void;
|
|
202
|
+
/** Callback fired when the item is opened (click, context menu, or keyboard) */
|
|
203
|
+
onItemOpen?: (source: "click" | "context-menu" | "keyboard") => void;
|
|
204
|
+
/** List of available assignees for the assignee selector */
|
|
205
|
+
assignees?: Assignee[];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface BoardCardContentProps<T> {
|
|
209
|
+
item: T;
|
|
210
|
+
cardConfig: BoardCardConfig<T>;
|
|
211
|
+
titleContent?: ReactNode;
|
|
212
|
+
onFieldChange?: (field: Extract<keyof T, string>, value: unknown) => void;
|
|
213
|
+
interactive?: boolean;
|
|
214
|
+
/** List of available assignees for the assignee selector */
|
|
215
|
+
assignees?: Assignee[];
|
|
216
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Sectioned List Table
|
|
2
|
+
|
|
3
|
+
Data-driven, reusable sectioned table with draggable sections/rows and configurable columns.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
`SectionedListTable` is **bring your own data only**:
|
|
8
|
+
- Consumers provide section/row data.
|
|
9
|
+
- Consumers describe columns with field metadata.
|
|
10
|
+
- Consumers do **not** provide custom cell render functions.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import {
|
|
16
|
+
SectionedListTable,
|
|
17
|
+
type ColumnDefinition,
|
|
18
|
+
type Section,
|
|
19
|
+
type SortState,
|
|
20
|
+
} from "~/components/shared/sectioned-list-table";
|
|
21
|
+
|
|
22
|
+
type Deal = {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
assignee: string;
|
|
26
|
+
value: number;
|
|
27
|
+
status: string;
|
|
28
|
+
priority: "High" | "Medium" | "Low";
|
|
29
|
+
completed: boolean;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const columns: ColumnDefinition<Deal>[] = [
|
|
33
|
+
{ id: "name", header: "Name", field: "name", type: "text", sortable: true, width: 250 },
|
|
34
|
+
{ id: "assignee", header: "Assignee", field: "assignee", type: "avatar", editable: false, width: 100 },
|
|
35
|
+
{ id: "value", header: "Value", field: "value", type: "currency", currencyCode: "USD", editable: false, width: 120 },
|
|
36
|
+
{
|
|
37
|
+
id: "priority",
|
|
38
|
+
header: "Priority",
|
|
39
|
+
field: "priority",
|
|
40
|
+
type: "badge",
|
|
41
|
+
badgeColorMap: { High: "red", Medium: "blue", Low: "green" },
|
|
42
|
+
editable: false,
|
|
43
|
+
width: 100,
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
function ExampleTable({ sections }: { sections: Section<Deal>[] }) {
|
|
48
|
+
const [sort, setSort] = React.useState<SortState>({ columnId: null, direction: null });
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<SectionedListTable
|
|
52
|
+
columns={columns}
|
|
53
|
+
sections={sections}
|
|
54
|
+
getItemId={(item) => item.id}
|
|
55
|
+
isItemCompleted={(item) => item.completed}
|
|
56
|
+
sort={sort}
|
|
57
|
+
onSort={setSort}
|
|
58
|
+
onCellEdit={(sectionId, rowIndex, field, value) => {
|
|
59
|
+
// Persist data field update
|
|
60
|
+
}}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Column Model
|
|
67
|
+
|
|
68
|
+
- `field`: Data key used for display and editing.
|
|
69
|
+
- `type`:
|
|
70
|
+
- `text`: plain string rendering.
|
|
71
|
+
- `currency`: localized currency formatting.
|
|
72
|
+
- `badge`: Cloudscape badge with optional `badgeColorMap`.
|
|
73
|
+
- `avatar`: initials avatar from string field.
|
|
74
|
+
- `editable`: defaults to editable for `text`; set `false` to lock.
|
|
75
|
+
|
|
76
|
+
## Notes
|
|
77
|
+
|
|
78
|
+
- Row drag is disabled when sort or filter text is active.
|
|
79
|
+
- Inline editing currently applies to `text` columns.
|
|
80
|
+
- For data consistency, keep `id` aligned with `field` unless you handle mapping in callbacks.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { SectionedListTable } from "./sectioned-list-table";
|
|
2
|
+
export type {
|
|
3
|
+
Assignee,
|
|
4
|
+
ColumnDefinition,
|
|
5
|
+
TableColumnType,
|
|
6
|
+
TableBadgeColor,
|
|
7
|
+
TableTaskAction,
|
|
8
|
+
Section,
|
|
9
|
+
SortState,
|
|
10
|
+
SectionedListTableProps,
|
|
11
|
+
ColumnPreferences,
|
|
12
|
+
ItemOpenEvent,
|
|
13
|
+
DrawerProps,
|
|
14
|
+
} from "./types";
|