@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.
Files changed (153) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +537 -0
  4. package/attack-flow.d.ts +16 -0
  5. package/charts.d.ts +32 -0
  6. package/decorators/index.js +8 -0
  7. package/decorators/withRouter.js +10 -0
  8. package/decorators/withTheme.js +10 -0
  9. package/decorators.d.ts +10 -0
  10. package/domain.d.ts +23 -0
  11. package/editor.d.ts +25 -0
  12. package/index.d.ts +702 -0
  13. package/lib/cn.js +8 -0
  14. package/lib/theme.js +26 -0
  15. package/lib/useFullscreen.js +52 -0
  16. package/lib/useListenOnResizeDebounce.js +22 -0
  17. package/lib/useThemeColors.js +39 -0
  18. package/package.json +113 -0
  19. package/preset/createConfig.js +98 -0
  20. package/preset/createPreview.js +53 -0
  21. package/preset/index.js +6 -0
  22. package/preset/restoreNativeFocus.js +33 -0
  23. package/preset/types.js +0 -0
  24. package/preset.d.ts +27 -0
  25. package/theme-9m7j1UoI.d.ts +5 -0
  26. package/ui/Accordion/Accordion.js +82 -0
  27. package/ui/Accordion/AccordionSection.js +41 -0
  28. package/ui/Accordion/FolderTreeExpandTrigger.js +29 -0
  29. package/ui/Accordion/chevronVariants.js +31 -0
  30. package/ui/Accordion/index.js +16 -0
  31. package/ui/AnimatedDots/AnimatedDots.js +10 -0
  32. package/ui/AnimatedDots/index.js +4 -0
  33. package/ui/Aside/Aside.js +34 -0
  34. package/ui/Aside/index.js +4 -0
  35. package/ui/AttackFlow/AttackFlow.js +9 -0
  36. package/ui/AttackFlow/AttackFlowLayout.js +63 -0
  37. package/ui/AttackFlow/Controls.js +42 -0
  38. package/ui/AttackFlow/Node.js +47 -0
  39. package/ui/AttackFlow/OtherNode.js +44 -0
  40. package/ui/AttackFlow/index.js +4 -0
  41. package/ui/AttackFlow/prependData.js +153 -0
  42. package/ui/AttackFlow/types.js +0 -0
  43. package/ui/AttackFlow/useAttackFlow.js +193 -0
  44. package/ui/Badge/Badge.js +57 -0
  45. package/ui/Badge/index.js +5 -0
  46. package/ui/Button/Button.css +1 -0
  47. package/ui/Button/Button.js +109 -0
  48. package/ui/Button/index.js +5 -0
  49. package/ui/Charts/AreaChartWithGradient.js +79 -0
  50. package/ui/Charts/index.js +4 -0
  51. package/ui/Checkbox/Checkbox.js +31 -0
  52. package/ui/Checkbox/index.js +4 -0
  53. package/ui/ConditionalContent/ConditionalContent.js +10 -0
  54. package/ui/ConditionalContent/index.js +4 -0
  55. package/ui/CorrelationTimer/CorrelationTimer.js +62 -0
  56. package/ui/CorrelationTimer/index.js +4 -0
  57. package/ui/DeleteButtonConfirm/DeleteButtonConfirm.js +65 -0
  58. package/ui/DeleteButtonConfirm/index.js +4 -0
  59. package/ui/Dialog/ConfirmDialog.js +54 -0
  60. package/ui/Dialog/DefaultDialog.js +82 -0
  61. package/ui/Dialog/Dialog.js +120 -0
  62. package/ui/Dialog/index.js +32 -0
  63. package/ui/Dropdown/Dropdown.js +204 -0
  64. package/ui/Dropdown/DropdownsCheckbox.js +102 -0
  65. package/ui/Dropdown/DropdownsSelect.js +97 -0
  66. package/ui/Dropdown/index.js +38 -0
  67. package/ui/Editor/Editor.js +97 -0
  68. package/ui/Editor/index.js +4 -0
  69. package/ui/Editor/monacoSetup.js +38 -0
  70. package/ui/Editor/theme.js +50 -0
  71. package/ui/Editor/types.js +0 -0
  72. package/ui/EmptyState/EmptyState.js +26 -0
  73. package/ui/EmptyState/index.js +4 -0
  74. package/ui/Field/Field.js +204 -0
  75. package/ui/Field/index.js +24 -0
  76. package/ui/HelperText/HelperText.js +7 -0
  77. package/ui/HelperText/index.js +4 -0
  78. package/ui/Input/Input.js +40 -0
  79. package/ui/Input/index.js +4 -0
  80. package/ui/InputNumber/InputNumber.js +90 -0
  81. package/ui/InputNumber/index.js +4 -0
  82. package/ui/InputPassword/InputPassword.js +30 -0
  83. package/ui/InputPassword/index.js +4 -0
  84. package/ui/Label/Label.js +13 -0
  85. package/ui/Label/LabelInfo.js +14 -0
  86. package/ui/Label/index.js +6 -0
  87. package/ui/MultiSelect/MultiSelect.js +163 -0
  88. package/ui/MultiSelect/index.js +4 -0
  89. package/ui/PageHeader/PageHeader.js +51 -0
  90. package/ui/PageHeader/index.js +4 -0
  91. package/ui/Pagination/Pagination.js +97 -0
  92. package/ui/Pagination/PaginationWrap.js +149 -0
  93. package/ui/Pagination/index.js +20 -0
  94. package/ui/RadioGroup/RadioGroup.js +45 -0
  95. package/ui/RadioGroup/index.js +5 -0
  96. package/ui/ScrollArea/ScrollArea.js +57 -0
  97. package/ui/ScrollArea/index.js +5 -0
  98. package/ui/SearchInput/SearchInput.js +38 -0
  99. package/ui/SearchInput/index.js +4 -0
  100. package/ui/SearchInputFields/SearchInputFields.js +53 -0
  101. package/ui/SearchInputFields/index.js +4 -0
  102. package/ui/Select/Select.js +155 -0
  103. package/ui/Select/SelectDefault.js +43 -0
  104. package/ui/Select/index.js +26 -0
  105. package/ui/Separator/Separator.js +26 -0
  106. package/ui/Separator/index.js +4 -0
  107. package/ui/Severity/Severity.js +11 -0
  108. package/ui/Severity/index.js +4 -0
  109. package/ui/Severity/utils.js +53 -0
  110. package/ui/Skeleton/Skeleton.js +25 -0
  111. package/ui/Skeleton/index.js +5 -0
  112. package/ui/Slider/Slider.js +50 -0
  113. package/ui/Slider/index.js +4 -0
  114. package/ui/Spinner/Spinner.js +21 -0
  115. package/ui/Spinner/index.js +5 -0
  116. package/ui/SpinnerSquare/SpinnerSquare.css +1 -0
  117. package/ui/SpinnerSquare/SpinnerSquare.js +22 -0
  118. package/ui/SpinnerSquare/index.js +4 -0
  119. package/ui/StatisticCard/StatisticCard.js +27 -0
  120. package/ui/StatisticCard/index.js +4 -0
  121. package/ui/StatisticCard/types.js +0 -0
  122. package/ui/Suggestions/Suggestions.js +244 -0
  123. package/ui/Suggestions/index.js +4 -0
  124. package/ui/Switch/Switch.js +64 -0
  125. package/ui/Switch/index.js +4 -0
  126. package/ui/SyncProcessBar/SyncProcessBar.js +14 -0
  127. package/ui/SyncProcessBar/index.js +4 -0
  128. package/ui/Table/GroupHeaderRow.js +36 -0
  129. package/ui/Table/RowGrouped.js +19 -0
  130. package/ui/Table/ServerGroupedTableBody.js +89 -0
  131. package/ui/Table/SortableHeader.js +46 -0
  132. package/ui/Table/Table.js +110 -0
  133. package/ui/Table/TableWrap.js +124 -0
  134. package/ui/Table/columnStyle.js +14 -0
  135. package/ui/Table/index.js +28 -0
  136. package/ui/Tabs/Tabs.js +76 -0
  137. package/ui/Tabs/index.js +4 -0
  138. package/ui/TextTruncate/TextTruncate.js +107 -0
  139. package/ui/TextTruncate/index.js +4 -0
  140. package/ui/Textarea/Textarea.js +20 -0
  141. package/ui/Textarea/index.js +4 -0
  142. package/ui/ThemeToggle/ThemeToggle.js +23 -0
  143. package/ui/ThemeToggle/index.js +4 -0
  144. package/ui/Toast/Toast.js +23 -0
  145. package/ui/Toast/index.js +4 -0
  146. package/ui/Tooltip/Tooltip.js +17 -0
  147. package/ui/Tooltip/TooltipLayout.js +60 -0
  148. package/ui/Tooltip/index.js +14 -0
  149. package/ui/TreeGuide/TreeGuide.js +23 -0
  150. package/ui/TreeGuide/index.js +5 -0
  151. package/ui/entries/charts.js +2 -0
  152. package/ui/entries/domain.js +3 -0
  153. package/ui/index.js +45 -0
