@examplary/ui 1.39.0 → 1.39.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.
|
@@ -39,7 +39,18 @@ import * as _ReactDom from "react-dom";
|
|
|
39
39
|
import * as _jsxRuntime from "react/jsx-runtime";
|
|
40
40
|
import * as ExamplaryUI from "../../index";
|
|
41
41
|
var componentCache = new Map();
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Little helper to evaluate the JS code in the context of the module.
|
|
44
|
+
*
|
|
45
|
+
* Note for security analysis: this is not a security risk on its own,
|
|
46
|
+
* as the code executed by this (from custom question types created
|
|
47
|
+
* either by Examplary or submitted by users) has been reviewed by
|
|
48
|
+
* Examplary staff, before being made available to accounts other than
|
|
49
|
+
* the creator.
|
|
50
|
+
*
|
|
51
|
+
* However, if the code being evaluated here were to be modified by an attacker
|
|
52
|
+
* after review, but before being loaded by users, then this could be a security risk.
|
|
53
|
+
*/
|
|
43
54
|
var evalInScope = function (js, contextAsScope) {
|
|
44
55
|
return new Function("\n with (this) { \n ".concat(js, "\n \n if (module.exports.default) {\n module.exports.default._context = this;\n }\n }\n ")).call(contextAsScope);
|
|
45
56
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { LucideProps } from "lucide-react";
|
|
2
3
|
import { PopoverTrigger } from "./popover";
|
|
3
4
|
type IconData = {
|
|
4
5
|
name: string;
|
|
@@ -14,8 +15,12 @@ interface IconPickerProps extends Omit<React.ComponentPropsWithoutRef<typeof Pop
|
|
|
14
15
|
className?: string;
|
|
15
16
|
iconsList?: IconData[];
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
+
type DynamicIconProps = {
|
|
19
|
+
name: string;
|
|
20
|
+
} & LucideProps;
|
|
21
|
+
export declare const DynamicIcon: React.MemoExoticComponent<({ name, ...props }: DynamicIconProps) => import("react/jsx-runtime").JSX.Element>;
|
|
22
|
+
export declare const IconPicker: {
|
|
18
23
|
({ value, defaultValue, onValueChange, children, chooseIconLabel, searchable, searchPlaceholder, iconsList, className, ...props }: IconPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
19
24
|
displayName: string;
|
|
20
25
|
};
|
|
21
|
-
export {
|
|
26
|
+
export {};
|
|
@@ -60,20 +60,42 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
60
60
|
import * as React from "react";
|
|
61
61
|
import { useState, useMemo, useCallback, useEffect } from "react";
|
|
62
62
|
import Fuse from "fuse.js";
|
|
63
|
-
import {
|
|
63
|
+
import { Icon } from "lucide-react";
|
|
64
64
|
import { useDebounceValue } from "usehooks-ts";
|
|
65
65
|
import { Button } from "./button";
|
|
66
66
|
import { Input } from "./input";
|
|
67
67
|
import { Popover, PopoverContent, PopoverTrigger } from "./popover";
|
|
68
68
|
import { Skeleton } from "./skeleton";
|
|
69
|
-
var IconRenderer = React.memo(function (_a) {
|
|
70
|
-
var name = _a.name;
|
|
71
|
-
return _jsx(DynamicIcon, { name: name });
|
|
72
|
-
});
|
|
73
|
-
IconRenderer.displayName = "IconRenderer";
|
|
74
69
|
var IconsColumnSkeleton = function () {
|
|
75
70
|
return (_jsxs("div", { className: "flex flex-col gap-2 w-full", children: [_jsx(Skeleton, { className: "h-4 w-1/2 rounded-md" }), _jsx("div", { className: "grid grid-cols-5 gap-2 w-full", children: Array.from({ length: 40 }).map(function (_, i) { return (_jsx(Skeleton, { className: "h-10 w-10 rounded-md" }, i)); }) })] }));
|
|
76
71
|
};
|
|
72
|
+
export var DynamicIcon = React.memo(function (_a) {
|
|
73
|
+
var name = _a.name, props = __rest(_a, ["name"]);
|
|
74
|
+
var _b = useState([]), node = _b[0], setNode = _b[1];
|
|
75
|
+
useEffect(function () {
|
|
76
|
+
var isMounted = true;
|
|
77
|
+
var loadIcon = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
78
|
+
var response;
|
|
79
|
+
return __generator(this, function (_a) {
|
|
80
|
+
switch (_a.label) {
|
|
81
|
+
case 0: return [4 /*yield*/, import("lucide-static/icon-nodes.json")];
|
|
82
|
+
case 1:
|
|
83
|
+
response = _a.sent();
|
|
84
|
+
if (isMounted) {
|
|
85
|
+
setNode(response.default[name]);
|
|
86
|
+
}
|
|
87
|
+
return [2 /*return*/];
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}); };
|
|
91
|
+
loadIcon();
|
|
92
|
+
return function () {
|
|
93
|
+
isMounted = false;
|
|
94
|
+
};
|
|
95
|
+
}, [name]);
|
|
96
|
+
return _jsx(Icon, __assign({}, props, { iconNode: node }));
|
|
97
|
+
});
|
|
98
|
+
DynamicIcon.displayName = "DynamicIcon";
|
|
77
99
|
var useIconsData = function () {
|
|
78
100
|
var _a = useState([]), icons = _a[0], setIcons = _a[1];
|
|
79
101
|
var _b = useState(true), isLoading = _b[0], setIsLoading = _b[1];
|
|
@@ -109,7 +131,7 @@ var useIconsData = function () {
|
|
|
109
131
|
}, []);
|
|
110
132
|
return { icons: icons, isLoading: isLoading };
|
|
111
133
|
};
|
|
112
|
-
var IconPicker = function (_a) {
|
|
134
|
+
export var IconPicker = function (_a) {
|
|
113
135
|
var value = _a.value, defaultValue = _a.defaultValue, onValueChange = _a.onValueChange, children = _a.children, chooseIconLabel = _a.chooseIconLabel, _b = _a.searchable, searchable = _b === void 0 ? true : _b, _c = _a.searchPlaceholder, searchPlaceholder = _c === void 0 ? "Search for an icon..." : _c, iconsList = _a.iconsList, className = _a.className, props = __rest(_a, ["value", "defaultValue", "onValueChange", "children", "chooseIconLabel", "searchable", "searchPlaceholder", "iconsList", "className"]);
|
|
114
136
|
var _d = useState(defaultValue), selectedIcon = _d[0], setSelectedIcon = _d[1];
|
|
115
137
|
var _e = useState(false), isOpen = _e[0], setIsOpen = _e[1];
|
|
@@ -151,12 +173,11 @@ var IconPicker = function (_a) {
|
|
|
151
173
|
parentRef.current.scrollTop = 0;
|
|
152
174
|
}
|
|
153
175
|
}, [setSearch]);
|
|
154
|
-
var renderIcon = useCallback(function (icon) { return (_jsx(Button, { variant: "roundedWhite", size: "icon", onClick: function () { return handleIconClick(icon.name); }, children: _jsx(
|
|
155
|
-
return (_jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, __assign({ asChild: true }, props, { children: children || (_jsxs(Button, { variant: "white", className: className, children: [value || selectedIcon ? (_jsx(
|
|
176
|
+
var renderIcon = useCallback(function (icon) { return (_jsx(Button, { variant: "roundedWhite", size: "icon", onClick: function () { return handleIconClick(icon.name); }, children: _jsx(DynamicIcon, { name: icon.name }) }, icon.name)); }, [handleIconClick]);
|
|
177
|
+
return (_jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, __assign({ asChild: true }, props, { children: children || (_jsxs(Button, { variant: "white", className: className, children: [value || selectedIcon ? (_jsx(DynamicIcon, { name: (value || selectedIcon) })) : null, chooseIconLabel || "Select icon"] })) })), _jsxs(PopoverContent, { className: "w-64 h-70 flex flex-col overflow-hidden p-0", children: [searchable && (_jsx("div", { className: "m-4 mb-2", children: _jsx(Input, { placeholder: searchPlaceholder, onChange: handleSearchChange }) })), _jsx("div", { ref: parentRef, className: "overflow-auto flex-1 p-4 pt-2", style: { scrollbarWidth: "thin" }, onWheel: function (e) {
|
|
156
178
|
e.stopPropagation();
|
|
157
179
|
}, onTouchMove: function (e) {
|
|
158
180
|
e.stopPropagation();
|
|
159
181
|
}, children: isLoading ? (_jsx(IconsColumnSkeleton, {})) : (_jsx("div", { className: "grid grid-cols-5 gap-2 w-full", children: filteredIcons.map(renderIcon) })) })] })] }));
|
|
160
182
|
};
|
|
161
183
|
IconPicker.displayName = "IconPicker";
|
|
162
|
-
export { IconPicker };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@examplary/ui",
|
|
3
3
|
"description": "UI components for the Examplary testing platform.",
|
|
4
4
|
"packageManager": "yarn@4.5.3",
|
|
5
|
-
"version": "1.39.
|
|
5
|
+
"version": "1.39.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"files": [
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"src/global.css"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"
|
|
13
|
+
"dev": "yarn build --watch",
|
|
14
14
|
"release": "semantic-release -e semantic-release-monorepo",
|
|
15
15
|
"build": "yarn build:js && yarn build:styles",
|
|
16
16
|
"build:js": "tsc ./src/index.ts --outDir dist --skipLibCheck --declaration --jsx react-jsx --esModuleInterop --moduleResolution bundler --module es2020",
|