aboutsummaryrefslogtreecommitdiff
path: root/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx')
-rwxr-xr-xusers/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx136
1 files changed, 136 insertions, 0 deletions
diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx
new file mode 100755
index 0000000..f5555a1
--- /dev/null
+++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx
@@ -0,0 +1,136 @@
1import * as Uebersicht from "uebersicht";
2import * as Specter from "./specter.jsx";
3import * as Utils from "../../utils";
4import { SuspenseIcon } from "../icons/icon.jsx";
5export { dataWidgetStyles as styles } from "../../styles/components/data/data-widget";
6
7const { React } = Uebersicht;
8
9/**
10 * Widget component that renders a clickable data widget with optional icon and specter.
11 * @param {Object} props - The properties object.
12 * @param {React.Component} props.Icon - The icon component to display.
13 * @param {string} props.classes - Additional classes for the widget.
14 * @param {string} props.href - The URL to link to.
15 * @param {function} props.onClick - The click event handler.
16 * @param {function} props.onRightClick - The right-click event handler.
17 * @param {function} props.onMiddleClick - The middle-click event handler.
18 * @param {Object} props.style - The style object.
19 * @param {boolean} props.disableSlider - Flag to disable the slider effect.
20 * @param {boolean} props.showSpecter - Flag to show the specter widget.
21 * @param {boolean} props.useDivForClick - Render a div for click handling instead of a button.
22 * @param {React.ReactNode} props.children - The child elements to render inside the widget.
23 * @returns {React.ReactElement} The rendered widget component.
24 */
25export function Widget({
26 Icon,
27 classes,
28 href,
29 onClick,
30 onRightClick,
31 onMiddleClick,
32 style,
33 disableSlider,
34 showSpecter,
35 useDivForClick,
36 children,
37}) {
38 const ref = React.useRef();
39
40 let Tag = "div";
41 if (href) Tag = "a";
42 if (onClick && !href && !useDivForClick) Tag = "button";
43
44 const renderDivButton = Tag === "div" && Boolean(onClick);
45
46 const dataWidgetClasses = Utils.classNames("data-widget", classes, {
47 "data-widget--clickable": href || onClick,
48 });
49
50 /**
51 * Handles the click event, determining the appropriate action based on the event.
52 * @param {MouseEvent} e - The mouse event.
53 */
54 const onClickProp = (e) => {
55 const { metaKey } = e;
56 const action = metaKey || isMiddleClick(e) ? onMiddleClick : onClick;
57 if (action) action(e);
58 };
59
60 /**
61 * Handles the mouse enter event to start the sliding effect.
62 */
63 const onMouseEnter = () => {
64 Utils.startSliding(
65 ref.current,
66 ".data-widget__inner",
67 ".data-widget__slider",
68 );
69 };
70
71 /**
72 * Handles the mouse leave event to stop the sliding effect.
73 */
74 const onMouseLeave = () => {
75 Utils.stopSliding(ref.current, ".data-widget__slider");
76 };
77
78 /**
79 * Handles keyboard interaction for div-based clickable widgets.
80 * @param {KeyboardEvent} e - The keyboard event.
81 */
82 const onKeyDown = (e) => {
83 if (e.key !== "Enter" && e.key !== " ") return;
84 e.preventDefault();
85 onClickProp(e);
86 };
87
88 return (
89 <Tag
90 ref={ref}
91 className={dataWidgetClasses}
92 href={href}
93 onClick={onClickProp}
94 role={renderDivButton ? "button" : undefined}
95 tabIndex={renderDivButton ? 0 : undefined}
96 onKeyDown={renderDivButton ? onKeyDown : undefined}
97 onContextMenu={onRightClick || undefined}
98 onMouseEnter={!disableSlider ? onMouseEnter : undefined}
99 onMouseLeave={!disableSlider ? onMouseLeave : undefined}
100 style={style}
101 >
102 {Icon && (
103 <SuspenseIcon>
104 <Icon />
105 </SuspenseIcon>
106 )}
107 {showSpecter && <Specter.Widget />}
108 <Inner disableSlider={disableSlider}>{children}</Inner>
109 </Tag>
110 );
111}
112
113/**
114 * Inner component that optionally wraps children with sliding effect elements.
115 * @param {Object} props - The properties object.
116 * @param {boolean} props.disableSlider - Flag to disable the slider effect.
117 * @param {React.ReactNode} props.children - The child elements to render inside the inner component.
118 * @returns {React.ReactElement} The rendered inner component.
119 */
120function Inner({ disableSlider, children }) {
121 if (disableSlider) return children;
122 return (
123 <div className="data-widget__inner">
124 <div className="data-widget__slider">{children}</div>
125 </div>
126 );
127}
128
129/**
130 * Checks if the event is a middle-click.
131 * @param {MouseEvent} e - The mouse event.
132 * @returns {boolean} True if the event is a middle-click, false otherwise.
133 */
134function isMiddleClick(e) {
135 return e.button === 1 || e["button&2"] === 1;
136}