@alepha/ui 0.11.2 → 0.11.4
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/dist/AlephaMantineProvider-CtIV-8MV.mjs +150 -0
- package/dist/AlephaMantineProvider-CtIV-8MV.mjs.map +1 -0
- package/dist/AlephaMantineProvider-D-vu9aCD.mjs +3 -0
- package/dist/{index.d.ts → index.d.mts} +290 -226
- package/dist/index.d.mts.map +1 -0
- package/dist/{index.js → index.mjs} +651 -730
- package/dist/index.mjs.map +1 -0
- package/package.json +14 -12
- package/src/RootRouter.ts +1 -1
- package/src/components/buttons/ActionButton.tsx +542 -0
- package/src/components/buttons/BurgerButton.tsx +20 -0
- package/src/components/{DarkModeButton.tsx → buttons/DarkModeButton.tsx} +27 -14
- package/src/components/buttons/LanguageButton.tsx +28 -0
- package/src/components/buttons/OmnibarButton.tsx +32 -0
- package/src/components/buttons/ToggleSidebarButton.tsx +28 -0
- package/src/components/dialogs/AlertDialog.tsx +10 -10
- package/src/components/dialogs/ConfirmDialog.tsx +18 -18
- package/src/components/dialogs/PromptDialog.tsx +5 -3
- package/src/components/{Control.tsx → form/Control.tsx} +6 -3
- package/src/components/{ControlDate.tsx → form/ControlDate.tsx} +4 -1
- package/src/components/{ControlSelect.tsx → form/ControlSelect.tsx} +4 -1
- package/src/components/{TypeForm.tsx → form/TypeForm.tsx} +8 -6
- package/src/components/layout/AdminShell.tsx +97 -0
- package/src/components/{AlephaMantineProvider.tsx → layout/AlephaMantineProvider.tsx} +30 -10
- package/src/components/layout/AppBar.tsx +133 -0
- package/src/components/layout/Omnibar.tsx +43 -0
- package/src/components/layout/Sidebar.tsx +410 -0
- package/src/components/table/DataTable.tsx +63 -0
- package/src/constants/ui.ts +8 -0
- package/src/index.ts +89 -24
- package/src/services/DialogService.tsx +13 -32
- package/src/services/ToastService.tsx +16 -4
- package/src/utils/parseInput.ts +1 -1
- package/dist/AlephaMantineProvider-DDbIijPF.js +0 -96
- package/dist/AlephaMantineProvider-DDbIijPF.js.map +0 -1
- package/dist/AlephaMantineProvider-pOu8hOzK.js +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/src/components/Action.tsx +0 -345
- package/src/components/DataTable.css +0 -199
- package/src/components/DataTable.tsx +0 -724
- package/src/components/Omnibar.tsx +0 -77
- package/src/components/Sidebar.css +0 -217
- package/src/components/Sidebar.tsx +0 -255
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type RouterGoOptions,
|
|
3
|
-
type UseActiveOptions,
|
|
4
|
-
useActive,
|
|
5
|
-
useAlepha,
|
|
6
|
-
useRouter,
|
|
7
|
-
} from "@alepha/react";
|
|
8
|
-
import { type FormModel, useFormState } from "@alepha/react-form";
|
|
9
|
-
import {
|
|
10
|
-
Button,
|
|
11
|
-
type ButtonProps,
|
|
12
|
-
Flex,
|
|
13
|
-
Menu,
|
|
14
|
-
Tooltip,
|
|
15
|
-
type TooltipProps,
|
|
16
|
-
} from "@mantine/core";
|
|
17
|
-
import { IconChevronRight } from "@tabler/icons-react";
|
|
18
|
-
import { type ReactNode, useState } from "react";
|
|
19
|
-
|
|
20
|
-
export interface ActionMenuItem {
|
|
21
|
-
/**
|
|
22
|
-
* Menu item type
|
|
23
|
-
*/
|
|
24
|
-
type?: "item" | "divider" | "label";
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Label text for the menu item
|
|
28
|
-
*/
|
|
29
|
-
label?: string;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Icon element to display before the label
|
|
33
|
-
*/
|
|
34
|
-
icon?: ReactNode;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Click handler for menu items
|
|
38
|
-
*/
|
|
39
|
-
onClick?: () => void;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Color for the menu item (e.g., "red" for danger actions)
|
|
43
|
-
*/
|
|
44
|
-
color?: string;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Nested submenu items
|
|
48
|
-
*/
|
|
49
|
-
children?: ActionMenuItem[];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface ActionMenuConfig {
|
|
53
|
-
/**
|
|
54
|
-
* Array of menu items to display
|
|
55
|
-
*/
|
|
56
|
-
items: ActionMenuItem[];
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Menu position relative to the button
|
|
60
|
-
*/
|
|
61
|
-
position?:
|
|
62
|
-
| "bottom"
|
|
63
|
-
| "bottom-start"
|
|
64
|
-
| "bottom-end"
|
|
65
|
-
| "top"
|
|
66
|
-
| "top-start"
|
|
67
|
-
| "top-end"
|
|
68
|
-
| "left"
|
|
69
|
-
| "right";
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Menu width
|
|
73
|
-
*/
|
|
74
|
-
width?: number | string;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Menu shadow
|
|
78
|
-
*/
|
|
79
|
-
shadow?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface ActionCommonProps extends ButtonProps {
|
|
83
|
-
children?: ReactNode;
|
|
84
|
-
textVisibleFrom?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Tooltip to display on hover. Can be a string for simple tooltips
|
|
88
|
-
* or a TooltipProps object for advanced configuration.
|
|
89
|
-
*/
|
|
90
|
-
tooltip?: string | TooltipProps;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Menu configuration. When provided, the action will display a dropdown menu.
|
|
94
|
-
*/
|
|
95
|
-
menu?: ActionMenuConfig;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* If set, a confirmation dialog will be shown before performing the action.
|
|
99
|
-
* If `true`, a default title and message will be used.
|
|
100
|
-
* If a string, it will be used as the message with a default title.
|
|
101
|
-
* If an object, it can contain `title` and `message` properties to customize the dialog.
|
|
102
|
-
*/
|
|
103
|
-
confirm?: boolean | string | { title?: string; message: string };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export type ActionProps = ActionCommonProps &
|
|
107
|
-
(ActiveHrefProps | ActionClickProps | ActionSubmitProps | {});
|
|
108
|
-
|
|
109
|
-
// ---------------------------------------------------------------------------------------------------------------------
|
|
110
|
-
|
|
111
|
-
// Helper function to render menu items recursively
|
|
112
|
-
const renderMenuItem = (item: ActionMenuItem, index: number): ReactNode => {
|
|
113
|
-
// Render divider
|
|
114
|
-
if (item.type === "divider") {
|
|
115
|
-
return <Menu.Divider key={index} />;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Render label
|
|
119
|
-
if (item.type === "label") {
|
|
120
|
-
return <Menu.Label key={index}>{item.label}</Menu.Label>;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Render submenu if has children
|
|
124
|
-
if (item.children && item.children.length > 0) {
|
|
125
|
-
return (
|
|
126
|
-
<Menu key={index} trigger="hover" position="right-start" offset={2}>
|
|
127
|
-
<Menu.Target>
|
|
128
|
-
<Menu.Item
|
|
129
|
-
leftSection={item.icon}
|
|
130
|
-
rightSection={<IconChevronRight size={14} />}
|
|
131
|
-
>
|
|
132
|
-
{item.label}
|
|
133
|
-
</Menu.Item>
|
|
134
|
-
</Menu.Target>
|
|
135
|
-
<Menu.Dropdown>
|
|
136
|
-
{item.children.map((child, childIndex) =>
|
|
137
|
-
renderMenuItem(child, childIndex),
|
|
138
|
-
)}
|
|
139
|
-
</Menu.Dropdown>
|
|
140
|
-
</Menu>
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Render regular menu item
|
|
145
|
-
return (
|
|
146
|
-
<Menu.Item
|
|
147
|
-
key={index}
|
|
148
|
-
leftSection={item.icon}
|
|
149
|
-
onClick={item.onClick}
|
|
150
|
-
color={item.color}
|
|
151
|
-
>
|
|
152
|
-
{item.label}
|
|
153
|
-
</Menu.Item>
|
|
154
|
-
);
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const Action = (_props: ActionProps) => {
|
|
158
|
-
const props = { variant: "subtle", ..._props };
|
|
159
|
-
const { tooltip, menu, ...restProps } = props;
|
|
160
|
-
|
|
161
|
-
if (props.leftSection && !props.children) {
|
|
162
|
-
restProps.className ??= "mantine-Action-iconOnly";
|
|
163
|
-
restProps.p ??= "xs";
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (props.textVisibleFrom) {
|
|
167
|
-
const { children, textVisibleFrom, leftSection, ...rest } = restProps;
|
|
168
|
-
return (
|
|
169
|
-
<>
|
|
170
|
-
<Flex w={"100%"} visibleFrom={textVisibleFrom}>
|
|
171
|
-
<Action
|
|
172
|
-
flex={1}
|
|
173
|
-
{...rest}
|
|
174
|
-
leftSection={leftSection}
|
|
175
|
-
tooltip={tooltip}
|
|
176
|
-
menu={menu}
|
|
177
|
-
>
|
|
178
|
-
{children}
|
|
179
|
-
</Action>
|
|
180
|
-
</Flex>
|
|
181
|
-
<Flex w={"100%"} hiddenFrom={textVisibleFrom}>
|
|
182
|
-
<Action px={"xs"} {...rest} tooltip={tooltip} menu={menu}>
|
|
183
|
-
{leftSection}
|
|
184
|
-
</Action>
|
|
185
|
-
</Flex>
|
|
186
|
-
</>
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const renderAction = () => {
|
|
191
|
-
if ("href" in restProps && restProps.href) {
|
|
192
|
-
return (
|
|
193
|
-
<ActionHref {...restProps} href={restProps.href}>
|
|
194
|
-
{restProps.children}
|
|
195
|
-
</ActionHref>
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if ("onClick" in restProps && restProps.onClick) {
|
|
200
|
-
return (
|
|
201
|
-
<ActionClick {...restProps} onClick={restProps.onClick}>
|
|
202
|
-
{restProps.children}
|
|
203
|
-
</ActionClick>
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if ("form" in restProps && restProps.form) {
|
|
208
|
-
return (
|
|
209
|
-
<ActionSubmit {...restProps} form={restProps.form}>
|
|
210
|
-
{restProps.children}
|
|
211
|
-
</ActionSubmit>
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return <Button {...(restProps as any)}>{restProps.children}</Button>;
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
let actionElement = renderAction();
|
|
219
|
-
|
|
220
|
-
// Wrap with Menu if provided
|
|
221
|
-
if (menu) {
|
|
222
|
-
actionElement = (
|
|
223
|
-
<Menu
|
|
224
|
-
position={menu.position || "bottom-start"}
|
|
225
|
-
width={menu.width || 200}
|
|
226
|
-
shadow={menu.shadow || "md"}
|
|
227
|
-
>
|
|
228
|
-
<Menu.Target>{actionElement}</Menu.Target>
|
|
229
|
-
<Menu.Dropdown>
|
|
230
|
-
{menu.items.map((item, index) => renderMenuItem(item, index))}
|
|
231
|
-
</Menu.Dropdown>
|
|
232
|
-
</Menu>
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Wrap with Tooltip if provided
|
|
237
|
-
if (tooltip) {
|
|
238
|
-
const tooltipProps: TooltipProps =
|
|
239
|
-
typeof tooltip === "string"
|
|
240
|
-
? { label: tooltip, children: actionElement }
|
|
241
|
-
: { ...tooltip, children: actionElement };
|
|
242
|
-
|
|
243
|
-
return <Tooltip {...tooltipProps} />;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return actionElement;
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
export default Action;
|
|
250
|
-
|
|
251
|
-
// ---------------------------------------------------------------------------------------------------------------------
|
|
252
|
-
|
|
253
|
-
export interface ActionSubmitProps extends ButtonProps {
|
|
254
|
-
form: FormModel<any>;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Action button that submits a form with loading and disabled state handling.
|
|
259
|
-
*/
|
|
260
|
-
const ActionSubmit = (props: ActionSubmitProps) => {
|
|
261
|
-
const { form, ...buttonProps } = props;
|
|
262
|
-
const state = useFormState(form);
|
|
263
|
-
return (
|
|
264
|
-
<Button
|
|
265
|
-
{...buttonProps}
|
|
266
|
-
loading={state.loading}
|
|
267
|
-
disabled={state.loading}
|
|
268
|
-
type={"submit"}
|
|
269
|
-
>
|
|
270
|
-
{props.children}
|
|
271
|
-
</Button>
|
|
272
|
-
);
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
// ---------------------------------------------------------------------------------------------------------------------
|
|
276
|
-
|
|
277
|
-
export interface ActionClickProps extends ButtonProps {
|
|
278
|
-
onClick: (e: any) => any;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Basic action button that handles click events with loading and error handling.
|
|
283
|
-
*/
|
|
284
|
-
const ActionClick = (props: ActionClickProps) => {
|
|
285
|
-
const [pending, setPending] = useState(false);
|
|
286
|
-
const alepha = useAlepha();
|
|
287
|
-
|
|
288
|
-
const onClick = async (e: any) => {
|
|
289
|
-
setPending(true);
|
|
290
|
-
try {
|
|
291
|
-
await props.onClick(e);
|
|
292
|
-
} catch (e) {
|
|
293
|
-
console.error(e);
|
|
294
|
-
await alepha.events.emit("form:submit:error", {
|
|
295
|
-
id: "action",
|
|
296
|
-
error: e as Error,
|
|
297
|
-
});
|
|
298
|
-
} finally {
|
|
299
|
-
setPending(false);
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
return (
|
|
304
|
-
<Button
|
|
305
|
-
{...props}
|
|
306
|
-
disabled={pending || props.disabled}
|
|
307
|
-
loading={pending}
|
|
308
|
-
onClick={onClick}
|
|
309
|
-
>
|
|
310
|
-
{props.children}
|
|
311
|
-
</Button>
|
|
312
|
-
);
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
// ---------------------------------------------------------------------------------------------------------------------
|
|
316
|
-
|
|
317
|
-
export interface ActiveHrefProps extends ButtonProps {
|
|
318
|
-
href: string;
|
|
319
|
-
active?: Partial<UseActiveOptions> | false;
|
|
320
|
-
routerGoOptions?: RouterGoOptions;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Action for navigation with active state support.
|
|
325
|
-
*/
|
|
326
|
-
const ActionHref = (props: ActiveHrefProps) => {
|
|
327
|
-
const { active: options, routerGoOptions, ...buttonProps } = props;
|
|
328
|
-
const router = useRouter();
|
|
329
|
-
const { isPending, isActive } = useActive(
|
|
330
|
-
options ? { href: props.href, ...options } : { href: props.href },
|
|
331
|
-
);
|
|
332
|
-
const anchorProps = router.anchor(props.href, routerGoOptions);
|
|
333
|
-
|
|
334
|
-
return (
|
|
335
|
-
<Button
|
|
336
|
-
component={"a"}
|
|
337
|
-
loading={isPending}
|
|
338
|
-
{...anchorProps}
|
|
339
|
-
{...buttonProps}
|
|
340
|
-
variant={isActive && options !== false ? "filled" : "subtle"}
|
|
341
|
-
>
|
|
342
|
-
{props.children}
|
|
343
|
-
</Button>
|
|
344
|
-
);
|
|
345
|
-
};
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
2
|
-
/* DataTable Component Styles */
|
|
3
|
-
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
4
|
-
|
|
5
|
-
.alepha-datatable-container {
|
|
6
|
-
display: flex;
|
|
7
|
-
flex-direction: column;
|
|
8
|
-
height: 100%;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.alepha-datatable-toolbar {
|
|
12
|
-
border-radius: var(--mantine-radius-md);
|
|
13
|
-
background: var(--mantine-color-body);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.alepha-datatable-search-input {
|
|
17
|
-
min-width: 200px;
|
|
18
|
-
max-width: 300px;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.alepha-datatable-page-size-select {
|
|
22
|
-
width: 120px;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.alepha-datatable-table {
|
|
26
|
-
position: relative;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.alepha-datatable-th {
|
|
30
|
-
font-weight: 600;
|
|
31
|
-
white-space: nowrap;
|
|
32
|
-
user-select: none;
|
|
33
|
-
transition: background-color 0.2s ease;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.alepha-datatable-th:hover {
|
|
37
|
-
background-color: var(--mantine-color-gray-0);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
[data-mantine-color-scheme="dark"] .alepha-datatable-th:hover {
|
|
41
|
-
background-color: var(--mantine-color-dark-6);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.alepha-datatable-tr {
|
|
45
|
-
transition: background-color 0.15s ease;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.alepha-datatable-tr.alepha-datatable-selected {
|
|
49
|
-
background-color: var(--mantine-color-blue-0) !important;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
[data-mantine-color-scheme="dark"]
|
|
53
|
-
.alepha-datatable-tr.alepha-datatable-selected {
|
|
54
|
-
background-color: rgba(34, 139, 230, 0.1) !important;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.alepha-datatable-checkbox-column {
|
|
58
|
-
width: 40px;
|
|
59
|
-
text-align: center;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.alepha-datatable-actions-column {
|
|
63
|
-
width: 100px;
|
|
64
|
-
text-align: center;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.alepha-datatable-sort-icon {
|
|
68
|
-
color: var(--mantine-color-blue-6);
|
|
69
|
-
transition: transform 0.2s ease;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.alepha-datatable-sort-icon-inactive {
|
|
73
|
-
color: var(--mantine-color-gray-5);
|
|
74
|
-
opacity: 0;
|
|
75
|
-
transition: opacity 0.2s ease;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.alepha-datatable-th:hover .alepha-datatable-sort-icon-inactive {
|
|
79
|
-
opacity: 0.5;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/* Loading state */
|
|
83
|
-
.alepha-datatable-loading {
|
|
84
|
-
position: relative;
|
|
85
|
-
pointer-events: none;
|
|
86
|
-
opacity: 0.5;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.alepha-datatable-loading-overlay {
|
|
90
|
-
position: absolute;
|
|
91
|
-
top: 0;
|
|
92
|
-
left: 0;
|
|
93
|
-
right: 0;
|
|
94
|
-
bottom: 0;
|
|
95
|
-
display: flex;
|
|
96
|
-
align-items: center;
|
|
97
|
-
justify-content: center;
|
|
98
|
-
background: rgba(255, 255, 255, 0.8);
|
|
99
|
-
z-index: 10;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
[data-mantine-color-scheme="dark"] .alepha-datatable-loading-overlay {
|
|
103
|
-
background: rgba(26, 27, 30, 0.8);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/* Sticky header styles */
|
|
107
|
-
.alepha-datatable-sticky-header {
|
|
108
|
-
position: sticky;
|
|
109
|
-
top: 0;
|
|
110
|
-
z-index: 5;
|
|
111
|
-
background: var(--mantine-color-body);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/* Zebra striping adjustments */
|
|
115
|
-
.alepha-datatable-striped tbody tr:nth-of-type(odd) {
|
|
116
|
-
background-color: var(--mantine-color-gray-0);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
[data-mantine-color-scheme="dark"]
|
|
120
|
-
.alepha-datatable-striped
|
|
121
|
-
tbody
|
|
122
|
-
tr:nth-of-type(odd) {
|
|
123
|
-
background-color: var(--mantine-color-dark-7);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/* Empty state */
|
|
127
|
-
.alepha-datatable-empty-state {
|
|
128
|
-
padding: 3rem 1rem;
|
|
129
|
-
text-align: center;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.alepha-datatable-empty-icon {
|
|
133
|
-
color: var(--mantine-color-gray-5);
|
|
134
|
-
margin-bottom: 1rem;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/* Footer */
|
|
138
|
-
.alepha-datatable-footer {
|
|
139
|
-
border-top: 1px solid var(--mantine-color-gray-2);
|
|
140
|
-
padding-top: var(--mantine-spacing-sm);
|
|
141
|
-
margin-top: var(--mantine-spacing-xs);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
[data-mantine-color-scheme="dark"] .alepha-datatable-footer {
|
|
145
|
-
border-top-color: var(--mantine-color-dark-5);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/* Custom scrollbar for better UX */
|
|
149
|
-
.alepha-datatable-container ::-webkit-scrollbar {
|
|
150
|
-
width: 8px;
|
|
151
|
-
height: 8px;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
.alepha-datatable-container ::-webkit-scrollbar-track {
|
|
155
|
-
background: var(--mantine-color-gray-1);
|
|
156
|
-
border-radius: 4px;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
[data-mantine-color-scheme="dark"]
|
|
160
|
-
.alepha-datatable-container
|
|
161
|
-
::-webkit-scrollbar-track {
|
|
162
|
-
background: var(--mantine-color-dark-6);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.alepha-datatable-container ::-webkit-scrollbar-thumb {
|
|
166
|
-
background: var(--mantine-color-gray-4);
|
|
167
|
-
border-radius: 4px;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
[data-mantine-color-scheme="dark"]
|
|
171
|
-
.alepha-datatable-container
|
|
172
|
-
::-webkit-scrollbar-thumb {
|
|
173
|
-
background: var(--mantine-color-dark-4);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
.alepha-datatable-container ::-webkit-scrollbar-thumb:hover {
|
|
177
|
-
background: var(--mantine-color-gray-5);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
[data-mantine-color-scheme="dark"]
|
|
181
|
-
.alepha-datatable-container
|
|
182
|
-
::-webkit-scrollbar-thumb:hover {
|
|
183
|
-
background: var(--mantine-color-dark-3);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/* Responsive */
|
|
187
|
-
@media (max-width: 768px) {
|
|
188
|
-
.alepha-datatable-toolbar {
|
|
189
|
-
padding: var(--mantine-spacing-sm);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.alepha-datatable-search-input {
|
|
193
|
-
min-width: 150px;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
.alepha-datatable-page-size-select {
|
|
197
|
-
width: 100px;
|
|
198
|
-
}
|
|
199
|
-
}
|