@socprime/react-ui 0.0.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/CHANGELOG.md +56 -0
- package/LICENSE +21 -0
- package/README.md +537 -0
- package/attack-flow.d.ts +16 -0
- package/charts.d.ts +32 -0
- package/decorators/index.js +8 -0
- package/decorators/withRouter.js +10 -0
- package/decorators/withTheme.js +10 -0
- package/decorators.d.ts +10 -0
- package/domain.d.ts +23 -0
- package/editor.d.ts +25 -0
- package/index.d.ts +702 -0
- package/lib/cn.js +8 -0
- package/lib/theme.js +26 -0
- package/lib/useFullscreen.js +52 -0
- package/lib/useListenOnResizeDebounce.js +22 -0
- package/lib/useThemeColors.js +39 -0
- package/package.json +113 -0
- package/preset/createConfig.js +98 -0
- package/preset/createPreview.js +53 -0
- package/preset/index.js +6 -0
- package/preset/restoreNativeFocus.js +33 -0
- package/preset/types.js +0 -0
- package/preset.d.ts +27 -0
- package/theme-9m7j1UoI.d.ts +5 -0
- package/ui/Accordion/Accordion.js +82 -0
- package/ui/Accordion/AccordionSection.js +41 -0
- package/ui/Accordion/FolderTreeExpandTrigger.js +29 -0
- package/ui/Accordion/chevronVariants.js +31 -0
- package/ui/Accordion/index.js +16 -0
- package/ui/AnimatedDots/AnimatedDots.js +10 -0
- package/ui/AnimatedDots/index.js +4 -0
- package/ui/Aside/Aside.js +34 -0
- package/ui/Aside/index.js +4 -0
- package/ui/AttackFlow/AttackFlow.js +9 -0
- package/ui/AttackFlow/AttackFlowLayout.js +63 -0
- package/ui/AttackFlow/Controls.js +42 -0
- package/ui/AttackFlow/Node.js +47 -0
- package/ui/AttackFlow/OtherNode.js +44 -0
- package/ui/AttackFlow/index.js +4 -0
- package/ui/AttackFlow/prependData.js +153 -0
- package/ui/AttackFlow/types.js +0 -0
- package/ui/AttackFlow/useAttackFlow.js +193 -0
- package/ui/Badge/Badge.js +57 -0
- package/ui/Badge/index.js +5 -0
- package/ui/Button/Button.css +1 -0
- package/ui/Button/Button.js +109 -0
- package/ui/Button/index.js +5 -0
- package/ui/Charts/AreaChartWithGradient.js +79 -0
- package/ui/Charts/index.js +4 -0
- package/ui/Checkbox/Checkbox.js +31 -0
- package/ui/Checkbox/index.js +4 -0
- package/ui/ConditionalContent/ConditionalContent.js +10 -0
- package/ui/ConditionalContent/index.js +4 -0
- package/ui/CorrelationTimer/CorrelationTimer.js +62 -0
- package/ui/CorrelationTimer/index.js +4 -0
- package/ui/DeleteButtonConfirm/DeleteButtonConfirm.js +65 -0
- package/ui/DeleteButtonConfirm/index.js +4 -0
- package/ui/Dialog/ConfirmDialog.js +54 -0
- package/ui/Dialog/DefaultDialog.js +82 -0
- package/ui/Dialog/Dialog.js +120 -0
- package/ui/Dialog/index.js +32 -0
- package/ui/Dropdown/Dropdown.js +204 -0
- package/ui/Dropdown/DropdownsCheckbox.js +102 -0
- package/ui/Dropdown/DropdownsSelect.js +97 -0
- package/ui/Dropdown/index.js +38 -0
- package/ui/Editor/Editor.js +97 -0
- package/ui/Editor/index.js +4 -0
- package/ui/Editor/monacoSetup.js +38 -0
- package/ui/Editor/theme.js +50 -0
- package/ui/Editor/types.js +0 -0
- package/ui/EmptyState/EmptyState.js +26 -0
- package/ui/EmptyState/index.js +4 -0
- package/ui/Field/Field.js +204 -0
- package/ui/Field/index.js +24 -0
- package/ui/HelperText/HelperText.js +7 -0
- package/ui/HelperText/index.js +4 -0
- package/ui/Input/Input.js +40 -0
- package/ui/Input/index.js +4 -0
- package/ui/InputNumber/InputNumber.js +90 -0
- package/ui/InputNumber/index.js +4 -0
- package/ui/InputPassword/InputPassword.js +30 -0
- package/ui/InputPassword/index.js +4 -0
- package/ui/Label/Label.js +13 -0
- package/ui/Label/LabelInfo.js +14 -0
- package/ui/Label/index.js +6 -0
- package/ui/MultiSelect/MultiSelect.js +163 -0
- package/ui/MultiSelect/index.js +4 -0
- package/ui/PageHeader/PageHeader.js +51 -0
- package/ui/PageHeader/index.js +4 -0
- package/ui/Pagination/Pagination.js +97 -0
- package/ui/Pagination/PaginationWrap.js +149 -0
- package/ui/Pagination/index.js +20 -0
- package/ui/RadioGroup/RadioGroup.js +45 -0
- package/ui/RadioGroup/index.js +5 -0
- package/ui/ScrollArea/ScrollArea.js +57 -0
- package/ui/ScrollArea/index.js +5 -0
- package/ui/SearchInput/SearchInput.js +38 -0
- package/ui/SearchInput/index.js +4 -0
- package/ui/SearchInputFields/SearchInputFields.js +53 -0
- package/ui/SearchInputFields/index.js +4 -0
- package/ui/Select/Select.js +155 -0
- package/ui/Select/SelectDefault.js +43 -0
- package/ui/Select/index.js +26 -0
- package/ui/Separator/Separator.js +26 -0
- package/ui/Separator/index.js +4 -0
- package/ui/Severity/Severity.js +11 -0
- package/ui/Severity/index.js +4 -0
- package/ui/Severity/utils.js +53 -0
- package/ui/Skeleton/Skeleton.js +25 -0
- package/ui/Skeleton/index.js +5 -0
- package/ui/Slider/Slider.js +50 -0
- package/ui/Slider/index.js +4 -0
- package/ui/Spinner/Spinner.js +21 -0
- package/ui/Spinner/index.js +5 -0
- package/ui/SpinnerSquare/SpinnerSquare.css +1 -0
- package/ui/SpinnerSquare/SpinnerSquare.js +22 -0
- package/ui/SpinnerSquare/index.js +4 -0
- package/ui/StatisticCard/StatisticCard.js +27 -0
- package/ui/StatisticCard/index.js +4 -0
- package/ui/StatisticCard/types.js +0 -0
- package/ui/Suggestions/Suggestions.js +244 -0
- package/ui/Suggestions/index.js +4 -0
- package/ui/Switch/Switch.js +64 -0
- package/ui/Switch/index.js +4 -0
- package/ui/SyncProcessBar/SyncProcessBar.js +14 -0
- package/ui/SyncProcessBar/index.js +4 -0
- package/ui/Table/GroupHeaderRow.js +36 -0
- package/ui/Table/RowGrouped.js +19 -0
- package/ui/Table/ServerGroupedTableBody.js +89 -0
- package/ui/Table/SortableHeader.js +46 -0
- package/ui/Table/Table.js +110 -0
- package/ui/Table/TableWrap.js +124 -0
- package/ui/Table/columnStyle.js +14 -0
- package/ui/Table/index.js +28 -0
- package/ui/Tabs/Tabs.js +76 -0
- package/ui/Tabs/index.js +4 -0
- package/ui/TextTruncate/TextTruncate.js +107 -0
- package/ui/TextTruncate/index.js +4 -0
- package/ui/Textarea/Textarea.js +20 -0
- package/ui/Textarea/index.js +4 -0
- package/ui/ThemeToggle/ThemeToggle.js +23 -0
- package/ui/ThemeToggle/index.js +4 -0
- package/ui/Toast/Toast.js +23 -0
- package/ui/Toast/index.js +4 -0
- package/ui/Tooltip/Tooltip.js +17 -0
- package/ui/Tooltip/TooltipLayout.js +60 -0
- package/ui/Tooltip/index.js +14 -0
- package/ui/TreeGuide/TreeGuide.js +23 -0
- package/ui/TreeGuide/index.js +5 -0
- package/ui/entries/charts.js +2 -0
- package/ui/entries/domain.js +3 -0
- package/ui/index.js +45 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { flexRender } from "@tanstack/react-table";
|
|
4
|
+
import { DatabaseIcon } from "lucide-react";
|
|
5
|
+
import { AnimatePresence, motion } from "motion/react";
|
|
6
|
+
import { memo } from "react";
|
|
7
|
+
import { ConditionalContent } from "../ConditionalContent/ConditionalContent.js";
|
|
8
|
+
import { EmptyState } from "../EmptyState/EmptyState.js";
|
|
9
|
+
import { SkeletonTable } from "../Skeleton/Skeleton.js";
|
|
10
|
+
import { getColumnStyle } from "./columnStyle.js";
|
|
11
|
+
import { RowGrouped } from "./RowGrouped.js";
|
|
12
|
+
import { SortableHeader } from "./SortableHeader.js";
|
|
13
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./Table.js";
|
|
14
|
+
function TableWrapInner({
|
|
15
|
+
className,
|
|
16
|
+
classNameTable,
|
|
17
|
+
classNameScrollArea,
|
|
18
|
+
classNameHeader,
|
|
19
|
+
classNameCell,
|
|
20
|
+
table,
|
|
21
|
+
columns,
|
|
22
|
+
data: _data,
|
|
23
|
+
orientation = "both",
|
|
24
|
+
loading = false,
|
|
25
|
+
rowSelection: _rowSelection,
|
|
26
|
+
loadedContent,
|
|
27
|
+
emptyContent
|
|
28
|
+
}) {
|
|
29
|
+
const defaultTableBody = /* @__PURE__ */ jsx(TableBody, { children: table.getRowModel().rows?.length ? /* @__PURE__ */ jsx(AnimatePresence, { mode: "popLayout", children: table.getRowModel().rows.map((row, index) => {
|
|
30
|
+
if (row.getIsGrouped()) {
|
|
31
|
+
return /* @__PURE__ */ jsx(RowGrouped, { row, table }, row.id);
|
|
32
|
+
}
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
motion.tr,
|
|
35
|
+
{
|
|
36
|
+
"data-state": row.getIsSelected() && "selected",
|
|
37
|
+
className: cn(
|
|
38
|
+
"hover:bg-hover/20 data-[state=selected]:bg-secondary/80 border-border group border-b transition-colors",
|
|
39
|
+
row.getIsGrouped() && "bg-secondary/30"
|
|
40
|
+
),
|
|
41
|
+
initial: { opacity: 0, x: -50 },
|
|
42
|
+
animate: { opacity: 1, x: 0 },
|
|
43
|
+
exit: { opacity: 0, x: -50 },
|
|
44
|
+
transition: {
|
|
45
|
+
duration: 0.3,
|
|
46
|
+
delay: index * 0.05,
|
|
47
|
+
ease: [0.16, 1, 0.3, 1]
|
|
48
|
+
},
|
|
49
|
+
children: row.getVisibleCells().map((cell) => {
|
|
50
|
+
if (cell.getIsPlaceholder() || cell.getIsGrouped()) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const columnStyle = getColumnStyle(cell.column.columnDef.meta);
|
|
54
|
+
return /* @__PURE__ */ jsx(
|
|
55
|
+
TableCell,
|
|
56
|
+
{
|
|
57
|
+
className: cn("px-6 py-4", classNameCell),
|
|
58
|
+
style: columnStyle,
|
|
59
|
+
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
60
|
+
},
|
|
61
|
+
cell.id
|
|
62
|
+
);
|
|
63
|
+
})
|
|
64
|
+
},
|
|
65
|
+
row.id
|
|
66
|
+
);
|
|
67
|
+
}) }) : /* @__PURE__ */ jsx(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsx(TableCell, { colSpan: columns.length, className: "h-24 p-0 text-center", children: emptyContent ?? /* @__PURE__ */ jsx(
|
|
68
|
+
EmptyState,
|
|
69
|
+
{
|
|
70
|
+
Icon: DatabaseIcon,
|
|
71
|
+
title: "No data",
|
|
72
|
+
description: "Results will be displayed here after you add some data"
|
|
73
|
+
}
|
|
74
|
+
) }) }) });
|
|
75
|
+
return /* @__PURE__ */ jsxs(
|
|
76
|
+
Table,
|
|
77
|
+
{
|
|
78
|
+
className,
|
|
79
|
+
classNameTable: cn("text-xs font-normal", classNameTable),
|
|
80
|
+
orientation,
|
|
81
|
+
classNameScrollArea,
|
|
82
|
+
children: [
|
|
83
|
+
/* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(TableRow, { children: headerGroup.headers.map((header) => {
|
|
84
|
+
const grouping = table.getState().grouping;
|
|
85
|
+
if (grouping.includes(header.column.id)) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
const columnStyle = getColumnStyle(header.column.columnDef.meta);
|
|
89
|
+
const canSort = header.column.getCanSort();
|
|
90
|
+
const isSortingEnabled = table.options.enableSorting !== false;
|
|
91
|
+
return /* @__PURE__ */ jsx(
|
|
92
|
+
TableHead,
|
|
93
|
+
{
|
|
94
|
+
className: cn(
|
|
95
|
+
"bg-secondary px-6 py-3",
|
|
96
|
+
classNameHeader,
|
|
97
|
+
canSort && isSortingEnabled && "hover:bg-muted/50 group cursor-pointer select-none"
|
|
98
|
+
),
|
|
99
|
+
style: columnStyle,
|
|
100
|
+
onClick: canSort && isSortingEnabled ? header.column.getToggleSortingHandler() : void 0,
|
|
101
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
102
|
+
header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()),
|
|
103
|
+
/* @__PURE__ */ jsx(SortableHeader, { header, isSortingEnabled })
|
|
104
|
+
] })
|
|
105
|
+
},
|
|
106
|
+
header.id
|
|
107
|
+
);
|
|
108
|
+
}) }, headerGroup.id)) }),
|
|
109
|
+
/* @__PURE__ */ jsx(
|
|
110
|
+
ConditionalContent,
|
|
111
|
+
{
|
|
112
|
+
loading,
|
|
113
|
+
loadingContent: /* @__PURE__ */ jsx(SkeletonTable, { rows: 10, columns: columns.length }),
|
|
114
|
+
loadedContent: loadedContent ?? defaultTableBody
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
const TableWrap = memo(TableWrapInner);
|
|
122
|
+
export {
|
|
123
|
+
TableWrap
|
|
124
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const getColumnStyle = (meta) => {
|
|
2
|
+
const { width, minWidth, maxWidth } = meta ?? {};
|
|
3
|
+
if (!width && !minWidth && !maxWidth) {
|
|
4
|
+
return void 0;
|
|
5
|
+
}
|
|
6
|
+
return {
|
|
7
|
+
width,
|
|
8
|
+
minWidth: minWidth ?? width,
|
|
9
|
+
maxWidth: maxWidth ?? width
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
getColumnStyle
|
|
14
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { GroupHeaderRow } from "./GroupHeaderRow.js";
|
|
2
|
+
import { ServerGroupedTableBody } from "./ServerGroupedTableBody.js";
|
|
3
|
+
import { SortableHeader } from "./SortableHeader.js";
|
|
4
|
+
import {
|
|
5
|
+
Table,
|
|
6
|
+
TableBody as TableBody2,
|
|
7
|
+
TableCaption as TableCaption2,
|
|
8
|
+
TableCell as TableCell2,
|
|
9
|
+
TableFooter as TableFooter2,
|
|
10
|
+
TableHead as TableHead2,
|
|
11
|
+
TableHeader as TableHeader2,
|
|
12
|
+
TableRow as TableRow2
|
|
13
|
+
} from "./Table.js";
|
|
14
|
+
import { TableWrap } from "./TableWrap.js";
|
|
15
|
+
export {
|
|
16
|
+
GroupHeaderRow,
|
|
17
|
+
ServerGroupedTableBody,
|
|
18
|
+
SortableHeader,
|
|
19
|
+
Table,
|
|
20
|
+
TableBody2 as TableBody,
|
|
21
|
+
TableCaption2 as TableCaption,
|
|
22
|
+
TableCell2 as TableCell,
|
|
23
|
+
TableFooter2 as TableFooter,
|
|
24
|
+
TableHead2 as TableHead,
|
|
25
|
+
TableHeader2 as TableHeader,
|
|
26
|
+
TableRow2 as TableRow,
|
|
27
|
+
TableWrap
|
|
28
|
+
};
|
package/ui/Tabs/Tabs.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
3
|
+
import { cn } from "../../lib/cn.js";
|
|
4
|
+
function Tabs({
|
|
5
|
+
tabs,
|
|
6
|
+
defaultValue,
|
|
7
|
+
value,
|
|
8
|
+
className,
|
|
9
|
+
tabClassName,
|
|
10
|
+
tabsListClassName,
|
|
11
|
+
tabsContentClassName,
|
|
12
|
+
onValueChange
|
|
13
|
+
}) {
|
|
14
|
+
const initialValue = defaultValue ?? tabs[0]?.value;
|
|
15
|
+
const isControlled = value !== void 0;
|
|
16
|
+
return /* @__PURE__ */ jsxs(
|
|
17
|
+
TabsPrimitive.Root,
|
|
18
|
+
{
|
|
19
|
+
className: cn("flex flex-col gap-4", className),
|
|
20
|
+
"data-slot": "tabs",
|
|
21
|
+
...isControlled ? {} : { defaultValue: initialValue },
|
|
22
|
+
value,
|
|
23
|
+
onValueChange,
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsx(TabsList, { className: tabsListClassName, children: tabs.map((tab) => /* @__PURE__ */ jsx(TabsTrigger, { value: tab.value, disabled: tab.disabled, className: tabClassName, children: tab.label }, tab.value)) }),
|
|
26
|
+
tabs.map((tab) => {
|
|
27
|
+
const TabPanel = tab.Content;
|
|
28
|
+
const shouldRenderPanel = value == null || value === tab.value;
|
|
29
|
+
return /* @__PURE__ */ jsx(TabsContent, { className: tabsContentClassName, value: tab.value, children: shouldRenderPanel && (TabPanel ? /* @__PURE__ */ jsx(TabPanel, {}) : tab.content) }, tab.value);
|
|
30
|
+
})
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
function TabsList({ className, ...props }) {
|
|
36
|
+
return /* @__PURE__ */ jsx(
|
|
37
|
+
TabsPrimitive.List,
|
|
38
|
+
{
|
|
39
|
+
"data-slot": "tabs-list",
|
|
40
|
+
className: cn(
|
|
41
|
+
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-1",
|
|
42
|
+
className
|
|
43
|
+
),
|
|
44
|
+
...props
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function TabsTrigger({ className, ...props }) {
|
|
49
|
+
return /* @__PURE__ */ jsx(
|
|
50
|
+
TabsPrimitive.Trigger,
|
|
51
|
+
{
|
|
52
|
+
"data-slot": "tabs-trigger",
|
|
53
|
+
className: cn(
|
|
54
|
+
"text-gray-chateau hover:text-default hover:bg-hover inline-flex cursor-pointer items-center justify-center gap-1.5 border-b border-transparent px-3 py-2 text-xs font-medium whitespace-nowrap transition-all",
|
|
55
|
+
"focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",
|
|
56
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
57
|
+
"data-[state=active]:bg-background data-[state=active]:text-success data-[state=active]:border-success border-b-2 data-[state=active]:shadow-sm",
|
|
58
|
+
className
|
|
59
|
+
),
|
|
60
|
+
...props
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
function TabsContent({ className, ...props }) {
|
|
65
|
+
return /* @__PURE__ */ jsx(
|
|
66
|
+
TabsPrimitive.Content,
|
|
67
|
+
{
|
|
68
|
+
"data-slot": "tabs-content",
|
|
69
|
+
className: cn("focus-visible:outline-none", className),
|
|
70
|
+
...props
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
Tabs
|
|
76
|
+
};
|
package/ui/Tabs/index.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { Copy, CopyCheck, ListChevronsDownUp, ListChevronsUpDown } from "lucide-react";
|
|
4
|
+
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
import { Tooltip } from "../Tooltip/Tooltip.js";
|
|
6
|
+
const TextTruncate = ({
|
|
7
|
+
children,
|
|
8
|
+
lines = 3,
|
|
9
|
+
className,
|
|
10
|
+
textClassName,
|
|
11
|
+
showToggle = true,
|
|
12
|
+
showCopy = true
|
|
13
|
+
}) => {
|
|
14
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
15
|
+
const [copied, setCopied] = useState(false);
|
|
16
|
+
const [needsTruncation, setNeedsTruncation] = useState(false);
|
|
17
|
+
const [hasBeenTruncated, setHasBeenTruncated] = useState(false);
|
|
18
|
+
const contentRef = useRef(null);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const checkTruncation = () => {
|
|
21
|
+
if (contentRef.current) {
|
|
22
|
+
const isTruncated = contentRef.current.scrollHeight > contentRef.current.clientHeight;
|
|
23
|
+
setNeedsTruncation(isTruncated);
|
|
24
|
+
if (isTruncated && !isExpanded) {
|
|
25
|
+
setHasBeenTruncated(true);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
setTimeout(checkTruncation, 0);
|
|
30
|
+
window.addEventListener("resize", checkTruncation);
|
|
31
|
+
return () => window.removeEventListener("resize", checkTruncation);
|
|
32
|
+
}, [children, lines, isExpanded]);
|
|
33
|
+
const toggleExpanded = () => setIsExpanded((prev) => !prev);
|
|
34
|
+
const handleToggle = (e) => {
|
|
35
|
+
e.stopPropagation();
|
|
36
|
+
toggleExpanded();
|
|
37
|
+
};
|
|
38
|
+
const handleCopy = async (e) => {
|
|
39
|
+
e.stopPropagation();
|
|
40
|
+
try {
|
|
41
|
+
const textToCopy = typeof children === "string" ? children : contentRef.current?.textContent || "";
|
|
42
|
+
await navigator.clipboard.writeText(textToCopy);
|
|
43
|
+
setCopied(true);
|
|
44
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
console.error("Failed to copy text:", err);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const handleKeyDown = (e, handler) => {
|
|
50
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
handler(e);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return /* @__PURE__ */ jsx("div", { className: cn("relative flex flex-col", className), children: /* @__PURE__ */ jsxs("div", { className: cn("flex items-start gap-2 break-words", textClassName), children: [
|
|
56
|
+
/* @__PURE__ */ jsx(
|
|
57
|
+
"div",
|
|
58
|
+
{
|
|
59
|
+
ref: contentRef,
|
|
60
|
+
className: "w-full select-text",
|
|
61
|
+
style: isExpanded ? {
|
|
62
|
+
display: "block",
|
|
63
|
+
wordBreak: "break-word",
|
|
64
|
+
whiteSpace: "pre-wrap"
|
|
65
|
+
} : {
|
|
66
|
+
display: "-webkit-box",
|
|
67
|
+
WebkitBoxOrient: "vertical",
|
|
68
|
+
WebkitLineClamp: lines,
|
|
69
|
+
overflow: "hidden"
|
|
70
|
+
},
|
|
71
|
+
children
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
showToggle && hasBeenTruncated || showCopy ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 bg-inherit pl-1", style: { zIndex: 10 }, children: [
|
|
75
|
+
showToggle && hasBeenTruncated && /* @__PURE__ */ jsx(
|
|
76
|
+
"div",
|
|
77
|
+
{
|
|
78
|
+
role: "button",
|
|
79
|
+
tabIndex: 0,
|
|
80
|
+
onClick: handleToggle,
|
|
81
|
+
onKeyDown: (e) => handleKeyDown(e, handleToggle),
|
|
82
|
+
className: cn(
|
|
83
|
+
"text-muted-foreground hover:text-success inline-flex cursor-pointer items-center gap-1 text-xs transition-colors hover:scale-105 active:scale-95"
|
|
84
|
+
),
|
|
85
|
+
children: /* @__PURE__ */ jsx(Tooltip, { content: isExpanded ? "Hide text" : "Show text", children: !needsTruncation && isExpanded ? /* @__PURE__ */ jsx(ListChevronsDownUp, { className: "size-3" }) : /* @__PURE__ */ jsx(ListChevronsUpDown, { className: "size-3" }) })
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
showCopy && /* @__PURE__ */ jsx(
|
|
89
|
+
"div",
|
|
90
|
+
{
|
|
91
|
+
role: "button",
|
|
92
|
+
tabIndex: 0,
|
|
93
|
+
onClick: handleCopy,
|
|
94
|
+
onKeyDown: (e) => handleKeyDown(e, handleCopy),
|
|
95
|
+
className: cn(
|
|
96
|
+
"text-muted-foreground hover:text-success inline-flex cursor-pointer items-center justify-center text-xs transition-colors hover:scale-105 active:scale-95",
|
|
97
|
+
copied && "text-success"
|
|
98
|
+
),
|
|
99
|
+
children: /* @__PURE__ */ jsx(Tooltip, { content: "Copy text", children: copied ? /* @__PURE__ */ jsx(CopyCheck, { className: "size-3" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3" }) })
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
] }) : null
|
|
103
|
+
] }) });
|
|
104
|
+
};
|
|
105
|
+
export {
|
|
106
|
+
TextTruncate
|
|
107
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
function Textarea({ className, ...props }) {
|
|
4
|
+
return /* @__PURE__ */ jsx(
|
|
5
|
+
"textarea",
|
|
6
|
+
{
|
|
7
|
+
"data-slot": "textarea",
|
|
8
|
+
className: cn(
|
|
9
|
+
"border-border bg-secondary placeholder:text-gray-chateau focus-visible:border-ring focus-visible:ring-secondary/50 aria-invalid:ring-destructive/20 aria-invalid:border-destructive flex field-sizing-content min-h-16 w-full rounded-md border px-3 py-2 text-base text-xs shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[2px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
10
|
+
"focus-visible:ring-success/40 focus-visible:border-success focus-visible:ring-[2px]",
|
|
11
|
+
"aria-invalid:ring-critical/40 aria-invalid:border-critical aria-invalid:ring-[2px]",
|
|
12
|
+
className
|
|
13
|
+
),
|
|
14
|
+
...props
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
Textarea
|
|
20
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { applyTheme, useDocumentTheme } from "../../lib/theme.js";
|
|
3
|
+
import { Button } from "../Button/Button.js";
|
|
4
|
+
function ThemeToggle() {
|
|
5
|
+
const theme = useDocumentTheme();
|
|
6
|
+
const next = theme === "dark" ? "light" : "dark";
|
|
7
|
+
return /* @__PURE__ */ jsxs(
|
|
8
|
+
Button,
|
|
9
|
+
{
|
|
10
|
+
onClick: () => applyTheme(next),
|
|
11
|
+
className: "btn btn--secondary px-4",
|
|
12
|
+
"aria-label": "Toggle theme",
|
|
13
|
+
variant: "secondaryOutline",
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ jsx("span", { children: theme === "dark" ? "\u{1F319}" : "\u2600\uFE0F" }),
|
|
16
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: theme === "dark" ? "Dark" : "Light" })
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
ThemeToggle
|
|
23
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useDocumentTheme } from "../../lib/theme.js";
|
|
3
|
+
import { Toaster as Sonner } from "sonner";
|
|
4
|
+
const Toaster = ({ ...props }) => {
|
|
5
|
+
const theme = useDocumentTheme();
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
Sonner,
|
|
8
|
+
{
|
|
9
|
+
theme,
|
|
10
|
+
className: "toaster group",
|
|
11
|
+
expand: true,
|
|
12
|
+
style: {
|
|
13
|
+
"--normal-bg": "var(--bg-secondary)",
|
|
14
|
+
"--normal-text": "var(--text-default)",
|
|
15
|
+
"--normal-border": "var(--border)"
|
|
16
|
+
},
|
|
17
|
+
...props
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
export {
|
|
22
|
+
Toaster
|
|
23
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TooltipContent, TooltipParent, TooltipTrigger } from "./TooltipLayout.js";
|
|
3
|
+
const Tooltip = ({
|
|
4
|
+
children,
|
|
5
|
+
content,
|
|
6
|
+
className,
|
|
7
|
+
classNameArrow,
|
|
8
|
+
...props
|
|
9
|
+
}) => {
|
|
10
|
+
return /* @__PURE__ */ jsxs(TooltipParent, { ...props, children: [
|
|
11
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children }),
|
|
12
|
+
/* @__PURE__ */ jsx(TooltipContent, { className, classNameArrow, children: content })
|
|
13
|
+
] });
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
Tooltip
|
|
17
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
3
|
+
import { cn } from "../../lib/cn.js";
|
|
4
|
+
const TooltipProvider = ({
|
|
5
|
+
delayDuration = 0,
|
|
6
|
+
...props
|
|
7
|
+
}) => {
|
|
8
|
+
return /* @__PURE__ */ jsx(
|
|
9
|
+
TooltipPrimitive.Provider,
|
|
10
|
+
{
|
|
11
|
+
"data-slot": "tooltip-provider",
|
|
12
|
+
delayDuration,
|
|
13
|
+
...props
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
const TooltipParent = ({ ...props }) => {
|
|
18
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props }) });
|
|
19
|
+
};
|
|
20
|
+
const TooltipTrigger = ({ ...props }) => {
|
|
21
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
22
|
+
};
|
|
23
|
+
const TooltipContent = ({
|
|
24
|
+
className,
|
|
25
|
+
classNameArrow,
|
|
26
|
+
sideOffset = 0,
|
|
27
|
+
children,
|
|
28
|
+
...props
|
|
29
|
+
}) => {
|
|
30
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
31
|
+
TooltipPrimitive.Content,
|
|
32
|
+
{
|
|
33
|
+
"data-slot": "tooltip-content",
|
|
34
|
+
sideOffset,
|
|
35
|
+
className: cn(
|
|
36
|
+
"animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 text-default text-2xs bg-tooltip-white text-tooltip-black z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 shadow-md",
|
|
37
|
+
className
|
|
38
|
+
),
|
|
39
|
+
...props,
|
|
40
|
+
children: [
|
|
41
|
+
children,
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
TooltipPrimitive.Arrow,
|
|
44
|
+
{
|
|
45
|
+
className: cn(
|
|
46
|
+
"bg-tooltip-white fill-tooltip-white z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]",
|
|
47
|
+
classNameArrow
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
) });
|
|
54
|
+
};
|
|
55
|
+
export {
|
|
56
|
+
TooltipContent,
|
|
57
|
+
TooltipParent,
|
|
58
|
+
TooltipProvider,
|
|
59
|
+
TooltipTrigger
|
|
60
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Tooltip } from "./Tooltip.js";
|
|
2
|
+
import {
|
|
3
|
+
TooltipContent,
|
|
4
|
+
TooltipParent,
|
|
5
|
+
TooltipProvider,
|
|
6
|
+
TooltipTrigger
|
|
7
|
+
} from "./TooltipLayout.js";
|
|
8
|
+
export {
|
|
9
|
+
Tooltip,
|
|
10
|
+
TooltipContent,
|
|
11
|
+
TooltipParent,
|
|
12
|
+
TooltipProvider,
|
|
13
|
+
TooltipTrigger
|
|
14
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
function TreeGuide({ className, children, ...props }) {
|
|
4
|
+
return /* @__PURE__ */ jsx("div", { className: cn("border-border ml-3 border-l pl-3", className), ...props, children });
|
|
5
|
+
}
|
|
6
|
+
function TreeRow({ className, children, ...props }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(
|
|
8
|
+
"div",
|
|
9
|
+
{
|
|
10
|
+
className: cn(
|
|
11
|
+
"relative flex min-w-0 items-center gap-1",
|
|
12
|
+
"before:bg-border before:absolute before:top-1/2 before:-left-3 before:h-px before:w-3 before:-translate-y-1/2",
|
|
13
|
+
className
|
|
14
|
+
),
|
|
15
|
+
...props,
|
|
16
|
+
children
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
TreeGuide,
|
|
22
|
+
TreeRow
|
|
23
|
+
};
|
package/ui/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export * from "./Accordion/index.js";
|
|
2
|
+
export * from "./AnimatedDots/index.js";
|
|
3
|
+
export * from "./Aside/index.js";
|
|
4
|
+
export * from "./Badge/index.js";
|
|
5
|
+
export * from "./Button/index.js";
|
|
6
|
+
export * from "./Checkbox/index.js";
|
|
7
|
+
export * from "./ConditionalContent/index.js";
|
|
8
|
+
export * from "./DeleteButtonConfirm/index.js";
|
|
9
|
+
export * from "./Dialog/index.js";
|
|
10
|
+
export * from "./Dropdown/index.js";
|
|
11
|
+
export * from "./EmptyState/index.js";
|
|
12
|
+
export * from "./Field/index.js";
|
|
13
|
+
export * from "./HelperText/index.js";
|
|
14
|
+
export * from "./Input/index.js";
|
|
15
|
+
export * from "./InputNumber/index.js";
|
|
16
|
+
export * from "./InputPassword/index.js";
|
|
17
|
+
export * from "./Label/index.js";
|
|
18
|
+
export * from "./MultiSelect/index.js";
|
|
19
|
+
export * from "./PageHeader/index.js";
|
|
20
|
+
export * from "./Pagination/index.js";
|
|
21
|
+
export * from "./RadioGroup/index.js";
|
|
22
|
+
export * from "./ScrollArea/index.js";
|
|
23
|
+
export * from "./SearchInput/index.js";
|
|
24
|
+
export * from "./SearchInputFields/index.js";
|
|
25
|
+
export * from "./Select/index.js";
|
|
26
|
+
export * from "./Separator/index.js";
|
|
27
|
+
export * from "./Skeleton/index.js";
|
|
28
|
+
export * from "./Slider/index.js";
|
|
29
|
+
export * from "./Spinner/index.js";
|
|
30
|
+
export * from "./SpinnerSquare/index.js";
|
|
31
|
+
export * from "./Suggestions/index.js";
|
|
32
|
+
export * from "./Switch/index.js";
|
|
33
|
+
export * from "./Table/index.js";
|
|
34
|
+
export * from "./Tabs/index.js";
|
|
35
|
+
export * from "./TextTruncate/index.js";
|
|
36
|
+
export * from "./Textarea/index.js";
|
|
37
|
+
export * from "./ThemeToggle/index.js";
|
|
38
|
+
export * from "./Toast/index.js";
|
|
39
|
+
export * from "./Tooltip/index.js";
|
|
40
|
+
export * from "./TreeGuide/index.js";
|
|
41
|
+
import { applyTheme, useDocumentTheme } from "../lib/theme.js";
|
|
42
|
+
export {
|
|
43
|
+
applyTheme,
|
|
44
|
+
useDocumentTheme
|
|
45
|
+
};
|