@camtomlabs/malix-design-system 0.1.2 → 0.1.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/LICENSE +19 -5
- package/README.md +141 -10
- package/dist/index.cjs +2456 -0
- package/dist/index.d.cts +562 -0
- package/dist/index.d.ts +562 -0
- package/dist/index.js +2367 -0
- package/package.json +21 -8
- package/src/styles.css +186 -0
- package/src/components/Accordion.tsx +0 -52
- package/src/components/Avatar.tsx +0 -18
- package/src/components/Badge.tsx +0 -27
- package/src/components/Banner.tsx +0 -75
- package/src/components/Breadcrumb.tsx +0 -58
- package/src/components/Button.tsx +0 -47
- package/src/components/Card.tsx +0 -34
- package/src/components/ChatInput.tsx +0 -53
- package/src/components/Checkbox.tsx +0 -85
- package/src/components/CreditsIndicator.tsx +0 -41
- package/src/components/DataTable.tsx +0 -75
- package/src/components/DateInput.tsx +0 -57
- package/src/components/Divider.tsx +0 -12
- package/src/components/Dropzone.tsx +0 -94
- package/src/components/EmptyState.tsx +0 -65
- package/src/components/FileCard.tsx +0 -78
- package/src/components/FilterTabs.tsx +0 -49
- package/src/components/FlyoutMenu.tsx +0 -36
- package/src/components/GlassPopover.tsx +0 -38
- package/src/components/Header.tsx +0 -22
- package/src/components/Input.tsx +0 -18
- package/src/components/InputGroup.tsx +0 -37
- package/src/components/LanguageSelector.tsx +0 -81
- package/src/components/Modal.tsx +0 -104
- package/src/components/OnboardingPopover.tsx +0 -61
- package/src/components/OperationStatus.tsx +0 -73
- package/src/components/Overlay.tsx +0 -66
- package/src/components/Pagination.tsx +0 -89
- package/src/components/Pill.tsx +0 -19
- package/src/components/PricingCard.tsx +0 -74
- package/src/components/ProgressBar.tsx +0 -47
- package/src/components/Radio.tsx +0 -56
- package/src/components/SectionHeader.tsx +0 -32
- package/src/components/SegmentedControl.tsx +0 -42
- package/src/components/Select.tsx +0 -62
- package/src/components/SelectGroup.tsx +0 -32
- package/src/components/SelectionCard.tsx +0 -47
- package/src/components/SidebarItem.tsx +0 -27
- package/src/components/SidebarPanel.tsx +0 -84
- package/src/components/SplitPane.tsx +0 -85
- package/src/components/StatCard.tsx +0 -64
- package/src/components/StatusDot.tsx +0 -26
- package/src/components/Stepper.tsx +0 -40
- package/src/components/TabBar.tsx +0 -45
- package/src/components/Textarea.tsx +0 -43
- package/src/components/Toggle.tsx +0 -50
- package/src/components/Tooltip.tsx +0 -33
- package/src/components/UserProfilePopover.tsx +0 -100
- package/src/components/ValidationAlert.tsx +0 -72
- package/src/index.ts +0 -177
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type CheckboxProps = Omit<React.HTMLAttributes<HTMLButtonElement>, 'onChange'> & {
|
|
4
|
-
checked?: boolean;
|
|
5
|
-
onChange?: (checked: boolean) => void;
|
|
6
|
-
disabled?: boolean;
|
|
7
|
-
label?: string;
|
|
8
|
-
indeterminate?: boolean;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export function Checkbox({
|
|
12
|
-
checked = false,
|
|
13
|
-
onChange,
|
|
14
|
-
disabled = false,
|
|
15
|
-
label,
|
|
16
|
-
indeterminate = false,
|
|
17
|
-
className,
|
|
18
|
-
...props
|
|
19
|
-
}: CheckboxProps) {
|
|
20
|
-
const handleClick = () => {
|
|
21
|
-
if (!disabled && onChange) {
|
|
22
|
-
onChange(!checked);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const checkbox = (
|
|
27
|
-
<button
|
|
28
|
-
type="button"
|
|
29
|
-
role="checkbox"
|
|
30
|
-
className={`malix-checkbox${className ? ` ${className}` : ''}`}
|
|
31
|
-
data-checked={checked}
|
|
32
|
-
data-disabled={disabled}
|
|
33
|
-
data-indeterminate={indeterminate}
|
|
34
|
-
aria-checked={indeterminate ? 'mixed' : checked}
|
|
35
|
-
disabled={disabled}
|
|
36
|
-
onClick={handleClick}
|
|
37
|
-
{...props}
|
|
38
|
-
>
|
|
39
|
-
{checked && !indeterminate ? (
|
|
40
|
-
<svg
|
|
41
|
-
className="malix-checkbox__icon"
|
|
42
|
-
viewBox="0 0 12 12"
|
|
43
|
-
fill="none"
|
|
44
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
45
|
-
aria-hidden="true"
|
|
46
|
-
>
|
|
47
|
-
<path
|
|
48
|
-
d="M2 6l3 3 5-5"
|
|
49
|
-
stroke="currentColor"
|
|
50
|
-
strokeWidth="2"
|
|
51
|
-
strokeLinecap="round"
|
|
52
|
-
strokeLinejoin="round"
|
|
53
|
-
/>
|
|
54
|
-
</svg>
|
|
55
|
-
) : null}
|
|
56
|
-
{indeterminate ? (
|
|
57
|
-
<svg
|
|
58
|
-
className="malix-checkbox__icon"
|
|
59
|
-
viewBox="0 0 12 12"
|
|
60
|
-
fill="none"
|
|
61
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
62
|
-
aria-hidden="true"
|
|
63
|
-
>
|
|
64
|
-
<path
|
|
65
|
-
d="M2 6h8"
|
|
66
|
-
stroke="currentColor"
|
|
67
|
-
strokeWidth="2"
|
|
68
|
-
strokeLinecap="round"
|
|
69
|
-
/>
|
|
70
|
-
</svg>
|
|
71
|
-
) : null}
|
|
72
|
-
</button>
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
if (label) {
|
|
76
|
-
return (
|
|
77
|
-
<label className="malix-checkbox-row">
|
|
78
|
-
{checkbox}
|
|
79
|
-
<span className="malix-checkbox-row__label">{label}</span>
|
|
80
|
-
</label>
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return checkbox;
|
|
85
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type CreditsIndicatorProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
4
|
-
remaining: number;
|
|
5
|
-
label?: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export function CreditsIndicator({
|
|
9
|
-
remaining,
|
|
10
|
-
label = 'Credits Remaining',
|
|
11
|
-
className,
|
|
12
|
-
...props
|
|
13
|
-
}: CreditsIndicatorProps) {
|
|
14
|
-
return (
|
|
15
|
-
<div
|
|
16
|
-
className={`malix-credits-indicator${className ? ` ${className}` : ''}`}
|
|
17
|
-
{...props}
|
|
18
|
-
>
|
|
19
|
-
<span className="malix-credits-indicator__icon" aria-hidden="true">
|
|
20
|
-
<svg
|
|
21
|
-
width="20"
|
|
22
|
-
height="20"
|
|
23
|
-
viewBox="0 0 24 24"
|
|
24
|
-
fill="none"
|
|
25
|
-
stroke="currentColor"
|
|
26
|
-
strokeWidth="2"
|
|
27
|
-
strokeLinecap="round"
|
|
28
|
-
strokeLinejoin="round"
|
|
29
|
-
>
|
|
30
|
-
<ellipse cx="12" cy="6" rx="8" ry="3" />
|
|
31
|
-
<path d="M4 6v6c0 1.66 3.58 3 8 3s8-1.34 8-3V6" />
|
|
32
|
-
<path d="M4 12v6c0 1.66 3.58 3 8 3s8-1.34 8-3v-6" />
|
|
33
|
-
</svg>
|
|
34
|
-
</span>
|
|
35
|
-
<div className="malix-credits-indicator__info">
|
|
36
|
-
<span className="malix-credits-indicator__label">{label}</span>
|
|
37
|
-
<span className="malix-credits-indicator__value">{remaining}</span>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type TableColumn = {
|
|
4
|
-
key: string;
|
|
5
|
-
header: string;
|
|
6
|
-
width?: string;
|
|
7
|
-
render?: (value: any, row: TableRow) => React.ReactNode;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type TableRow = Record<string, any>;
|
|
11
|
-
|
|
12
|
-
export type DataTableProps = React.HTMLAttributes<HTMLTableElement> & {
|
|
13
|
-
columns: TableColumn[];
|
|
14
|
-
data: TableRow[];
|
|
15
|
-
onRowClick?: (row: TableRow) => void;
|
|
16
|
-
emptyMessage?: string;
|
|
17
|
-
className?: string;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export function DataTable({
|
|
21
|
-
columns,
|
|
22
|
-
data,
|
|
23
|
-
onRowClick,
|
|
24
|
-
emptyMessage,
|
|
25
|
-
className,
|
|
26
|
-
...props
|
|
27
|
-
}: DataTableProps) {
|
|
28
|
-
return (
|
|
29
|
-
<table
|
|
30
|
-
className={`malix-data-table${className ? ` ${className}` : ''}`}
|
|
31
|
-
{...props}
|
|
32
|
-
>
|
|
33
|
-
<thead>
|
|
34
|
-
<tr className="malix-data-table__header-row">
|
|
35
|
-
{columns.map((col) => (
|
|
36
|
-
<th
|
|
37
|
-
key={col.key}
|
|
38
|
-
className="malix-data-table__header-cell"
|
|
39
|
-
style={col.width ? { width: col.width } : undefined}
|
|
40
|
-
>
|
|
41
|
-
{col.header}
|
|
42
|
-
</th>
|
|
43
|
-
))}
|
|
44
|
-
</tr>
|
|
45
|
-
</thead>
|
|
46
|
-
<tbody className="malix-data-table__body">
|
|
47
|
-
{data.length > 0 ? (
|
|
48
|
-
data.map((row, rowIndex) => (
|
|
49
|
-
<tr
|
|
50
|
-
key={rowIndex}
|
|
51
|
-
className="malix-data-table__data-row"
|
|
52
|
-
data-clickable={onRowClick ? true : undefined}
|
|
53
|
-
onClick={onRowClick ? () => onRowClick(row) : undefined}
|
|
54
|
-
>
|
|
55
|
-
{columns.map((col) => (
|
|
56
|
-
<td key={col.key} className="malix-data-table__cell">
|
|
57
|
-
{col.render ? col.render(row[col.key], row) : row[col.key]}
|
|
58
|
-
</td>
|
|
59
|
-
))}
|
|
60
|
-
</tr>
|
|
61
|
-
))
|
|
62
|
-
) : (
|
|
63
|
-
<tr className="malix-data-table__data-row">
|
|
64
|
-
<td
|
|
65
|
-
className="malix-data-table__cell"
|
|
66
|
-
colSpan={columns.length}
|
|
67
|
-
>
|
|
68
|
-
{emptyMessage || 'No data available'}
|
|
69
|
-
</td>
|
|
70
|
-
</tr>
|
|
71
|
-
)}
|
|
72
|
-
</tbody>
|
|
73
|
-
</table>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type DateInputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'onChange'> & {
|
|
4
|
-
value?: string;
|
|
5
|
-
placeholder?: string;
|
|
6
|
-
onChange?: (value: string) => void;
|
|
7
|
-
disabled?: boolean;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export function DateInput({
|
|
11
|
-
value,
|
|
12
|
-
placeholder = 'dd/mm/yyyy',
|
|
13
|
-
onChange,
|
|
14
|
-
disabled,
|
|
15
|
-
className,
|
|
16
|
-
id,
|
|
17
|
-
...props
|
|
18
|
-
}: DateInputProps) {
|
|
19
|
-
const inputId = id || `date-input-${React.useId()}`;
|
|
20
|
-
|
|
21
|
-
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
22
|
-
onChange?.(e.target.value);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<div
|
|
27
|
-
className={`malix-date-input${className ? ` ${className}` : ''}`}
|
|
28
|
-
data-filled={value ? true : undefined}
|
|
29
|
-
data-disabled={disabled || undefined}
|
|
30
|
-
>
|
|
31
|
-
<input
|
|
32
|
-
id={inputId}
|
|
33
|
-
type="date"
|
|
34
|
-
className="malix-date-input__native"
|
|
35
|
-
value={value}
|
|
36
|
-
onChange={handleChange}
|
|
37
|
-
disabled={disabled}
|
|
38
|
-
aria-label={placeholder}
|
|
39
|
-
{...props}
|
|
40
|
-
/>
|
|
41
|
-
<span className="malix-date-input__value">
|
|
42
|
-
{value || placeholder}
|
|
43
|
-
</span>
|
|
44
|
-
<span className="malix-date-input__icon" aria-hidden="true">
|
|
45
|
-
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
46
|
-
<path
|
|
47
|
-
d="M12.667 2.667H3.333C2.597 2.667 2 3.264 2 4v9.333c0 .737.597 1.334 1.333 1.334h9.334c.736 0 1.333-.597 1.333-1.334V4c0-.736-.597-1.333-1.333-1.333ZM10.667 1.333V4M5.333 1.333V4M2 6.667h12"
|
|
48
|
-
stroke="currentColor"
|
|
49
|
-
strokeWidth="1.33"
|
|
50
|
-
strokeLinecap="round"
|
|
51
|
-
strokeLinejoin="round"
|
|
52
|
-
/>
|
|
53
|
-
</svg>
|
|
54
|
-
</span>
|
|
55
|
-
</div>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type DividerProps = React.HTMLAttributes<HTMLHRElement>;
|
|
4
|
-
|
|
5
|
-
export function Divider({ className, ...props }: DividerProps) {
|
|
6
|
-
return (
|
|
7
|
-
<hr
|
|
8
|
-
className={`malix-divider${className ? ` ${className}` : ''}`}
|
|
9
|
-
{...props}
|
|
10
|
-
/>
|
|
11
|
-
);
|
|
12
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import React, { useRef, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
export type DropzoneProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
4
|
-
onDrop?: (files: File[]) => void;
|
|
5
|
-
accept?: string;
|
|
6
|
-
title?: string;
|
|
7
|
-
hint?: string;
|
|
8
|
-
disabled?: boolean;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export function Dropzone({
|
|
12
|
-
onDrop,
|
|
13
|
-
accept,
|
|
14
|
-
title = 'Drop files here',
|
|
15
|
-
hint = 'or click to browse',
|
|
16
|
-
disabled = false,
|
|
17
|
-
className,
|
|
18
|
-
...props
|
|
19
|
-
}: DropzoneProps) {
|
|
20
|
-
const [dragging, setDragging] = useState(false);
|
|
21
|
-
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
22
|
-
|
|
23
|
-
function handleDragOver(event: React.DragEvent<HTMLDivElement>) {
|
|
24
|
-
event.preventDefault();
|
|
25
|
-
if (!disabled) setDragging(true);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function handleDragLeave(event: React.DragEvent<HTMLDivElement>) {
|
|
29
|
-
event.preventDefault();
|
|
30
|
-
setDragging(false);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function handleDrop(event: React.DragEvent<HTMLDivElement>) {
|
|
34
|
-
event.preventDefault();
|
|
35
|
-
setDragging(false);
|
|
36
|
-
if (disabled) return;
|
|
37
|
-
const files = Array.from(event.dataTransfer.files);
|
|
38
|
-
onDrop?.(files);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
42
|
-
const files = event.target.files ? Array.from(event.target.files) : [];
|
|
43
|
-
if (files.length > 0) onDrop?.(files);
|
|
44
|
-
event.target.value = '';
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function handleClick() {
|
|
48
|
-
if (!disabled) inputRef.current?.click();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<div
|
|
53
|
-
className={`malix-dropzone${className ? ` ${className}` : ''}`}
|
|
54
|
-
data-dragging={dragging}
|
|
55
|
-
data-disabled={disabled}
|
|
56
|
-
onDragOver={handleDragOver}
|
|
57
|
-
onDragLeave={handleDragLeave}
|
|
58
|
-
onDrop={handleDrop}
|
|
59
|
-
onClick={handleClick}
|
|
60
|
-
role="button"
|
|
61
|
-
tabIndex={disabled ? -1 : 0}
|
|
62
|
-
aria-disabled={disabled || undefined}
|
|
63
|
-
{...props}
|
|
64
|
-
>
|
|
65
|
-
<input
|
|
66
|
-
ref={inputRef}
|
|
67
|
-
type="file"
|
|
68
|
-
accept={accept}
|
|
69
|
-
onChange={handleInputChange}
|
|
70
|
-
hidden
|
|
71
|
-
aria-hidden="true"
|
|
72
|
-
/>
|
|
73
|
-
<svg
|
|
74
|
-
className="malix-dropzone__icon"
|
|
75
|
-
width="32"
|
|
76
|
-
height="32"
|
|
77
|
-
viewBox="0 0 24 24"
|
|
78
|
-
fill="none"
|
|
79
|
-
stroke="currentColor"
|
|
80
|
-
strokeWidth="1.5"
|
|
81
|
-
strokeLinecap="round"
|
|
82
|
-
strokeLinejoin="round"
|
|
83
|
-
aria-hidden="true"
|
|
84
|
-
>
|
|
85
|
-
<path d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242" />
|
|
86
|
-
<path d="M12 12v9" />
|
|
87
|
-
<path d="m16 16-4-4-4 4" />
|
|
88
|
-
</svg>
|
|
89
|
-
<span className="malix-dropzone__title">{title}</span>
|
|
90
|
-
<span className="malix-dropzone__hint">{hint}</span>
|
|
91
|
-
<span className="malix-dropzone__browse-btn">Browse files</span>
|
|
92
|
-
</div>
|
|
93
|
-
);
|
|
94
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type EmptyStateProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
4
|
-
icon?: React.ReactNode;
|
|
5
|
-
title: string;
|
|
6
|
-
description?: string;
|
|
7
|
-
action?: React.ReactNode;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const DefaultIcon = () => (
|
|
11
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
12
|
-
<path
|
|
13
|
-
d="M3 7V5C3 3.895 3.895 3 5 3H9L11 5H19C20.105 5 21 5.895 21 7V9"
|
|
14
|
-
stroke="currentColor"
|
|
15
|
-
strokeWidth="1.5"
|
|
16
|
-
strokeLinecap="round"
|
|
17
|
-
strokeLinejoin="round"
|
|
18
|
-
/>
|
|
19
|
-
<rect
|
|
20
|
-
x="2"
|
|
21
|
-
y="9"
|
|
22
|
-
width="20"
|
|
23
|
-
height="12"
|
|
24
|
-
rx="2"
|
|
25
|
-
stroke="currentColor"
|
|
26
|
-
strokeWidth="1.5"
|
|
27
|
-
strokeLinecap="round"
|
|
28
|
-
strokeLinejoin="round"
|
|
29
|
-
/>
|
|
30
|
-
<path
|
|
31
|
-
d="M9 15H15"
|
|
32
|
-
stroke="currentColor"
|
|
33
|
-
strokeWidth="1.5"
|
|
34
|
-
strokeLinecap="round"
|
|
35
|
-
strokeLinejoin="round"
|
|
36
|
-
/>
|
|
37
|
-
</svg>
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
export function EmptyState({
|
|
41
|
-
icon,
|
|
42
|
-
title,
|
|
43
|
-
description,
|
|
44
|
-
action,
|
|
45
|
-
className,
|
|
46
|
-
...props
|
|
47
|
-
}: EmptyStateProps) {
|
|
48
|
-
return (
|
|
49
|
-
<div
|
|
50
|
-
className={`malix-empty-state${className ? ` ${className}` : ''}`}
|
|
51
|
-
{...props}
|
|
52
|
-
>
|
|
53
|
-
<div className="malix-empty-state__icon-wrap">
|
|
54
|
-
{icon ?? <DefaultIcon />}
|
|
55
|
-
</div>
|
|
56
|
-
<h3 className="malix-empty-state__title">{title}</h3>
|
|
57
|
-
{description ? (
|
|
58
|
-
<p className="malix-empty-state__description">{description}</p>
|
|
59
|
-
) : null}
|
|
60
|
-
{action ? (
|
|
61
|
-
<div className="malix-empty-state__action">{action}</div>
|
|
62
|
-
) : null}
|
|
63
|
-
</div>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type FileCardProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
4
|
-
fileName: string;
|
|
5
|
-
meta?: string;
|
|
6
|
-
icon?: React.ReactNode;
|
|
7
|
-
onAction?: React.MouseEventHandler<HTMLButtonElement>;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const DefaultFileIcon = () => (
|
|
11
|
-
<svg
|
|
12
|
-
width="20"
|
|
13
|
-
height="20"
|
|
14
|
-
viewBox="0 0 24 24"
|
|
15
|
-
fill="none"
|
|
16
|
-
stroke="currentColor"
|
|
17
|
-
strokeWidth="2"
|
|
18
|
-
strokeLinecap="round"
|
|
19
|
-
strokeLinejoin="round"
|
|
20
|
-
>
|
|
21
|
-
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
|
|
22
|
-
<polyline points="14 2 14 8 20 8" />
|
|
23
|
-
<line x1="16" y1="13" x2="8" y2="13" />
|
|
24
|
-
<line x1="16" y1="17" x2="8" y2="17" />
|
|
25
|
-
<polyline points="10 9 9 9 8 9" />
|
|
26
|
-
</svg>
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
const MoreVerticalIcon = () => (
|
|
30
|
-
<svg
|
|
31
|
-
width="16"
|
|
32
|
-
height="16"
|
|
33
|
-
viewBox="0 0 24 24"
|
|
34
|
-
fill="currentColor"
|
|
35
|
-
>
|
|
36
|
-
<circle cx="12" cy="5" r="1.5" />
|
|
37
|
-
<circle cx="12" cy="12" r="1.5" />
|
|
38
|
-
<circle cx="12" cy="19" r="1.5" />
|
|
39
|
-
</svg>
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
export function FileCard({
|
|
43
|
-
fileName,
|
|
44
|
-
meta,
|
|
45
|
-
icon,
|
|
46
|
-
onAction,
|
|
47
|
-
className,
|
|
48
|
-
...props
|
|
49
|
-
}: FileCardProps) {
|
|
50
|
-
return (
|
|
51
|
-
<div
|
|
52
|
-
className={`malix-file-card${className ? ` ${className}` : ''}`}
|
|
53
|
-
{...props}
|
|
54
|
-
>
|
|
55
|
-
<div className="malix-file-card__icon-wrap">
|
|
56
|
-
<span className="malix-file-card__icon">
|
|
57
|
-
{icon ?? <DefaultFileIcon />}
|
|
58
|
-
</span>
|
|
59
|
-
</div>
|
|
60
|
-
<div className="malix-file-card__info">
|
|
61
|
-
<span className="malix-file-card__name">{fileName}</span>
|
|
62
|
-
{meta ? (
|
|
63
|
-
<span className="malix-file-card__meta">{meta}</span>
|
|
64
|
-
) : null}
|
|
65
|
-
</div>
|
|
66
|
-
{onAction ? (
|
|
67
|
-
<button
|
|
68
|
-
type="button"
|
|
69
|
-
className="malix-file-card__action"
|
|
70
|
-
onClick={onAction}
|
|
71
|
-
aria-label="More actions"
|
|
72
|
-
>
|
|
73
|
-
<MoreVerticalIcon />
|
|
74
|
-
</button>
|
|
75
|
-
) : null}
|
|
76
|
-
</div>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type FilterTabItem = {
|
|
4
|
-
label: string;
|
|
5
|
-
count?: number;
|
|
6
|
-
value: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type FilterTabsProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> & {
|
|
10
|
-
items: FilterTabItem[];
|
|
11
|
-
value: string;
|
|
12
|
-
onChange: (value: string) => void;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export function FilterTabs({
|
|
16
|
-
items,
|
|
17
|
-
value,
|
|
18
|
-
onChange,
|
|
19
|
-
className,
|
|
20
|
-
...props
|
|
21
|
-
}: FilterTabsProps) {
|
|
22
|
-
return (
|
|
23
|
-
<div
|
|
24
|
-
className={`malix-filter-tabs${className ? ` ${className}` : ''}`}
|
|
25
|
-
role="tablist"
|
|
26
|
-
{...props}
|
|
27
|
-
>
|
|
28
|
-
{items.map((item) => {
|
|
29
|
-
const isActive = item.value === value;
|
|
30
|
-
return (
|
|
31
|
-
<button
|
|
32
|
-
key={item.value}
|
|
33
|
-
type="button"
|
|
34
|
-
role="tab"
|
|
35
|
-
className="malix-filter-tabs__tab"
|
|
36
|
-
data-active={isActive || undefined}
|
|
37
|
-
aria-selected={isActive}
|
|
38
|
-
onClick={() => onChange(item.value)}
|
|
39
|
-
>
|
|
40
|
-
<span className="malix-filter-tabs__tab-label">{item.label}</span>
|
|
41
|
-
{item.count != null ? (
|
|
42
|
-
<span className="malix-filter-tabs__tab-count">{item.count}</span>
|
|
43
|
-
) : null}
|
|
44
|
-
</button>
|
|
45
|
-
);
|
|
46
|
-
})}
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type FlyoutMenuItem = {
|
|
4
|
-
icon?: React.ReactNode;
|
|
5
|
-
label: string;
|
|
6
|
-
active?: boolean;
|
|
7
|
-
onClick?: () => void;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type FlyoutMenuProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
11
|
-
items: FlyoutMenuItem[];
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export function FlyoutMenu({ items, className, ...props }: FlyoutMenuProps) {
|
|
15
|
-
return (
|
|
16
|
-
<nav
|
|
17
|
-
className={`malix-flyout-menu${className ? ` ${className}` : ''}`}
|
|
18
|
-
role="menu"
|
|
19
|
-
{...props}
|
|
20
|
-
>
|
|
21
|
-
{items.map((item, i) => (
|
|
22
|
-
<button
|
|
23
|
-
key={i}
|
|
24
|
-
type="button"
|
|
25
|
-
className="malix-flyout-menu__item"
|
|
26
|
-
data-active={item.active || undefined}
|
|
27
|
-
role="menuitem"
|
|
28
|
-
onClick={item.onClick}
|
|
29
|
-
>
|
|
30
|
-
{item.icon ? <span className="malix-flyout-menu__icon">{item.icon}</span> : null}
|
|
31
|
-
<span className="malix-flyout-menu__label">{item.label}</span>
|
|
32
|
-
</button>
|
|
33
|
-
))}
|
|
34
|
-
</nav>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type GlassPopoverProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
4
|
-
title?: string;
|
|
5
|
-
onClose?: () => void;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export function GlassPopover({
|
|
9
|
-
title,
|
|
10
|
-
onClose,
|
|
11
|
-
children,
|
|
12
|
-
className,
|
|
13
|
-
...props
|
|
14
|
-
}: GlassPopoverProps) {
|
|
15
|
-
return (
|
|
16
|
-
<div
|
|
17
|
-
className={`malix-glass-popover${className ? ` ${className}` : ''}`}
|
|
18
|
-
{...props}
|
|
19
|
-
>
|
|
20
|
-
{(title || onClose) ? (
|
|
21
|
-
<div className="malix-glass-popover__header">
|
|
22
|
-
{title ? <span className="malix-glass-popover__title">{title}</span> : null}
|
|
23
|
-
{onClose ? (
|
|
24
|
-
<button
|
|
25
|
-
type="button"
|
|
26
|
-
className="malix-glass-popover__close"
|
|
27
|
-
onClick={onClose}
|
|
28
|
-
aria-label="Close"
|
|
29
|
-
>
|
|
30
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" /></svg>
|
|
31
|
-
</button>
|
|
32
|
-
) : null}
|
|
33
|
-
</div>
|
|
34
|
-
) : null}
|
|
35
|
-
<div className="malix-glass-popover__body">{children}</div>
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type HeaderProps = React.HTMLAttributes<HTMLElement> & {
|
|
4
|
-
pageTitle: string;
|
|
5
|
-
actions?: React.ReactNode;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export function Header({ pageTitle, actions, className, ...props }: HeaderProps) {
|
|
9
|
-
return (
|
|
10
|
-
<header
|
|
11
|
-
className={`malix-header${className ? ` ${className}` : ''}`}
|
|
12
|
-
{...props}
|
|
13
|
-
>
|
|
14
|
-
<div className="malix-header__left">
|
|
15
|
-
<h1 className="malix-header__title">{pageTitle}</h1>
|
|
16
|
-
</div>
|
|
17
|
-
{actions ? (
|
|
18
|
-
<div className="malix-header__right">{actions}</div>
|
|
19
|
-
) : null}
|
|
20
|
-
</header>
|
|
21
|
-
);
|
|
22
|
-
}
|
package/src/components/Input.tsx
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type InputProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
4
|
-
leadingIcon?: React.ReactNode;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export function Input({ leadingIcon, ...props }: InputProps) {
|
|
8
|
-
return (
|
|
9
|
-
<label className="malix-input-wrap">
|
|
10
|
-
{leadingIcon ? <span className="malix-button__icon">{leadingIcon}</span> : null}
|
|
11
|
-
<input className="malix-input" {...props} />
|
|
12
|
-
</label>
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function SearchInput(props: Omit<InputProps, 'type'>) {
|
|
17
|
-
return <Input type="search" placeholder="Search" {...props} />;
|
|
18
|
-
}
|