@hitachivantara/uikit-react-lab
Version:
Contributed React components for the NEXT UI Kit.
442 lines (441 loc) • 15.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const react = require("react");
const css = require("@emotion/css");
const Popover = require("@mui/material/Popover");
const reactflow = require("reactflow");
const uikitReactCore = require("@hitachivantara/uikit-react-core");
const uikitReactIcons = require("@hitachivantara/uikit-react-icons");
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
const Popover__default = /* @__PURE__ */ _interopDefault(Popover);
const defaultData = {
title: "Sticky Note",
backgroundColor: uikitReactCore.theme.colors.warningSubtle,
borderColor: uikitReactCore.theme.colors.warningSubtle,
textColor: uikitReactCore.theme.colors.text,
hasShadow: true,
bold: false,
italic: false,
fontSize: 14,
expanded: true,
visible: true
};
const classes = {
root: css.css({
width: "100%",
height: "100%",
position: "relative",
display: "flex",
outline: "none"
}),
nodeToolbar: css.css({
backgroundColor: "transparent",
borderRadius: uikitReactCore.theme.radii.full,
top: 10
}),
buttonsContainer: css.css({
padding: uikitReactCore.theme.space.xs
}),
textAreaRoot: css.css({
flex: 1,
width: "100%",
border: "none",
background: "transparent",
outline: "none"
}),
textAreaInput: css.css({
resize: "none",
height: "100%",
width: "100%",
padding: uikitReactCore.theme.space.xs,
"&:focus-visible": {
outline: "none"
},
paddingRight: 32
}),
textAreaInputFolded: css.css({
resize: "none",
width: "100%",
padding: 0,
border: "none",
overflow: "hidden",
minHeight: "1.5rem",
height: "auto"
}),
colorConfig: css.css({
display: "flex",
flexDirection: "column",
gap: uikitReactCore.theme.space.sm
}),
folded: css.css({
width: 34,
height: 34
}),
expandButton: css.css({
position: "absolute",
top: uikitReactCore.theme.space.xxs,
right: uikitReactCore.theme.space.xxs
}),
fontSizes: css.css({
maxHeight: 160,
overflowY: "auto",
padding: uikitReactCore.theme.space.xs
})
};
const colorsToConfig = ["textColor", "backgroundColor", "borderColor"];
const fontSizes = [10, 11, 12, 14, 16, 20, 24, 32, 36, 40, 48, 64, 96, 128];
const StickyNode = ({
id,
selected,
data = {}
}) => {
const mergedData = react.useMemo(() => ({ ...defaultData, ...data }), [data]);
const [text, setText] = react.useState("");
const { setNodes } = reactflow.useReactFlow();
const [editing, setEditing] = react.useState(false);
const [toolbarVisible, setToolbarVisible] = react.useState(false);
const [colorsConfigOpen, setColorsConfigOpen] = react.useState(false);
const [fontSizeConfigOpen, setFontSizeConfigOpen] = react.useState(false);
const [fontSize, setFontSize] = react.useState(mergedData.fontSize ?? 14);
const colorConfigBtnRef = react.useRef(null);
const fontSizeConfigBtnRef = react.useRef(null);
const handleToggleBold = react.useCallback(() => {
setNodes(
(nds) => nds.map((node) => {
if (node.id === id) {
node.data = {
...node.data,
bold: !node.data?.bold
};
}
return node;
})
);
}, [setNodes, id]);
const handleToggleItalic = react.useCallback(() => {
setNodes(
(nds) => nds.map((node) => {
if (node.id === id) {
node.data = {
...node.data,
italic: !node.data?.italic
};
}
return node;
})
);
}, [setNodes, id]);
const handleChangeFontSize = react.useCallback(
(size) => {
setFontSize(size);
setNodes(
(nds) => nds.map((node) => {
if (node.id === id) {
node.data = {
...node.data,
fontSize: size
};
}
return node;
})
);
setFontSizeConfigOpen(false);
},
[setNodes, id]
);
const handleToggleExpand = react.useCallback(() => {
setNodes(
(nds) => nds.map((node) => {
if (node.id === id) {
node.data = {
...node.data,
expanded: !node.data?.expanded
};
}
return node;
})
);
}, [setNodes, id]);
const handleResetColors = react.useCallback(() => {
setNodes(
(nds) => nds.map((node) => {
if (node.id === id) {
node.data = {
...node.data,
backgroundColor: defaultData.backgroundColor,
borderColor: defaultData.borderColor,
textColor: defaultData.textColor,
hasShadow: defaultData.hasShadow
};
}
return node;
})
);
}, [setNodes, id]);
const handleDeleteSticky = react.useCallback(() => {
setNodes((nds) => nds.filter((node) => node.id !== id));
mergedData.onDelete?.();
}, [mergedData, setNodes, id]);
if (!mergedData.visible) return null;
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsxs(
Popover__default.default,
{
open: colorsConfigOpen,
anchorEl: colorConfigBtnRef.current,
onClose: () => {
setColorsConfigOpen(false);
setEditing(false);
},
anchorOrigin: {
vertical: "bottom",
horizontal: "left"
},
transformOrigin: {
vertical: "top",
horizontal: "left"
},
children: [
/* @__PURE__ */ jsxRuntime.jsx(uikitReactCore.HvDialogTitle, { children: "Customize Colors" }),
/* @__PURE__ */ jsxRuntime.jsx(uikitReactCore.HvDialogContent, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classes.colorConfig, children: [
colorsToConfig.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvColorPicker,
{
label: `${c.charAt(0).toUpperCase() + c.slice(1).replace("Color", " Color")}`,
value: mergedData[c] ?? "",
onChange: (color) => {
setNodes(
(nds) => nds.map((node) => {
if (node.id === id) {
node.data = {
...node.data,
[c]: color
};
}
return node;
})
);
}
},
c
)),
/* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvCheckBox,
{
label: "Drop Shadow",
defaultChecked: mergedData.hasShadow,
onChange: (_, checked) => {
setNodes(
(nds) => nds.map((node) => {
if (node.id === id) {
node.data = {
...node.data,
hasShadow: checked
};
}
return node;
})
);
}
}
),
/* @__PURE__ */ jsxRuntime.jsx(uikitReactCore.HvButton, { variant: "secondarySubtle", onClick: handleResetColors, children: "Reset to defaults" })
] }) })
]
}
),
/* @__PURE__ */ jsxRuntime.jsx(
Popover__default.default,
{
open: fontSizeConfigOpen,
anchorEl: fontSizeConfigBtnRef.current,
onClose: () => {
setFontSizeConfigOpen(false);
setEditing(false);
},
anchorOrigin: {
vertical: "bottom",
horizontal: "right"
},
transformOrigin: {
vertical: "top",
horizontal: "right"
},
children: /* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvSelectionList,
{
className: classes.fontSizes,
value: fontSize,
onChange: (evt, newValue) => {
handleChangeFontSize(newValue);
},
children: fontSizes.map((size) => /* @__PURE__ */ jsxRuntime.jsx(uikitReactCore.HvListItem, { value: size, children: size }, size))
}
)
}
),
/* @__PURE__ */ jsxRuntime.jsxs(
"div",
{
className: css.cx(
classes.root,
"nowheel",
!mergedData.expanded && classes.folded
),
style: {
backgroundColor: mergedData.backgroundColor ?? uikitReactCore.theme.colors.bgContainer,
boxShadow: mergedData.hasShadow ? "0 8px 12px rgba(65,65,65,0.25)" : "none",
border: mergedData.borderColor ? `1px solid ${mergedData.borderColor}` : "none",
fontSize: `${mergedData.fontSize ?? 14}px`,
lineHeight: `${mergedData.fontSize ?? 14}px`
},
children: [
mergedData.expanded && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
reactflow.NodeResizer,
{
isVisible: selected,
minWidth: 100,
minHeight: 75,
lineStyle: {
color: uikitReactCore.theme.colors.primary,
borderStyle: "solid"
},
handleStyle: {
width: 6,
height: 6,
border: `1px solid ${uikitReactCore.theme.colors.primary}`,
backgroundColor: mergedData.backgroundColor ?? "transparent",
borderRadius: uikitReactCore.theme.radii.full
}
}
),
/* @__PURE__ */ jsxRuntime.jsx(
reactflow.NodeToolbar,
{
isVisible: editing || toolbarVisible || selected,
position: reactflow.Position.Top,
className: classes.nodeToolbar,
onMouseEnter: () => setToolbarVisible(true),
onMouseLeave: () => setToolbarVisible(false),
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.buttonsContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(uikitReactCore.HvMultiButton, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvIconButton,
{
"aria-label": "Font Size",
title: "Font Size",
ref: fontSizeConfigBtnRef,
onClick: () => {
setEditing(true);
setFontSizeConfigOpen(true);
},
children: /* @__PURE__ */ jsxRuntime.jsx(uikitReactIcons.FontSize, {})
}
),
/* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvIconButton,
{
"aria-label": "Bold",
title: "Bold",
selected: mergedData.bold,
onClick: handleToggleBold,
children: /* @__PURE__ */ jsxRuntime.jsx(uikitReactIcons.Bold, {})
}
),
/* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvIconButton,
{
"aria-label": "Italic",
title: "Italic",
selected: mergedData.italic,
onClick: handleToggleItalic,
children: /* @__PURE__ */ jsxRuntime.jsx(uikitReactIcons.Italic, {})
}
),
/* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvIconButton,
{
"aria-label": "Customize Colors",
title: "Customize Colors",
ref: colorConfigBtnRef,
onClick: () => {
setEditing(true);
setColorsConfigOpen(true);
},
children: /* @__PURE__ */ jsxRuntime.jsx(uikitReactIcons.Palette, {})
}
),
/* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvIconButton,
{
"aria-label": "Delete",
title: "Delete",
onClick: handleDeleteSticky,
children: /* @__PURE__ */ jsxRuntime.jsx(uikitReactIcons.Delete, {})
}
)
] }) })
}
),
/* @__PURE__ */ jsxRuntime.jsxs(
"div",
{
onMouseEnter: () => setToolbarVisible(true),
onMouseLeave: () => setToolbarVisible(false),
className: classes.textAreaRoot,
children: [
/* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvIconButton,
{
className: classes.expandButton,
title: "Fold",
onClick: handleToggleExpand,
children: /* @__PURE__ */ jsxRuntime.jsx(uikitReactIcons.ActualSize, {})
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"textarea",
{
id: `sticky-textarea-${id}`,
value: text || "",
onChange: (e) => setText(e.target.value),
className: classes.textAreaInput,
placeholder: "Type here...",
style: {
color: mergedData.textColor ?? uikitReactCore.theme.colors.text,
fontWeight: mergedData.bold ? "bold" : "normal",
fontStyle: mergedData.italic ? "italic" : "normal",
fontSize: mergedData.fontSize ?? "14px"
},
onFocus: () => setEditing(true),
onBlur: () => {
setEditing(false);
setColorsConfigOpen(false);
}
}
)
]
}
)
] }),
!mergedData.expanded && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
uikitReactCore.HvIconButton,
{
title: /* @__PURE__ */ jsxRuntime.jsx(
"span",
{
style: { whiteSpace: "pre-wrap", wordBreak: "break-word" },
children: text
}
),
onClick: handleToggleExpand,
children: /* @__PURE__ */ jsxRuntime.jsx(uikitReactIcons.Fullscreen, {})
}
) })
]
}
)
] });
};
exports.StickyNode = StickyNode;