uibee 3.2.0 → 3.3.1
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/components/alert/alert.d.ts +15 -0
- package/dist/components/alert/alert.js +29 -0
- package/dist/components/badge/badge.d.ts +16 -0
- package/dist/components/badge/badge.js +26 -0
- package/dist/components/buttons/button.d.ts +25 -0
- package/dist/components/buttons/button.js +44 -0
- package/dist/components/code/code.d.ts +23 -0
- package/dist/components/code/code.js +39 -0
- package/dist/components/confirm/confirmPopup.d.ts +23 -0
- package/dist/components/confirm/confirmPopup.js +52 -0
- package/dist/components/container/accordion.d.ts +25 -0
- package/dist/components/container/accordion.js +41 -0
- package/dist/components/container/card.d.ts +13 -0
- package/dist/components/container/card.js +10 -0
- package/dist/components/container/expandableCard.d.ts +32 -0
- package/dist/components/container/expandableCard.js +70 -0
- package/dist/components/container/glassCard.d.ts +13 -0
- package/dist/components/container/glassCard.js +10 -0
- package/dist/components/container/highlight.d.ts +10 -0
- package/dist/components/container/highlight.js +10 -0
- package/dist/components/container/iconBubble.d.ts +25 -0
- package/dist/components/container/iconBubble.js +21 -0
- package/dist/components/container/leftBarPanel.d.ts +15 -0
- package/dist/components/container/leftBarPanel.js +10 -0
- package/dist/components/container/page.d.ts +15 -0
- package/dist/components/container/page.js +16 -0
- package/dist/components/container/pulseDot.d.ts +12 -0
- package/dist/components/container/pulseDot.js +23 -0
- package/dist/components/container/statCard.d.ts +18 -0
- package/dist/components/container/statCard.js +25 -0
- package/dist/components/container/tabs.d.ts +35 -0
- package/dist/components/container/tabs.js +36 -0
- package/dist/components/empty/emptyState.d.ts +19 -0
- package/dist/components/empty/emptyState.js +27 -0
- package/dist/components/footer/footer.d.ts +49 -0
- package/dist/components/footer/footer.js +109 -0
- package/dist/components/footer/loginContent.d.ts +18 -0
- package/dist/components/footer/loginContent.js +138 -0
- package/dist/components/inputs/checkbox.d.ts +20 -0
- package/dist/components/inputs/checkbox.js +76 -0
- package/dist/components/inputs/fileInput.d.ts +19 -0
- package/dist/components/inputs/fileInput.js +108 -0
- package/dist/components/inputs/input.d.ts +16 -0
- package/dist/components/inputs/input.js +157 -0
- package/dist/components/inputs/multiSelect.d.ts +37 -0
- package/dist/components/inputs/multiSelect.js +99 -0
- package/dist/components/inputs/radio.d.ts +20 -0
- package/dist/components/inputs/radio.js +70 -0
- package/dist/components/inputs/range.d.ts +14 -0
- package/dist/components/inputs/range.js +60 -0
- package/dist/components/inputs/searchInput.d.ts +11 -0
- package/dist/components/inputs/searchInput.js +56 -0
- package/dist/components/inputs/select.d.ts +42 -0
- package/dist/components/inputs/select.js +164 -0
- package/dist/components/inputs/shared/colorPickerPopup.js +293 -0
- package/dist/components/inputs/shared/dateTimePickerPopup.js +225 -0
- package/dist/components/inputs/shared/fieldWrapper.js +33 -0
- package/dist/components/inputs/shared/index.js +6 -0
- package/dist/components/inputs/shared/inputError.js +17 -0
- package/dist/components/inputs/shared/inputInfo.js +13 -0
- package/dist/components/inputs/shared/inputLabel.js +19 -0
- package/dist/components/inputs/switch.d.ts +14 -0
- package/dist/components/inputs/switch.js +37 -0
- package/dist/components/inputs/tagInput.d.ts +31 -0
- package/dist/components/inputs/tagInput.js +72 -0
- package/dist/components/inputs/textarea.d.ts +14 -0
- package/dist/components/inputs/textarea.js +76 -0
- package/dist/components/inputs/toggle.d.ts +21 -0
- package/dist/components/inputs/toggle.js +33 -0
- package/dist/components/login/loginPage.d.ts +15 -0
- package/dist/components/login/loginPage.js +80 -0
- package/dist/components/logo/logo.d.ts +9 -0
- package/dist/components/logo/logo.js +138 -0
- package/dist/components/logo/logoSmall.d.ts +4 -0
- package/dist/components/logo/logoSmall.js +56 -0
- package/dist/components/markdownrender/markdownRender.d.ts +16 -0
- package/dist/components/markdownrender/markdownRender.js +59 -0
- package/dist/components/modal/modal.d.ts +22 -0
- package/dist/components/modal/modal.js +59 -0
- package/dist/components/navbar/bubble.js +36 -0
- package/dist/components/navbar/navbar.d.ts +50 -0
- package/dist/components/navbar/navbar.js +99 -0
- package/dist/components/navbar/navbarDropdown.d.ts +15 -0
- package/dist/components/navbar/navbarDropdown.js +63 -0
- package/dist/components/navbar/navbarItem.d.ts +23 -0
- package/dist/components/navbar/navbarItem.js +38 -0
- package/dist/components/sidebar/sidebar.d.ts +34 -0
- package/dist/components/sidebar/sidebar.js +135 -0
- package/dist/components/spinner/spinner.d.ts +11 -0
- package/dist/components/spinner/spinner.js +16 -0
- package/dist/components/table/body.js +253 -0
- package/dist/components/table/constants.js +58 -0
- package/dist/components/table/empty.js +24 -0
- package/dist/components/table/format.js +39 -0
- package/dist/components/table/header.js +109 -0
- package/dist/components/table/menu.d.ts +18 -0
- package/dist/components/table/menu.js +76 -0
- package/dist/components/table/pagination.d.ts +14 -0
- package/dist/components/table/pagination.js +130 -0
- package/dist/components/table/skeleton.js +39 -0
- package/dist/components/table/table.d.ts +7 -0
- package/dist/components/table/table.js +213 -0
- package/dist/components/table/types.d.ts +52 -0
- package/dist/components/table/utils.js +9 -0
- package/dist/components/toast/toastItem.js +61 -0
- package/dist/components/toast/toaster.d.ts +13 -0
- package/dist/components/toast/toaster.js +117 -0
- package/dist/components/toggle/language.d.ts +10 -0
- package/dist/components/toggle/language.js +34 -0
- package/dist/components/toggle/theme.d.ts +8 -0
- package/dist/components/toggle/theme.js +135 -0
- package/dist/components/version/version.d.ts +13 -0
- package/dist/components/version/version.js +19 -0
- package/dist/components/vulnerability/constants.d.ts +4 -0
- package/dist/components/vulnerability/constants.js +17 -0
- package/dist/components/vulnerability/severityPill.d.ts +15 -0
- package/dist/components/vulnerability/severityPill.js +20 -0
- package/dist/{style.css → globals.css} +155 -226
- package/dist/hooks/useClickOutside.d.ts +6 -0
- package/dist/{useClickOutside-Cmp-RsP3.js → hooks/useClickOutside.js} +1 -1
- package/dist/hooks/useDarkMode.d.ts +4 -0
- package/dist/hooks/useDarkMode.js +19 -0
- package/dist/hooks/useVisibility.d.ts +7 -0
- package/dist/hooks/useVisibility.js +25 -0
- package/dist/icons/icons.d.ts +420 -0
- package/dist/{icons-lZYQ6Vlr.js → icons/icons.js} +1 -1
- package/dist/src/components/index.d.ts +51 -901
- package/dist/src/components/index.js +49 -4160
- package/dist/src/hooks/index.d.ts +3 -14
- package/dist/src/hooks/index.js +3 -42
- package/dist/src/icons/index.d.ts +1 -419
- package/dist/src/icons/index.js +1 -1
- package/dist/src/styles/index.js +1 -1
- package/dist/src/utils/index.d.ts +5 -37
- package/dist/src/utils/index.js +5 -124
- package/dist/utils/auth/callback.d.ts +14 -0
- package/dist/utils/auth/callback.js +53 -0
- package/dist/utils/auth/getDomain.js +6 -0
- package/dist/utils/auth/login.d.ts +12 -0
- package/dist/utils/auth/login.js +17 -0
- package/dist/utils/auth/logout.d.ts +10 -0
- package/dist/utils/auth/logout.js +20 -0
- package/dist/utils/auth/token.d.ts +10 -0
- package/dist/utils/auth/token.js +30 -0
- package/dist/utils/logoConsoleOutput/logoConsoleOutput.d.ts +4 -0
- package/dist/utils/logoConsoleOutput/logoConsoleOutput.js +11 -0
- package/package.json +1 -1
- package/src/components/buttons/button.tsx +2 -0
- package/src/components/footer/footer.tsx +65 -28
- package/src/components/index.ts +0 -1
- package/src/components/inputs/checkbox.tsx +2 -0
- package/src/components/inputs/input.tsx +2 -0
- package/src/components/inputs/radio.tsx +2 -0
- package/src/components/inputs/range.tsx +2 -0
- package/src/components/inputs/shared/colorPickerPopup.tsx +2 -0
- package/src/components/inputs/shared/dateTimePickerPopup.tsx +2 -0
- package/src/components/inputs/textarea.tsx +2 -0
- package/src/components/inputs/toggle.tsx +2 -0
- package/src/components/sidebar/sidebar.tsx +37 -10
- package/src/components/toast/toastItem.tsx +2 -0
- package/src/globals.css +6 -1
- package/tsdown.config.ts +1 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//#region src/components/inputs/select.d.ts
|
|
2
|
+
type Option = {
|
|
3
|
+
value: string | number;
|
|
4
|
+
label: string;
|
|
5
|
+
image?: string;
|
|
6
|
+
};
|
|
7
|
+
type SelectProps = {
|
|
8
|
+
label?: string;
|
|
9
|
+
name: string;
|
|
10
|
+
value?: string | number | null;
|
|
11
|
+
onChange?: (value: string | number | null) => void;
|
|
12
|
+
options: Option[];
|
|
13
|
+
error?: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
required?: boolean;
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
info?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
clearable?: boolean;
|
|
21
|
+
searchable?: boolean;
|
|
22
|
+
textSize?: 'sm' | 'md';
|
|
23
|
+
};
|
|
24
|
+
declare function Select({
|
|
25
|
+
label,
|
|
26
|
+
name,
|
|
27
|
+
value,
|
|
28
|
+
onChange,
|
|
29
|
+
options,
|
|
30
|
+
error,
|
|
31
|
+
className,
|
|
32
|
+
disabled,
|
|
33
|
+
required,
|
|
34
|
+
placeholder,
|
|
35
|
+
info,
|
|
36
|
+
description,
|
|
37
|
+
clearable,
|
|
38
|
+
searchable,
|
|
39
|
+
textSize
|
|
40
|
+
}: SelectProps): import("react").JSX.Element;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { Option, SelectProps, Select as default };
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import FieldWrapper from "./shared/fieldWrapper.js";
|
|
3
|
+
import "./shared/index.js";
|
|
4
|
+
import useClickOutside from "../../hooks/useClickOutside.js";
|
|
5
|
+
import { useEffect, useRef, useState } from "react";
|
|
6
|
+
import { ChevronDown, Search, X } from "lucide-react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import Image from "next/image.js";
|
|
9
|
+
//#region src/components/inputs/select.tsx
|
|
10
|
+
function Select({ label, name, value, onChange, options, error, className, disabled, required, placeholder = "Select an option", info, description, clearable = true, searchable = true, textSize = "sm" }) {
|
|
11
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
12
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
13
|
+
const [selectedOption, setSelectedOption] = useState(options.find((opt) => opt.value === value));
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!isOpen) setSearchTerm("");
|
|
16
|
+
}, [isOpen]);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setSelectedOption(options.find((opt) => opt.value === value));
|
|
19
|
+
}, [value, options]);
|
|
20
|
+
const containerRef = useRef(null);
|
|
21
|
+
useClickOutside(containerRef, () => setIsOpen(false));
|
|
22
|
+
function handleSelect(option) {
|
|
23
|
+
if (disabled) return;
|
|
24
|
+
setSelectedOption(option);
|
|
25
|
+
setIsOpen(false);
|
|
26
|
+
if (onChange) onChange(option.value);
|
|
27
|
+
}
|
|
28
|
+
function handleClear(e) {
|
|
29
|
+
e.stopPropagation();
|
|
30
|
+
if (disabled) return;
|
|
31
|
+
setSelectedOption(void 0);
|
|
32
|
+
if (onChange) onChange(null);
|
|
33
|
+
}
|
|
34
|
+
const filteredOptions = options.filter((option) => option.label.toLowerCase().includes(searchTerm.toLowerCase()));
|
|
35
|
+
return /* @__PURE__ */ jsxs(FieldWrapper, {
|
|
36
|
+
label,
|
|
37
|
+
name,
|
|
38
|
+
required,
|
|
39
|
+
info,
|
|
40
|
+
description,
|
|
41
|
+
error,
|
|
42
|
+
textSize,
|
|
43
|
+
className,
|
|
44
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
45
|
+
className: "relative",
|
|
46
|
+
ref: containerRef,
|
|
47
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
48
|
+
type: "button",
|
|
49
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
50
|
+
disabled,
|
|
51
|
+
"aria-haspopup": "listbox",
|
|
52
|
+
"aria-expanded": isOpen,
|
|
53
|
+
"aria-labelledby": label ? void 0 : name,
|
|
54
|
+
className: `
|
|
55
|
+
w-full rounded-md bg-login-500/50 border border-login-500
|
|
56
|
+
text-login-text text-left text-sm
|
|
57
|
+
focus:outline-none focus:border-login/60 focus:ring-1 focus:ring-login/30
|
|
58
|
+
disabled:opacity-40 disabled:cursor-not-allowed
|
|
59
|
+
h-10 py-2 pl-3 pr-10
|
|
60
|
+
transition-all duration-150
|
|
61
|
+
flex items-center justify-between
|
|
62
|
+
${error ? "border-red-500/70 focus:border-red-500/70 focus:ring-red-500/30" : ""}
|
|
63
|
+
${!selectedOption ? "text-login-200" : ""}
|
|
64
|
+
`,
|
|
65
|
+
title: label,
|
|
66
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
67
|
+
className: "flex items-center gap-2 truncate",
|
|
68
|
+
children: [selectedOption?.image && /* @__PURE__ */ jsx(Image, {
|
|
69
|
+
src: selectedOption.image,
|
|
70
|
+
alt: "",
|
|
71
|
+
width: 30,
|
|
72
|
+
height: 20,
|
|
73
|
+
className: "rounded-xs object-cover shrink-0"
|
|
74
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
75
|
+
className: "truncate",
|
|
76
|
+
children: selectedOption ? selectedOption.label : placeholder
|
|
77
|
+
})]
|
|
78
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
79
|
+
className: "absolute inset-y-0 right-0 flex items-center px-2 gap-1",
|
|
80
|
+
children: [clearable && selectedOption && !disabled && /* @__PURE__ */ jsx("div", {
|
|
81
|
+
role: "button",
|
|
82
|
+
onClick: handleClear,
|
|
83
|
+
className: `
|
|
84
|
+
p-1 hover:bg-login-500 rounded-full text-login-200
|
|
85
|
+
hover:text-red-400 transition-colors cursor-pointer
|
|
86
|
+
`,
|
|
87
|
+
title: "Clear selection",
|
|
88
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-3 h-3" })
|
|
89
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
90
|
+
className: `
|
|
91
|
+
text-login-200 pointer-events-none
|
|
92
|
+
transition-transform duration-200
|
|
93
|
+
${isOpen ? "rotate-180" : ""}
|
|
94
|
+
`,
|
|
95
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: "w-4 h-4" })
|
|
96
|
+
})]
|
|
97
|
+
})]
|
|
98
|
+
}), isOpen && /* @__PURE__ */ jsxs("div", {
|
|
99
|
+
className: `
|
|
100
|
+
absolute z-50 w-full mt-1 bg-login-700 border border-login-500/50
|
|
101
|
+
rounded-md shadow-xl max-h-60 overflow-hidden flex flex-col
|
|
102
|
+
`,
|
|
103
|
+
children: [searchable && /* @__PURE__ */ jsx("div", {
|
|
104
|
+
className: "p-2 sticky top-0 bg-login-700 border-b border-login-500/20 z-10",
|
|
105
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
106
|
+
className: "relative",
|
|
107
|
+
children: [/* @__PURE__ */ jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-login-200" }), /* @__PURE__ */ jsx("input", {
|
|
108
|
+
type: "text",
|
|
109
|
+
value: searchTerm,
|
|
110
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
111
|
+
placeholder: "Search...",
|
|
112
|
+
autoFocus: true,
|
|
113
|
+
className: `
|
|
114
|
+
w-full bg-login-600 border border-login-500/50 rounded-md
|
|
115
|
+
py-1.5 pl-9 pr-3 text-sm text-login-text
|
|
116
|
+
focus:outline-none focus:border-login/60 focus:ring-1 focus:ring-login/30
|
|
117
|
+
`
|
|
118
|
+
})]
|
|
119
|
+
})
|
|
120
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
121
|
+
className: "overflow-auto noscroll",
|
|
122
|
+
children: filteredOptions.length > 0 ? /* @__PURE__ */ jsx("ul", {
|
|
123
|
+
className: "py-1",
|
|
124
|
+
role: "listbox",
|
|
125
|
+
children: filteredOptions.map((option) => /* @__PURE__ */ jsx("li", {
|
|
126
|
+
role: "option",
|
|
127
|
+
"aria-selected": selectedOption?.value === option.value,
|
|
128
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
129
|
+
type: "button",
|
|
130
|
+
onClick: () => handleSelect(option),
|
|
131
|
+
className: `
|
|
132
|
+
w-full text-left px-3 py-2 text-sm
|
|
133
|
+
hover:bg-login-600 transition-colors duration-150
|
|
134
|
+
flex items-center gap-2
|
|
135
|
+
${selectedOption?.value === option.value ? "bg-login/15 text-login" : "text-login-text"}
|
|
136
|
+
`,
|
|
137
|
+
children: [option.image && /* @__PURE__ */ jsx(Image, {
|
|
138
|
+
src: option.image,
|
|
139
|
+
alt: "",
|
|
140
|
+
width: 75,
|
|
141
|
+
height: 25,
|
|
142
|
+
className: "rounded-md object-cover shrink-0"
|
|
143
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
144
|
+
className: "truncate",
|
|
145
|
+
children: option.label
|
|
146
|
+
})]
|
|
147
|
+
})
|
|
148
|
+
}, option.value))
|
|
149
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
150
|
+
className: "px-3 py-2 text-sm text-login-200",
|
|
151
|
+
children: searchTerm ? "No results found" : "No options available"
|
|
152
|
+
})
|
|
153
|
+
})]
|
|
154
|
+
})]
|
|
155
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
156
|
+
type: "hidden",
|
|
157
|
+
name,
|
|
158
|
+
value: selectedOption?.value || "",
|
|
159
|
+
required
|
|
160
|
+
})]
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
164
|
+
export { Select as default };
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/inputs/shared/colorPickerPopup.tsx
|
|
5
|
+
function hexToHsv(hex) {
|
|
6
|
+
hex = hex.replace("#", "");
|
|
7
|
+
let r = 0, g = 0, b = 0;
|
|
8
|
+
if (hex.length === 3) {
|
|
9
|
+
r = parseInt(hex[0] + hex[0], 16);
|
|
10
|
+
g = parseInt(hex[1] + hex[1], 16);
|
|
11
|
+
b = parseInt(hex[2] + hex[2], 16);
|
|
12
|
+
} else if (hex.length === 6) {
|
|
13
|
+
r = parseInt(hex.substring(0, 2), 16);
|
|
14
|
+
g = parseInt(hex.substring(2, 4), 16);
|
|
15
|
+
b = parseInt(hex.substring(4, 6), 16);
|
|
16
|
+
}
|
|
17
|
+
r /= 255;
|
|
18
|
+
g /= 255;
|
|
19
|
+
b /= 255;
|
|
20
|
+
const max = Math.max(r, g, b);
|
|
21
|
+
const min = Math.min(r, g, b);
|
|
22
|
+
const d = max - min;
|
|
23
|
+
let h = 0;
|
|
24
|
+
const s = max === 0 ? 0 : d / max;
|
|
25
|
+
const v = max;
|
|
26
|
+
if (max !== min) {
|
|
27
|
+
switch (max) {
|
|
28
|
+
case r:
|
|
29
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
30
|
+
break;
|
|
31
|
+
case g:
|
|
32
|
+
h = (b - r) / d + 2;
|
|
33
|
+
break;
|
|
34
|
+
case b:
|
|
35
|
+
h = (r - g) / d + 4;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
h /= 6;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
h: h * 360,
|
|
42
|
+
s: s * 100,
|
|
43
|
+
v: v * 100
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function hsvToRgb(h, s, v) {
|
|
47
|
+
let r = 0, g = 0, b = 0;
|
|
48
|
+
const i = Math.floor(h * 6);
|
|
49
|
+
const f = h * 6 - i;
|
|
50
|
+
const p = v * (1 - s);
|
|
51
|
+
const q = v * (1 - f * s);
|
|
52
|
+
const t = v * (1 - (1 - f) * s);
|
|
53
|
+
switch (i % 6) {
|
|
54
|
+
case 0:
|
|
55
|
+
r = v;
|
|
56
|
+
g = t;
|
|
57
|
+
b = p;
|
|
58
|
+
break;
|
|
59
|
+
case 1:
|
|
60
|
+
r = q;
|
|
61
|
+
g = v;
|
|
62
|
+
b = p;
|
|
63
|
+
break;
|
|
64
|
+
case 2:
|
|
65
|
+
r = p;
|
|
66
|
+
g = v;
|
|
67
|
+
b = t;
|
|
68
|
+
break;
|
|
69
|
+
case 3:
|
|
70
|
+
r = p;
|
|
71
|
+
g = q;
|
|
72
|
+
b = v;
|
|
73
|
+
break;
|
|
74
|
+
case 4:
|
|
75
|
+
r = t;
|
|
76
|
+
g = p;
|
|
77
|
+
b = v;
|
|
78
|
+
break;
|
|
79
|
+
case 5:
|
|
80
|
+
r = v;
|
|
81
|
+
g = p;
|
|
82
|
+
b = q;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
r: Math.round(r * 255),
|
|
87
|
+
g: Math.round(g * 255),
|
|
88
|
+
b: Math.round(b * 255)
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function hsvToHex(h, s, v) {
|
|
92
|
+
const { r, g, b } = hsvToRgb(h / 360, s / 100, v / 100);
|
|
93
|
+
function toHex(x) {
|
|
94
|
+
const hex = x.toString(16);
|
|
95
|
+
return hex.length === 1 ? "0" + hex : hex;
|
|
96
|
+
}
|
|
97
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
98
|
+
}
|
|
99
|
+
const PRESET_COLORS = [
|
|
100
|
+
"#f87171",
|
|
101
|
+
"#fd8738",
|
|
102
|
+
"#fbbf24",
|
|
103
|
+
"#facc15",
|
|
104
|
+
"#a3e635",
|
|
105
|
+
"#4ade80",
|
|
106
|
+
"#34d399",
|
|
107
|
+
"#2dd4bf",
|
|
108
|
+
"#38bdf8",
|
|
109
|
+
"#60a5fa",
|
|
110
|
+
"#818cf8",
|
|
111
|
+
"#a78bfa",
|
|
112
|
+
"#c084fc",
|
|
113
|
+
"#e879f9",
|
|
114
|
+
"#f472b6",
|
|
115
|
+
"#fb7185"
|
|
116
|
+
];
|
|
117
|
+
function SaturationPicker({ hsv, onChange }) {
|
|
118
|
+
const containerRef = useRef(null);
|
|
119
|
+
function handleMove(e) {
|
|
120
|
+
if (!containerRef.current) return;
|
|
121
|
+
const { left, top, width, height } = containerRef.current.getBoundingClientRect();
|
|
122
|
+
const x = Math.min(Math.max((e.clientX - left) / width, 0), 1);
|
|
123
|
+
const y = Math.min(Math.max((e.clientY - top) / height, 0), 1);
|
|
124
|
+
onChange(x * 100, (1 - y) * 100);
|
|
125
|
+
}
|
|
126
|
+
function handleMouseDown(e) {
|
|
127
|
+
handleMove(e);
|
|
128
|
+
function moveHandler(e) {
|
|
129
|
+
handleMove(e);
|
|
130
|
+
}
|
|
131
|
+
function upHandler() {
|
|
132
|
+
window.removeEventListener("mousemove", moveHandler);
|
|
133
|
+
window.removeEventListener("mouseup", upHandler);
|
|
134
|
+
}
|
|
135
|
+
window.addEventListener("mousemove", moveHandler);
|
|
136
|
+
window.addEventListener("mouseup", upHandler);
|
|
137
|
+
}
|
|
138
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
139
|
+
ref: containerRef,
|
|
140
|
+
className: "w-full h-32 relative rounded-md overflow-hidden cursor-crosshair mb-3 select-none",
|
|
141
|
+
style: { backgroundColor: hsvToHex(hsv.h, 100, 100) },
|
|
142
|
+
onMouseDown: handleMouseDown,
|
|
143
|
+
children: [
|
|
144
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-linear-to-r from-white to-transparent" }),
|
|
145
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-linear-to-t from-black to-transparent" }),
|
|
146
|
+
/* @__PURE__ */ jsx("div", {
|
|
147
|
+
className: `
|
|
148
|
+
absolute w-3 h-3 border-2 border-white rounded-full
|
|
149
|
+
shadow-md -translate-x-1/2 -translate-y-1/2 pointer-events-none
|
|
150
|
+
`,
|
|
151
|
+
style: {
|
|
152
|
+
left: `${hsv.s}%`,
|
|
153
|
+
top: `${100 - hsv.v}%`
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
]
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function HuePicker({ hue, onChange }) {
|
|
160
|
+
const containerRef = useRef(null);
|
|
161
|
+
function handleMove(e) {
|
|
162
|
+
if (!containerRef.current) return;
|
|
163
|
+
const { left, width } = containerRef.current.getBoundingClientRect();
|
|
164
|
+
onChange(Math.min(Math.max((e.clientX - left) / width, 0), 1) * 360);
|
|
165
|
+
}
|
|
166
|
+
function handleMouseDown(e) {
|
|
167
|
+
handleMove(e);
|
|
168
|
+
function moveHandler(e) {
|
|
169
|
+
handleMove(e);
|
|
170
|
+
}
|
|
171
|
+
function upHandler() {
|
|
172
|
+
window.removeEventListener("mousemove", moveHandler);
|
|
173
|
+
window.removeEventListener("mouseup", upHandler);
|
|
174
|
+
}
|
|
175
|
+
window.addEventListener("mousemove", moveHandler);
|
|
176
|
+
window.addEventListener("mouseup", upHandler);
|
|
177
|
+
}
|
|
178
|
+
return /* @__PURE__ */ jsx("div", {
|
|
179
|
+
ref: containerRef,
|
|
180
|
+
className: "w-full h-3 relative rounded-full cursor-pointer mb-4 select-none",
|
|
181
|
+
style: { background: "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)" },
|
|
182
|
+
onMouseDown: handleMouseDown,
|
|
183
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
184
|
+
className: `
|
|
185
|
+
absolute w-4 h-4 bg-white border border-gray-200
|
|
186
|
+
rounded-full shadow-sm -translate-x-1/2 -translate-y-1/2
|
|
187
|
+
top-1/2 pointer-events-none
|
|
188
|
+
`,
|
|
189
|
+
style: { left: `${hue / 360 * 100}%` }
|
|
190
|
+
})
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
function ColorPickerPopup({ value, onChange, onClose, anchorName }) {
|
|
194
|
+
const [hsv, setHsv] = useState(() => hexToHsv(value || "#000000"));
|
|
195
|
+
const [hexInput, setHexInput] = useState(value || "#000000");
|
|
196
|
+
useEffect(() => {
|
|
197
|
+
if (value && value !== hexInput) {
|
|
198
|
+
setHsv(hexToHsv(value));
|
|
199
|
+
setHexInput(value);
|
|
200
|
+
}
|
|
201
|
+
}, [value]);
|
|
202
|
+
function handleColorChange(newHsv) {
|
|
203
|
+
setHsv(newHsv);
|
|
204
|
+
const hex = hsvToHex(newHsv.h, newHsv.s, newHsv.v);
|
|
205
|
+
setHexInput(hex);
|
|
206
|
+
onChange(hex);
|
|
207
|
+
}
|
|
208
|
+
function handleSaturationChange(s, v) {
|
|
209
|
+
handleColorChange({
|
|
210
|
+
...hsv,
|
|
211
|
+
s,
|
|
212
|
+
v
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function handleHueChange(h) {
|
|
216
|
+
handleColorChange({
|
|
217
|
+
...hsv,
|
|
218
|
+
h
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
function manualHexChange(e) {
|
|
222
|
+
const val = e.target.value;
|
|
223
|
+
setHexInput(val);
|
|
224
|
+
if (/^#[0-9A-F]{6}$/i.test(val)) {
|
|
225
|
+
setHsv(hexToHsv(val));
|
|
226
|
+
onChange(val);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
230
|
+
className: "fixed z-50 bg-login-700 border border-login-500/50 rounded-md shadow-xl p-3 w-64 select-none anchor-popup",
|
|
231
|
+
style: {
|
|
232
|
+
positionAnchor: anchorName,
|
|
233
|
+
positionArea: "bottom span-right",
|
|
234
|
+
insetArea: "bottom span-right",
|
|
235
|
+
positionTryFallbacks: "flip-block",
|
|
236
|
+
margin: "0.25rem 0"
|
|
237
|
+
},
|
|
238
|
+
children: [
|
|
239
|
+
/* @__PURE__ */ jsx(SaturationPicker, {
|
|
240
|
+
hsv,
|
|
241
|
+
onChange: handleSaturationChange
|
|
242
|
+
}),
|
|
243
|
+
/* @__PURE__ */ jsx(HuePicker, {
|
|
244
|
+
hue: hsv.h,
|
|
245
|
+
onChange: handleHueChange
|
|
246
|
+
}),
|
|
247
|
+
/* @__PURE__ */ jsxs("div", {
|
|
248
|
+
className: "flex items-center gap-2 mb-3",
|
|
249
|
+
children: [
|
|
250
|
+
/* @__PURE__ */ jsx("div", {
|
|
251
|
+
className: "text-xs text-login-200 font-mono",
|
|
252
|
+
children: "HEX"
|
|
253
|
+
}),
|
|
254
|
+
/* @__PURE__ */ jsx("input", {
|
|
255
|
+
type: "text",
|
|
256
|
+
value: hexInput,
|
|
257
|
+
onChange: manualHexChange,
|
|
258
|
+
className: `
|
|
259
|
+
flex-1 min-w-0 bg-login-600 border border-login-500/50 rounded
|
|
260
|
+
px-2 py-1 text-sm text-login-text focus:outline-none
|
|
261
|
+
focus:border-login/60 focus:ring-1 focus:ring-login/30
|
|
262
|
+
`,
|
|
263
|
+
spellCheck: false
|
|
264
|
+
}),
|
|
265
|
+
/* @__PURE__ */ jsx("div", {
|
|
266
|
+
className: "w-8 h-8 rounded border border-login-500/50 shrink-0",
|
|
267
|
+
style: { backgroundColor: hexInput }
|
|
268
|
+
})
|
|
269
|
+
]
|
|
270
|
+
}),
|
|
271
|
+
/* @__PURE__ */ jsx("div", {
|
|
272
|
+
className: "grid grid-cols-8 gap-1.5 pt-3 border-t border-login-500/25",
|
|
273
|
+
children: PRESET_COLORS.map((color) => /* @__PURE__ */ jsx("button", {
|
|
274
|
+
type: "button",
|
|
275
|
+
className: `
|
|
276
|
+
w-6 h-6 rounded-sm cursor-pointer hover:scale-110
|
|
277
|
+
hover:zIndex-10 transition-transform ring-1 ring-inset ring-black/10
|
|
278
|
+
`,
|
|
279
|
+
style: { backgroundColor: color },
|
|
280
|
+
onClick: () => {
|
|
281
|
+
setHsv(hexToHsv(color));
|
|
282
|
+
setHexInput(color);
|
|
283
|
+
onChange(color);
|
|
284
|
+
onClose();
|
|
285
|
+
},
|
|
286
|
+
title: color
|
|
287
|
+
}, color))
|
|
288
|
+
})
|
|
289
|
+
]
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
//#endregion
|
|
293
|
+
export { ColorPickerPopup as default };
|