@@ -0,0 +1,163 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { ChevronDownIcon, Loader2 } from "lucide-react";
3
+ import { useMemo, useState } from "react";
4
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
5
+ import { Badge } from "../Badge/Badge.js";
6
+ import { Checkbox } from "../Checkbox/Checkbox.js";
7
+ import { SearchInput } from "../SearchInput/SearchInput.js";
8
+ import { ScrollArea } from "../ScrollArea/ScrollArea.js";
9
+ import { cn } from "../../lib/cn.js";
10
+ function MultiSelect({
11
+ loading = false,
12
+ options,
13
+ value = [],
14
+ placeholder = "Select elements...",
15
+ className,
16
+ disabled = false,
17
+ maxDisplay = 3,
18
+ maxSelection,
19
+ searchable = true,
20
+ size = "default",
21
+ dropdownClassName,
22
+ align = "start",
23
+ variant,
24
+ badgeClassNames,
25
+ id,
26
+ name,
27
+ onChange
28
+ }) {
29
+ const [open, setOpen] = useState(false);
30
+ const [searchQuery, setSearchQuery] = useState("");
31
+ const filteredOptions = useMemo(() => {
32
+ if (!searchQuery) return options;
33
+ const query = searchQuery.toLowerCase();
34
+ return options.filter((option) => option.label.toLowerCase().includes(query));
35
+ }, [options, searchQuery]);
36
+ const selectedOptions = useMemo(
37
+ () => options.filter((option) => value.includes(option.value)),
38
+ [options, value]
39
+ );
40
+ const displayedBadges = selectedOptions.slice(0, maxDisplay);
41
+ const remainingCount = selectedOptions.length - maxDisplay;
42
+ const isMaxReached = maxSelection !== void 0 && value.length >= maxSelection;
43
+ const handleToggle = (optionValue) => {
44
+ const isSelected = value.includes(optionValue);
45
+ if (isSelected) {
46
+ onChange(value.filter((v) => v !== optionValue));
47
+ return;
48
+ }
49
+ if (isMaxReached) return;
50
+ onChange([...value, optionValue]);
51
+ };
52
+ const handleRemove = (optionValue) => {
53
+ onChange(value.filter((v) => v !== optionValue));
54
+ };
55
+ const renderSelectedBadges = () => {
56
+ if (selectedOptions.length === 0) {
57
+ return /* @__PURE__ */ jsx("span", { className: "text-gray-chateau", children: placeholder });
58
+ }
59
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
60
+ displayedBadges.map((option) => /* @__PURE__ */ jsx(
61
+ Badge,
62
+ {
63
+ className: badgeClassNames,
64
+ variant: variant || option.badgeVariant,
65
+ onRemove: () => handleRemove(option.value),
66
+ children: option.label
67
+ },
68
+ option.value
69
+ )),
70
+ remainingCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "outline", children: [
71
+ "+",
72
+ remainingCount
73
+ ] })
74
+ ] });
75
+ };
76
+ const renderOptionItem = (option) => {
77
+ const isSelected = value.includes(option.value);
78
+ const isDisabled = option.disabled || !isSelected && isMaxReached;
79
+ return /* @__PURE__ */ jsxs(
80
+ "label",
81
+ {
82
+ className: cn(
83
+ "flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-xs transition-colors",
84
+ "hover:bg-hover focus:bg-hover focus:text-default",
85
+ isSelected && "bg-hover",
86
+ isDisabled && "cursor-not-allowed opacity-50"
87
+ ),
88
+ children: [
89
+ /* @__PURE__ */ jsx(
90
+ Checkbox,
91
+ {
92
+ checked: isSelected,
93
+ onCheckedChange: () => handleToggle(option.value),
94
+ disabled: isDisabled
95
+ }
96
+ ),
97
+ /* @__PURE__ */ jsxs("span", { className: "flex flex-1 items-center gap-2", children: [
98
+ option.label,
99
+ option.typeLabel && /* @__PURE__ */ jsx(Badge, { variant: option.badgeVariant, className: "text-2xs", children: option.typeLabel })
100
+ ] })
101
+ ]
102
+ },
103
+ option.value
104
+ );
105
+ };
106
+ return /* @__PURE__ */ jsxs(PopoverPrimitive.Root, { open, onOpenChange: setOpen, children: [
107
+ /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
108
+ "button",
109
+ {
110
+ type: "button",
111
+ id,
112
+ name,
113
+ disabled,
114
+ "data-size": size,
115
+ "data-state": open ? "open" : "closed",
116
+ className: cn(
117
+ 'border-border bg-secondary data-[placeholder]:text-gray-chateau [&_svg:not([class*="text-"])]:text-gray-chateau flex min-h-9 w-full items-center justify-between gap-2 rounded-md border px-3 py-1 text-xs font-normal transition-[color,box-shadow] outline-none',
118
+ "focus-visible:border-success focus-visible:ring-success/40 focus-visible:ring-[2px]",
119
+ "data-[state=open]:border-success data-[state=open]:ring-success/40 data-[state=open]:ring-[2px]",
120
+ "disabled:cursor-not-allowed disabled:opacity-50",
121
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0",
122
+ className
123
+ ),
124
+ children: [
125
+ /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-wrap items-center gap-1", children: renderSelectedBadges() }),
126
+ loading ? /* @__PURE__ */ jsx(Loader2, { className: "text-gray-chateau size-4 animate-spin" }) : /* @__PURE__ */ jsx(ChevronDownIcon, { className: "ml-2 size-4 shrink-0 opacity-50" })
127
+ ]
128
+ }
129
+ ) }),
130
+ /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
131
+ PopoverPrimitive.Content,
132
+ {
133
+ align,
134
+ sideOffset: 4,
135
+ className: cn(
136
+ "bg-secondary border-border text-foreground z-50 rounded-md border shadow-md outline-none",
137
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
138
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
139
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
140
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
141
+ "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
142
+ dropdownClassName
143
+ ),
144
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 p-3", children: [
145
+ searchable && /* @__PURE__ */ jsx(
146
+ SearchInput,
147
+ {
148
+ className: "w-full text-xs",
149
+ classNamesInput: "h-10",
150
+ value: searchQuery,
151
+ onChange: (e) => setSearchQuery(e.target.value),
152
+ placeholder: "Search..."
153
+ }
154
+ ),
155
+ /* @__PURE__ */ jsx(ScrollArea, { children: /* @__PURE__ */ jsx("div", { className: "flex max-h-64 flex-col gap-2", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-gray-chateau py-6 text-center text-xs", children: "Nothing found" }) : filteredOptions.map(renderOptionItem) }) })
156
+ ] })
157
+ }
158
+ ) })
159
+ ] });
160
+ }
161
+ export {
162
+ MultiSelect
163
+ };
@@ -0,0 +1,4 @@
1
+ import { MultiSelect } from "./MultiSelect.js";
2
+ export {
3
+ MultiSelect
4
+ };
@@ -0,0 +1,51 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { ArrowLeft } from "lucide-react";
3
+ import { Link } from "react-router-dom";
4
+ import { cn } from "../../lib/cn.js";
5
+ import { Button } from "../Button/Button.js";
6
+ import { ConditionalContent } from "../ConditionalContent/ConditionalContent.js";
7
+ import { Skeleton } from "../Skeleton/Skeleton.js";
8
+ const PageHeader = ({
9
+ loading,
10
+ title,
11
+ titleIcon,
12
+ backLink,
13
+ description,
14
+ descriptionSize = "md",
15
+ className,
16
+ titleClassName,
17
+ children
18
+ }) => {
19
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-6 max-lg:flex-wrap", className), children: [
20
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
21
+ backLink && /* @__PURE__ */ jsx(Link, { to: backLink, children: /* @__PURE__ */ jsx(Button, { variant: "icon", size: "xs", children: /* @__PURE__ */ jsx(ArrowLeft, { size: 20 }) }) }),
22
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1", children: [
23
+ /* @__PURE__ */ jsx(
24
+ ConditionalContent,
25
+ {
26
+ loading: !!loading,
27
+ loadingContent: /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-64" }),
28
+ loadedContent: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
29
+ titleIcon && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: titleIcon }),
30
+ /* @__PURE__ */ jsx("h2", { className: cn("text-default text-xl font-medium break-all", titleClassName), children: title })
31
+ ] })
32
+ }
33
+ ),
34
+ description && /* @__PURE__ */ jsx(
35
+ "div",
36
+ {
37
+ className: cn(
38
+ "text-gray-chateau break-all",
39
+ descriptionSize === "sm" ? "text-2xs" : "text-sm"
40
+ ),
41
+ children: description
42
+ }
43
+ )
44
+ ] })
45
+ ] }),
46
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", children })
47
+ ] });
48
+ };
49
+ export {
50
+ PageHeader
51
+ };
@@ -0,0 +1,4 @@
1
+ import { PageHeader } from "./PageHeader.js";
2
+ export {
3
+ PageHeader
4
+ };
@@ -0,0 +1,97 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/cn.js";
3
+ import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from "lucide-react";
4
+ function Pagination({ className, ...props }) {
5
+ return /* @__PURE__ */ jsx(
6
+ "nav",
7
+ {
8
+ role: "navigation",
9
+ "aria-label": "pagination",
10
+ "data-slot": "pagination",
11
+ className: cn("mx-auto flex w-full justify-center", className),
12
+ ...props
13
+ }
14
+ );
15
+ }
16
+ function PaginationContent({ className, ...props }) {
17
+ return /* @__PURE__ */ jsx(
18
+ "ul",
19
+ {
20
+ "data-slot": "pagination-content",
21
+ className: cn("flex flex-row items-center gap-1", className),
22
+ ...props
23
+ }
24
+ );
25
+ }
26
+ function PaginationItem({ ...props }) {
27
+ return /* @__PURE__ */ jsx("li", { "data-slot": "pagination-item", ...props });
28
+ }
29
+ function PaginationLink({ className, isActive, ...props }) {
30
+ return /* @__PURE__ */ jsx(
31
+ "a",
32
+ {
33
+ "aria-current": isActive ? "page" : void 0,
34
+ "data-slot": "pagination-link",
35
+ "data-active": isActive,
36
+ className: cn(
37
+ "hover:bg-hover flex items-center justify-center rounded-sm border border-transparent",
38
+ className
39
+ ),
40
+ ...props
41
+ }
42
+ );
43
+ }
44
+ function PaginationPrevious({ className, ...props }) {
45
+ return /* @__PURE__ */ jsxs(
46
+ PaginationLink,
47
+ {
48
+ "aria-label": "Go to previous page",
49
+ size: "s",
50
+ className: cn("gap-1 px-2.5 sm:pl-2.5", className),
51
+ ...props,
52
+ children: [
53
+ /* @__PURE__ */ jsx(ChevronLeftIcon, {}),
54
+ /* @__PURE__ */ jsx("span", { className: "hidden md:block", children: "Previous" })
55
+ ]
56
+ }
57
+ );
58
+ }
59
+ function PaginationNext({ className, ...props }) {
60
+ return /* @__PURE__ */ jsxs(
61
+ PaginationLink,
62
+ {
63
+ "aria-label": "Go to next page",
64
+ size: "s",
65
+ className: cn("gap-1 px-2.5 sm:pr-2.5", className),
66
+ ...props,
67
+ children: [
68
+ /* @__PURE__ */ jsx("span", { className: "hidden md:block", children: "Next" }),
69
+ /* @__PURE__ */ jsx(ChevronRightIcon, {})
70
+ ]
71
+ }
72
+ );
73
+ }
74
+ function PaginationEllipsis({ className, ...props }) {
75
+ return /* @__PURE__ */ jsxs(
76
+ "span",
77
+ {
78
+ "aria-hidden": true,
79
+ "data-slot": "pagination-ellipsis",
80
+ className: cn("flex size-9 items-center justify-center", className),
81
+ ...props,
82
+ children: [
83
+ /* @__PURE__ */ jsx(MoreHorizontalIcon, { className: "size-4" }),
84
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "More pages" })
85
+ ]
86
+ }
87
+ );
88
+ }
89
+ export {
90
+ Pagination,
91
+ PaginationContent,
92
+ PaginationEllipsis,
93
+ PaginationItem,
94
+ PaginationLink,
95
+ PaginationNext,
96
+ PaginationPrevious
97
+ };
@@ -0,0 +1,149 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useState } from "react";
3
+ import { Button } from "../Button/Button.js";
4
+ import { Input } from "../Input/Input.js";
5
+ import { SelectDefault } from "../Select/SelectDefault.js";
6
+ import {
7
+ Pagination,
8
+ PaginationContent,
9
+ PaginationEllipsis,
10
+ PaginationItem,
11
+ PaginationLink,
12
+ PaginationNext,
13
+ PaginationPrevious
14
+ } from "./Pagination.js";
15
+ const perPageOptions = [
16
+ { label: "10", value: "10" },
17
+ { label: "25", value: "25" },
18
+ { label: "50", value: "50" },
19
+ { label: "100", value: "100" }
20
+ ];
21
+ const PaginationWrap = ({
22
+ page,
23
+ totalPages,
24
+ limit = 25,
25
+ maxVisible = 5,
26
+ optionsPerPage,
27
+ onPageChange,
28
+ setLimit = () => {
29
+ }
30
+ }) => {
31
+ const [pageGo, setPageGo] = useState(null);
32
+ const pageNumbers = useMemo(() => {
33
+ const pages = [];
34
+ if (totalPages <= maxVisible) {
35
+ for (let i = 1; i <= totalPages; i++) {
36
+ pages.push(i);
37
+ }
38
+ } else if (page <= 3) {
39
+ for (let i = 1; i <= 4; i++) {
40
+ pages.push(i);
41
+ }
42
+ pages.push(-1);
43
+ pages.push(totalPages);
44
+ } else if (page >= totalPages - 2) {
45
+ pages.push(1);
46
+ pages.push(-1);
47
+ for (let i = totalPages - 3; i <= totalPages; i++) {
48
+ pages.push(i);
49
+ }
50
+ } else {
51
+ pages.push(1);
52
+ pages.push(-1);
53
+ for (let i = page - 1; i <= page + 1; i++) {
54
+ pages.push(i);
55
+ }
56
+ pages.push(-1);
57
+ pages.push(totalPages);
58
+ }
59
+ return pages;
60
+ }, [page, totalPages, maxVisible]);
61
+ const onPageGoClick = () => {
62
+ onPageChange(Number(pageGo));
63
+ setPageGo(null);
64
+ };
65
+ const limitItemChange = (value) => {
66
+ setLimit(Number(value));
67
+ setPageGo(null);
68
+ };
69
+ const previousPageClick = () => {
70
+ onPageChange(Math.max(1, page - 1));
71
+ setPageGo(null);
72
+ };
73
+ const nextPageClick = () => {
74
+ onPageChange(Math.min(totalPages, page + 1));
75
+ setPageGo(null);
76
+ };
77
+ const pageClick = (page2) => {
78
+ onPageChange(page2);
79
+ setPageGo(null);
80
+ };
81
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 xl:flex-nowrap", children: [
82
+ /* @__PURE__ */ jsxs("div", { className: "order-2 flex items-center gap-2 xl:order-1", children: [
83
+ /* @__PURE__ */ jsx("div", { className: "text-gray-chateau hidden text-xs whitespace-nowrap lg:flex", children: "Items per page:" }),
84
+ /* @__PURE__ */ jsx(
85
+ SelectDefault,
86
+ {
87
+ className: "h-8 text-xs",
88
+ options: optionsPerPage || perPageOptions,
89
+ value: limit.toString(),
90
+ placeholder: "Select items per page",
91
+ onChange: limitItemChange
92
+ }
93
+ )
94
+ ] }),
95
+ /* @__PURE__ */ jsx(Pagination, { className: "order-1 xl:order-2", children: /* @__PURE__ */ jsxs(PaginationContent, { children: [
96
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
97
+ PaginationPrevious,
98
+ {
99
+ onClick: previousPageClick,
100
+ className: `h-8 text-xs ${page === 1 ? "pointer-events-none opacity-50" : "cursor-pointer"}`
101
+ }
102
+ ) }),
103
+ pageNumbers.map((pageNum, idx) => /* @__PURE__ */ jsx(PaginationItem, { children: pageNum === -1 ? /* @__PURE__ */ jsx(PaginationEllipsis, {}) : /* @__PURE__ */ jsx(
104
+ PaginationLink,
105
+ {
106
+ className: `h-8 w-8 cursor-pointer text-xs ${page === pageNum ? "border-border" : ""}`,
107
+ onClick: () => pageClick(pageNum),
108
+ isActive: page === pageNum,
109
+ children: pageNum
110
+ }
111
+ ) }, idx)),
112
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
113
+ PaginationNext,
114
+ {
115
+ onClick: nextPageClick,
116
+ className: `h-8 text-xs ${page === totalPages || totalPages === 0 ? "pointer-events-none opacity-50" : "cursor-pointer"}`
117
+ }
118
+ ) })
119
+ ] }) }),
120
+ /* @__PURE__ */ jsxs("div", { className: "order-3 flex items-center gap-3 xl:order-2", children: [
121
+ /* @__PURE__ */ jsx("div", { className: "text-gray-chateau hidden text-xs whitespace-nowrap lg:flex", children: "Go to:" }),
122
+ /* @__PURE__ */ jsx(
123
+ Input,
124
+ {
125
+ className: "h-8 w-13 px-2 text-xs",
126
+ type: "text",
127
+ value: pageGo ?? "",
128
+ placeholder: "Page",
129
+ pattern: "^[0-9]*$",
130
+ onChange: (e) => setPageGo(Number(e.target.value) || null)
131
+ }
132
+ ),
133
+ /* @__PURE__ */ jsx(
134
+ Button,
135
+ {
136
+ className: "px-2 text-xs",
137
+ size: "s",
138
+ variant: "secondary",
139
+ disabled: pageGo !== null ? !(pageGo > 0 && pageGo <= totalPages) : true,
140
+ onClick: onPageGoClick,
141
+ children: "Go"
142
+ }
143
+ )
144
+ ] })
145
+ ] });
146
+ };
147
+ export {
148
+ PaginationWrap
149
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ Pagination as Pagination2,
3
+ PaginationContent as PaginationContent2,
4
+ PaginationEllipsis as PaginationEllipsis2,
5
+ PaginationItem as PaginationItem2,
6
+ PaginationLink,
7
+ PaginationNext as PaginationNext2,
8
+ PaginationPrevious as PaginationPrevious2
9
+ } from "./Pagination.js";
10
+ import { PaginationWrap } from "./PaginationWrap.js";
11
+ export {
12
+ Pagination2 as Pagination,
13
+ PaginationContent2 as PaginationContent,
14
+ PaginationEllipsis2 as PaginationEllipsis,
15
+ PaginationItem2 as PaginationItem,
16
+ PaginationLink,
17
+ PaginationNext2 as PaginationNext,
18
+ PaginationPrevious2 as PaginationPrevious,
19
+ PaginationWrap
20
+ };
@@ -0,0 +1,45 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import {
3
+ Indicator as RadioGroupIndicatorPrimitive,
4
+ Item as RadioGroupItemPrimitive,
5
+ Root as RadioGroupPrimitive
6
+ } from "@radix-ui/react-radio-group";
7
+ import { cn } from "../../lib/cn.js";
8
+ function RadioGroup({ className, ...props }) {
9
+ return /* @__PURE__ */ jsx(
10
+ RadioGroupPrimitive,
11
+ {
12
+ "data-slot": "radio-group",
13
+ className: cn("grid w-full gap-2", className),
14
+ ...props
15
+ }
16
+ );
17
+ }
18
+ function RadioGroupItem({
19
+ className,
20
+ ...props
21
+ }) {
22
+ return /* @__PURE__ */ jsx(
23
+ RadioGroupItemPrimitive,
24
+ {
25
+ "data-slot": "radio-group-item",
26
+ className: cn(
27
+ "group/radio-group-item peer border-border bg-secondary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-critical aria-invalid:ring-critical/20 aria-invalid:data-[state=checked]:border-success dark:bg-secondary/30 dark:aria-invalid:border-critical/50 dark:aria-invalid:ring-critical/40 data-[state=checked]:border-success data-[state=checked]:bg-success data-[state=checked]:text-foreground dark:data-[state=checked]:bg-secondary relative flex aspect-square size-4 shrink-0 rounded-full border outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-[3px]",
28
+ className
29
+ ),
30
+ ...props,
31
+ children: /* @__PURE__ */ jsx(
32
+ RadioGroupIndicatorPrimitive,
33
+ {
34
+ "data-slot": "radio-group-indicator",
35
+ className: "flex size-4 items-center justify-center",
36
+ children: /* @__PURE__ */ jsx("span", { className: "bg-success absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full" })
37
+ }
38
+ )
39
+ }
40
+ );
41
+ }
42
+ export {
43
+ RadioGroup,
44
+ RadioGroupItem
45
+ };
@@ -0,0 +1,5 @@
1
+ import { RadioGroup as RadioGroup2, RadioGroupItem as RadioGroupItem2 } from "./RadioGroup.js";
2
+ export {
3
+ RadioGroup2 as RadioGroup,
4
+ RadioGroupItem2 as RadioGroupItem
5
+ };
@@ -0,0 +1,57 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3
+ import { cn } from "../../lib/cn.js";
4
+ function ScrollArea({ className, children, orientation = "vertical", ...props }) {
5
+ return /* @__PURE__ */ jsxs(
6
+ ScrollAreaPrimitive.Root,
7
+ {
8
+ "data-slot": "scroll-area",
9
+ className: cn("relative flex min-h-0 flex-col overflow-hidden", className),
10
+ ...props,
11
+ children: [
12
+ /* @__PURE__ */ jsx(
13
+ ScrollAreaPrimitive.Viewport,
14
+ {
15
+ "data-slot": "scroll-area-viewport",
16
+ className: "focus-visible:ring-ring/50 h-0 min-h-0 w-full flex-1 rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&>div]:!block",
17
+ children
18
+ }
19
+ ),
20
+ (orientation === "vertical" || orientation === "both") && /* @__PURE__ */ jsx(ScrollBar, { orientation: "vertical" }),
21
+ (orientation === "horizontal" || orientation === "both") && /* @__PURE__ */ jsx(ScrollBar, { orientation: "horizontal" }),
22
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
23
+ ]
24
+ }
25
+ );
26
+ }
27
+ function ScrollBar({
28
+ className,
29
+ orientation = "vertical",
30
+ ...props
31
+ }) {
32
+ return /* @__PURE__ */ jsx(
33
+ ScrollAreaPrimitive.ScrollAreaScrollbar,
34
+ {
35
+ "data-slot": "scroll-area-scrollbar",
36
+ orientation,
37
+ className: cn(
38
+ "flex touch-none p-px transition-colors select-none",
39
+ orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
40
+ orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
41
+ className
42
+ ),
43
+ ...props,
44
+ children: /* @__PURE__ */ jsx(
45
+ ScrollAreaPrimitive.ScrollAreaThumb,
46
+ {
47
+ "data-slot": "scroll-area-thumb",
48
+ className: "bg-border relative flex-1 rounded-full"
49
+ }
50
+ )
51
+ }
52
+ );
53
+ }
54
+ export {
55
+ ScrollArea,
56
+ ScrollBar
57
+ };
@@ -0,0 +1,5 @@
1
+ import { ScrollArea, ScrollBar } from "./ScrollArea.js";
2
+ export {
3
+ ScrollArea,
4
+ ScrollBar
5
+ };
@@ -0,0 +1,38 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/cn.js";
3
+ import { SearchIcon, XIcon } from "lucide-react";
4
+ import { Input } from "../Input/Input.js";
5
+ const SearchInput = ({
6
+ className,
7
+ classNamesInput,
8
+ value,
9
+ placeholder,
10
+ onChange,
11
+ ...props
12
+ }) => {
13
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
14
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute top-1/2 left-2 flex size-4 -translate-y-[60%] items-center", children: /* @__PURE__ */ jsx(SearchIcon, { className: "text-subdued h-4 w-4" }) }),
15
+ /* @__PURE__ */ jsx(
16
+ Input,
17
+ {
18
+ type: "text",
19
+ className: cn("px-7", classNamesInput),
20
+ placeholder: placeholder || "Search...",
21
+ ...props,
22
+ value,
23
+ onChange
24
+ }
25
+ ),
26
+ value && /* @__PURE__ */ jsx(
27
+ "button",
28
+ {
29
+ className: "absolute inset-y-0 right-2 flex cursor-pointer items-center",
30
+ onClick: () => onChange?.({ target: { value: "" } }),
31
+ children: /* @__PURE__ */ jsx(XIcon, { className: "text-subdued hover:text-foreground h-4 w-4" })
32
+ }
33
+ )
34
+ ] });
35
+ };
36
+ export {
37
+ SearchInput
38
+ };
@@ -0,0 +1,4 @@
1
+ import { SearchInput } from "./SearchInput.js";
2
+ export {
3
+ SearchInput
4
+ };