ehscan-react-components 0.1.46 → 0.1.48

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/README.md CHANGED
@@ -7,6 +7,7 @@ This library is ideal for dashboards, admin panels, internal tools, and feature-
7
7
  ## 📦 Available Components
8
8
 
9
9
  ## Table of Contents
10
+ - [Button](#button)
10
11
  - [Drag And Drop](#drag-and-drop)
11
12
  - [AddBox](#addbox)
12
13
  - [Window](#window)
@@ -24,6 +25,77 @@ yarn add ehscan-react-components
24
25
 
25
26
  # Usage Examples
26
27
 
28
+ ## Button
29
+
30
+ A flexible, reusable button component for React with support for multiple interaction styles like raw, pop, and ripple effects.
31
+
32
+ Features:
33
+
34
+ - **Optional text and icon support**: You can pass text and/or children (e.g., an icon) to display inside the button.
35
+ - **Multiple button styles**: Controlled via the type prop:
36
+ - "raw": Standard button with no extra visual effect.
37
+ - "pop": Shrinks slightly when pressed, creating a “pop” effect.
38
+ - "ripple": Shows a ripple animation on click.
39
+ - **Click handling with optional delay**: The click callback is triggered on button press, with an optional 200ms delay unless notimeout is true.
40
+ - **Custom styling**: You can pass additional classes via addClass.
41
+ - **Accessibility support**: Uses aria-pressed to indicate a selected state.
42
+
43
+ ![Button Preview](https://raw.githubusercontent.com/beeplaced/ehscan-react-components/main/src/images/Button.png)
44
+
45
+ ```jsx
46
+ import { Button } from 'ehscan-react-components';
47
+
48
+ const ButtonPage = () => {
49
+
50
+ const doStuff = () => {
51
+ console.log("doStuff")
52
+ }
53
+
54
+ return (<>
55
+ <Button index={'primary'} text='Primary' type="pop" addClass="inject-styling" click={() => doStuff()} >
56
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="white"><path d="m354-287 126-76 126 77-33-144 111-96-146-13-58-136-58 135-146 13 111 97-33 143ZM233-120l65-281L80-590l288-25 112-265 112 265 288 25-218 189 65 281-247-149-247 149Zm247-350Z" /></svg>
57
+ </Button>
58
+ <Button index={'danger'} text='Danger' type="pop" addClass="ext-btn--danger" click={() => doStuff()} >
59
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#FFFFFF"><path d="M330-120 120-330v-300l210-210h300l210 210v300L630-120H330Zm36-190 114-114 114 114 56-56-114-114 114-114-56-56-114 114-114-114-56 56 114 114-114 114 56 56Zm-2 110h232l164-164v-232L596-760H364L200-596v232l164 164Zm116-280Z" /></svg>
60
+ </Button>
61
+ <Button index={'secondary'} text='Secondary' type="pop" addClass="ext-btn--secondary" click={() => doStuff()} >
62
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#0000F5"><path d="M360-160q-19 0-36-8.5T296-192L80-480l216-288q11-15 28-23.5t36-8.5h440q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H360ZM180-480l180 240h440v-480H360L180-480Zm220 40q17 0 28.5-11.5T440-480q0-17-11.5-28.5T400-520q-17 0-28.5 11.5T360-480q0 17 11.5 28.5T400-440Zm140 0q17 0 28.5-11.5T580-480q0-17-11.5-28.5T540-520q-17 0-28.5 11.5T500-480q0 17 11.5 28.5T540-440Zm140 0q17 0 28.5-11.5T720-480q0-17-11.5-28.5T680-520q-17 0-28.5 11.5T640-480q0 17 11.5 28.5T680-440Zm-100-40Z" /></svg>
63
+ </Button>
64
+ </>)
65
+ }
66
+
67
+ ```
68
+ ### Styling
69
+ ```css
70
+ .inject-styling {
71
+ /* Spacing & layout */
72
+ --ext-btn-gap: 0.5rem;
73
+ --ext-btn-padding: 5px 10px 5px 5px;
74
+ --ext-btn-width: fit-content;
75
+ --ext-btn-height: auto;
76
+
77
+ /* Typography */
78
+ --ext-btn-font-size: 1rem;
79
+ --ext-btn-font-weight: 500;
80
+ --ext-btn-color: #fff;
81
+ --ext-btn-colorbtn-line-height: 1.5;
82
+ --ext-btn-font-family: inherit;
83
+
84
+ /* Background & color */
85
+ --ext-btn-bg: #007aff;
86
+ --ext-btn-color: #fff;
87
+
88
+ /* Border & radius */
89
+ --ext-btn-border: none;
90
+ --ext-btn-radius: 18px;
91
+
92
+ /* Effects & transitions */
93
+ --ext-btn-transition: all 0.2s ease;
94
+ --ext-btn-pop-scale: 0.95;
95
+ --ripple-box-shadow: rgb(100 100 111 / 20%) 0px 7px 29px 0px;
96
+ }
97
+ ```
98
+
27
99
  ## Drag And Drop
28
100
 
29
101
  ```jsx
@@ -310,8 +382,10 @@ const WindowWrapper = ({ windowOpen, setWindowOpen }) => {
310
382
  ```
311
383
  ----
312
384
  # Changelog
385
+ ## [0.1.48] - 2025-12-12
386
+ - Improved Button, module styling and docu, mobile usage (type: "pop")
387
+ - Ripple module styling
313
388
 
314
389
  ## [0.1.45] - 2025-12-11
315
390
  - Added Drag And Drop Component
316
391
  - Added Window css module and docu
317
- ---
@@ -1,4 +1,4 @@
1
- export { Button } from './Button';
1
+ export { Button } from './button/Button';
2
2
  export { Window } from './window/Window';
3
3
  export { DragAndDrop } from './dnd/DragAndDrop';
4
4
  export { TextArea } from './TextArea';
@@ -1,5 +1,5 @@
1
1
  // ehscan-react-components entries
2
- export { Button } from './Button';
2
+ export { Button } from './button/Button';
3
3
  export { Window } from './window/Window';
4
4
  export { DragAndDrop } from './dnd/DragAndDrop';
5
5
  export { TextArea } from './TextArea';
@@ -1,13 +1,12 @@
1
1
  import { ReactNode } from "react";
2
- import './style/button.css';
3
2
  type Props = {
4
3
  index?: string | number;
5
4
  text?: string;
6
5
  selected?: boolean;
7
6
  addClass?: string;
8
7
  notimeout?: boolean;
9
- size?: 'sm' | 'md' | 'lg';
10
8
  click?: (args?: any) => void;
9
+ type?: "raw" | "pop" | "ripple";
11
10
  children?: ReactNode;
12
11
  };
13
12
  export declare const Button: React.FC<Props>;
@@ -1,12 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useCallback } from "react";
3
- import useRipple from "./tools/useRipple";
4
- import './style/button.css';
5
- export const Button = ({ index, text, selected, addClass, notimeout, size = 'md', click, children }) => {
3
+ import useRipple from "../tools/useRipple";
4
+ import styles from '../style/button.module.css';
5
+ export const Button = ({ index, text, selected, addClass, notimeout, click, type = "raw", children }) => {
6
6
  const buttonRef = useRef(null);
7
7
  const handleRipple = useRipple();
8
8
  const handleButtonClick = useCallback((event) => {
9
- handleRipple(event, buttonRef);
9
+ if (type === 'ripple')
10
+ handleRipple(event, buttonRef);
10
11
  if (notimeout) {
11
12
  click === null || click === void 0 ? void 0 : click(event);
12
13
  return;
@@ -15,5 +16,5 @@ export const Button = ({ index, text, selected, addClass, notimeout, size = 'md'
15
16
  click === null || click === void 0 ? void 0 : click(event);
16
17
  }, 200);
17
18
  }, [notimeout, click, handleRipple]);
18
- return (_jsx(_Fragment, { children: _jsxs("button", { type: "button", ref: buttonRef, onClick: handleButtonClick, className: `ext-btn ext-btn--${size} _ripple ${addClass !== null && addClass !== void 0 ? addClass : 'ext-btn--primary'}`, "aria-pressed": selected, children: [children, text && _jsx("div", { className: "ext-btn-label", children: text })] }, index) }));
19
+ return (_jsx(_Fragment, { children: _jsxs("button", { type: "button", ref: buttonRef, onClick: handleButtonClick, className: `${styles.button} ${styles.ApplyRipple} ${addClass !== null && addClass !== void 0 ? addClass : styles.btnPrimary}${type === 'pop' ? ` ${styles.buttonPop}` : ''}`, "aria-pressed": selected, children: [children, text && _jsx("div", { className: styles.btnLabel, children: text })] }, index) }));
19
20
  };
@@ -0,0 +1,100 @@
1
+ /* EHSCAN Base Button */
2
+ .button {
3
+ display: inline-flex;
4
+ align-items: center;
5
+ justify-content: center;
6
+ gap: var(--ext-btn-gap, 0.5rem);
7
+ font-family: inherit;
8
+ font-size: var(--ext-btn-font-size, 1rem);
9
+ font-weight: var(--ext-btn-font-weight, 500);
10
+ color: var(--ext-btn-color, #fff);
11
+ background-color: var(--btn-bg, #007aff);
12
+ border: none;
13
+ border-radius: var(--ext-btn-radius, 18px);
14
+ padding: var(--ext-btn-padding, 5px 10px 5px 5px);
15
+ width: var(--ext-btn-width, fit-content);
16
+ height: var(--ext-btn-height, auto);
17
+ cursor: pointer;
18
+ transition: var(--ext-btn-transition, all 0.2s ease);
19
+ text-align: center;
20
+ text-decoration: none;
21
+ user-select: none;
22
+ line-height: var(--ext-btn-colorbtn-line-height, 1.5);
23
+ }
24
+
25
+ .button:focus-visible {
26
+ outline: 2px solid var(--ext-btn-bg, #007aff);
27
+ outline-offset: 2px;
28
+ }
29
+
30
+ .button:disabled,
31
+ .button[aria-disabled="true"] {
32
+ opacity: 0.6;
33
+ cursor: not-allowed;
34
+ }
35
+
36
+ .button:hover:not(:disabled):not([aria-disabled="true"]) {
37
+ filter: brightness(0.9);
38
+ }
39
+
40
+ .buttonPop:active:not(:disabled):not([aria-disabled="true"]) {
41
+ transform: scale(var(--ext-btn-pop-scale, .95));
42
+ }
43
+
44
+ /* Variants */
45
+ .btnPrimary {
46
+ --ext-btn-bg: #007aff;
47
+ --ext-btn-color: #fff;
48
+ }
49
+
50
+ .ext-btn--secondary {
51
+ --btn-bg: #e5e5ea;
52
+ --btn-color: #111;
53
+ }
54
+
55
+ .ext-btn--outline {
56
+ --btn-bg: transparent;
57
+ --btn-color: #007aff;
58
+ }
59
+
60
+ .ext-btn--ghost {
61
+ --btn-bg: transparent;
62
+ --btn-color: #007aff;
63
+ }
64
+
65
+ .ext-btn--danger {
66
+ --btn-bg: #ff3b30;
67
+ --btn-color: #fff;
68
+ }
69
+
70
+ /* Loading state */
71
+ .ext-btn--loading {
72
+ pointer-events: none;
73
+ opacity: 0.8;
74
+ }
75
+
76
+ /* Icon and label wrappers */
77
+ .ext-btn-icon {
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ font-size: 1.1em;
82
+ }
83
+
84
+ .btnLabel {
85
+ display: inline-block;
86
+ white-space: nowrap;
87
+ }
88
+
89
+ /* --------------
90
+ Apply Ripple effect
91
+ ---------------*/
92
+ .ApplyRipple {
93
+ box-shadow: var(--ripple-box-shadow, rgb(100 100 111 / 20%) 0px 7px 29px 0px);
94
+ position: relative;
95
+ overflow: hidden;
96
+ display: flex;
97
+ align-items: center;
98
+ justify-content: center;
99
+ user-select: none;
100
+ }
@@ -0,0 +1,20 @@
1
+ /* --------------
2
+ Ripple effect
3
+ ---------------*/
4
+ .ripple {
5
+ background: var(--ext-ripple-effect-bck, rgb(0 0 0 / 15%));
6
+ position: absolute;
7
+ border-radius: 50%;
8
+ transform: scale(0);
9
+ animation: ripple-animation 0.6s linear;
10
+ pointer-events: none;
11
+ transform-origin: center center;
12
+ will-change: transform, opacity;
13
+ }
14
+
15
+ @keyframes ripple-animation {
16
+ to {
17
+ transform: scale(4);
18
+ opacity: 0;
19
+ }
20
+ }
@@ -1,4 +1,5 @@
1
1
  import { useCallback } from 'react';
2
+ import styles from '../style/ripple.module.css';
2
3
  const useRipple = () => {
3
4
  const handleRipple = useCallback((event, buttonRef) => {
4
5
  const button = buttonRef.current;
@@ -12,7 +13,7 @@ const useRipple = () => {
12
13
  ripple.style.width = ripple.style.height = `${size}px`;
13
14
  ripple.style.left = `${x}px`;
14
15
  ripple.style.top = `${y}px`;
15
- ripple.className = 'ripple';
16
+ ripple.className = styles.ripple;
16
17
  button.appendChild(ripple);
17
18
  setTimeout(() => ripple.remove(), 600);
18
19
  }, []);
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useRef, useEffect, useState } from "react";
3
3
  import { useDraggable } from "../tools/useDraggable"; // adjust path as needed
4
- import styles from './style/window.module.css';
4
+ import styles from '../style/window.module.css';
5
5
  export const Window = ({ trackMove, open, initialPosition = { x: 600, y: 100 }, initialWidth = 400, initialBodyPadding = 20, header, body, footer, onClose, }) => {
6
6
  const targetRef = useRef(null);
7
7
  const headerRef = useRef(null);
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "ehscan-react-components",
3
- "version": "0.1.46",
3
+ "version": "0.1.48",
4
4
  "description": "components",
5
5
  "main": "dist/Components.js",
6
6
  "types": "dist/Components.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc && npm run copy-css",
9
- "copy-css": "rsync -a src/style/ dist/style/",
9
+ "copy-css": "rsync -a src/style/ dist/style/",
10
10
  "prepublishOnly": "npm run build"
11
11
  },
12
12
  "keywords": [
package/dist/Window.d.ts DELETED
@@ -1,17 +0,0 @@
1
- import React from "react";
2
- import './style/window.css';
3
- export interface Props {
4
- trackMove?: (args?: any) => void;
5
- open: boolean;
6
- initialPosition?: {
7
- x: number;
8
- y: number;
9
- };
10
- initialWidth?: number;
11
- initialBodyPadding?: number;
12
- header?: React.ReactNode;
13
- body?: React.ReactNode;
14
- footer?: React.ReactNode;
15
- onClose?: () => void;
16
- }
17
- export declare const Window: React.FC<Props>;
package/dist/Window.js DELETED
@@ -1,35 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useRef, useEffect, useState } from "react";
3
- import { useDraggable } from "./tools/useDraggable"; // adjust path as needed
4
- import './style/window.css';
5
- export const Window = ({ trackMove, open, initialPosition = { x: 600, y: 100 }, initialWidth = 400, initialBodyPadding = 20, header, body, footer, onClose, }) => {
6
- const targetRef = useRef(null);
7
- const headerRef = useRef(null);
8
- const resizeHandleRef = useRef(null);
9
- const bodyRef = useRef(null);
10
- const footerRef = useRef(null);
11
- const [bodyPadding] = useState(initialBodyPadding);
12
- const [windowWidth] = useState(initialWidth);
13
- useDraggable(open, targetRef, headerRef, bodyRef, resizeHandleRef, bodyPadding, trackMove);
14
- useEffect(() => {
15
- if (!bodyRef.current || !targetRef.current || !headerRef.current)
16
- return;
17
- const headerHeight = headerRef.current.offsetHeight;
18
- const topPosition = targetRef.current.getBoundingClientRect().top;
19
- const availableHeight = window.innerHeight - topPosition - 20; // 20px bottom margin
20
- const bodyMaxHeight = Math.max(100, availableHeight - headerHeight - 2 * bodyPadding);
21
- bodyRef.current.style.maxHeight = `${bodyMaxHeight}px`;
22
- bodyRef.current.style.overflowY = "auto";
23
- }, [bodyPadding]);
24
- const [fadeIn, setFadeIn] = useState(false);
25
- useEffect(() => {
26
- if (open === undefined)
27
- return;
28
- setTimeout(() => {
29
- setFadeIn(open);
30
- }, 0);
31
- }, [open]);
32
- if (!open)
33
- return null;
34
- return (_jsxs("div", { ref: targetRef, className: `ext-window${fadeIn ? ' fadein' : ''}`, style: { left: `${initialPosition.x}px`, top: `${initialPosition.y}px`, minWidth: `${windowWidth}px` }, children: [_jsx("div", { ref: headerRef, className: "ext-window-header", children: header !== null && header !== void 0 ? header : (_jsxs(_Fragment, { children: [_jsx("div", { className: "ext-window-drag-handle", children: "||" }), _jsx("div", { className: "ext-window-header-title", children: "Header" }), _jsx("div", { onClick: onClose, children: "close" })] })) }), _jsx("div", { ref: bodyRef, className: "ext-window-body _ewb", style: { padding: `${bodyPadding}px` }, children: body !== null && body !== void 0 ? body : _jsx(_Fragment, { children: "Body" }) }), footer && (_jsx("div", { ref: footerRef, className: "ext-window-footer", children: footer })), _jsx("div", { className: "resize-handle", ref: resizeHandleRef })] }));
35
- };
@@ -1,132 +0,0 @@
1
- /* EHSCAN Base Button - Refactored */
2
- .ext-btn {
3
- /* Core variables with fallbacks */
4
- /* --btn-bg: #007aff;
5
- --btn-color: #fff;
6
- --btn-radius: 18px;
7
- --btn-padding: 0.5rem;
8
- --btn-width: fit-content;
9
- --btn-height: auto;
10
- --btn-font-size: 1rem;
11
- --btn-font-weight: 500;
12
- --btn-transition: all 0.2s ease;
13
- --btn-line-height: 1.5;
14
- --btn-gap: 0.5rem;
15
- --ripple-box-shadow: rgb(100 100 111 / 20%) 0px 7px 29px 0px;
16
- --ripple-effect-bck: rgb(0 0 0 / 15%); */
17
-
18
- display: inline-flex;
19
- align-items: center;
20
- justify-content: center;
21
- gap: var(--btn-gap, 0.5rem);
22
- font-family: inherit;
23
- font-size: var(--btn-font-size, 1rem);
24
- font-weight: var(--btn-font-weight, 500);
25
- color: var(--btn-color, #fff);
26
- background-color: var(--btn-bg, #007aff);
27
- border: none;
28
- border-radius: var(--btn-radius, 18px);
29
- padding: var(--btn-padding, 0.5rem);
30
- width: var(--btn-width, fit-content);
31
- height: var(--btn-height, auto);
32
- cursor: pointer;
33
- transition: var(--btn-transition, all 0.2s ease);
34
- text-align: center;
35
- text-decoration: none;
36
- user-select: none;
37
- line-height: var(--btn-line-height, 1.5);
38
- }
39
-
40
- .ext-btn:focus-visible {
41
- outline: 2px solid var(--btn-bg, #007aff);
42
- outline-offset: 2px;
43
- }
44
-
45
- .ext-btn:disabled,
46
- .ext-btn[aria-disabled="true"] {
47
- opacity: 0.6;
48
- cursor: not-allowed;
49
- }
50
-
51
- .ext-btn:hover:not(:disabled):not([aria-disabled="true"]) {
52
- filter: brightness(0.9);
53
- }
54
-
55
- .ext-btn:active:not(:disabled):not([aria-disabled="true"]) {
56
- transform: scale(0.97);
57
- }
58
-
59
- /* Variants */
60
- .ext-btn--primary {
61
- --btn-bg: #007aff;
62
- --btn-color: #fff;
63
- }
64
-
65
- .ext-btn--secondary {
66
- --btn-bg: #e5e5ea;
67
- --btn-color: #111;
68
- }
69
-
70
- .ext-btn--outline {
71
- --btn-bg: transparent;
72
- --btn-color: #007aff;
73
- }
74
-
75
- .ext-btn--ghost {
76
- --btn-bg: transparent;
77
- --btn-color: #007aff;
78
- }
79
-
80
- .ext-btn--danger {
81
- --btn-bg: #ff3b30;
82
- --btn-color: #fff;
83
- }
84
-
85
- /* Loading state */
86
- .ext-btn--loading {
87
- pointer-events: none;
88
- opacity: 0.8;
89
- }
90
-
91
- /* Icon and label wrappers */
92
- .ext-btn-icon {
93
- display: flex;
94
- align-items: center;
95
- justify-content: center;
96
- font-size: 1.1em;
97
- }
98
-
99
- .ext-btn-label {
100
- display: inline-block;
101
- white-space: nowrap;
102
- }
103
-
104
- /* Ripple effect */
105
- ._ripple {
106
- font-weight: var(--btn-font-weight, 500);
107
- box-shadow: var(--ripple-box-shadow, rgb(100 100 111 / 20%) 0px 7px 29px 0px);
108
- position: relative;
109
- overflow: hidden;
110
- display: flex;
111
- align-items: center;
112
- justify-content: center;
113
- user-select: none;
114
- }
115
-
116
- .ripple {
117
- background: var(--ripple-effect-bck, rgb(0 0 0 / 15%));
118
- position: absolute;
119
- border-radius: 50%;
120
- transform: scale(0);
121
- animation: ripple-animation 0.6s linear;
122
- pointer-events: none;
123
- transform-origin: center center;
124
- will-change: transform, opacity;
125
- }
126
-
127
- @keyframes ripple-animation {
128
- to {
129
- transform: scale(4);
130
- opacity: 0;
131
- }
132
- }
@@ -1,82 +0,0 @@
1
- /* 🪟 ExtWindow Base */
2
- .ext-window {
3
- /* --ext-window-bck-color: white;
4
- --ext-window-width: 400px;
5
- --ext-window-min-height: 300px;
6
- --ext-window-border-radius: 12px;
7
- --ext-window-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
8
- --ext-window-opacity: 0;
9
- --ext-window-transition: opacity 0.4s ease-in-out; */
10
- background-color: var(--ext-window-bck-color, white);
11
- position: absolute;
12
- width: var(--ext-window-width, 400px);
13
- min-height: var(--ext-window-min-height, 300px);
14
- border-radius: var(--ext-window-border-radius, 12px);
15
- box-shadow: var(--ext-window-shadow, rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px);
16
- opacity: var(--ext-window-opacity, 0);
17
- transition: var(--ext-window-transition, opacity 0.4s ease-in-out);
18
- user-select: none;
19
- }
20
-
21
- .ext-window.fadein {
22
- opacity: 1;
23
- }
24
-
25
- /* Header */
26
- .ext-window-header {
27
- border-radius: var(--ext-window-border-radius, 12px) var(--ext-window-border-radius, 12px) 0 0;
28
- background-color: var(--ext-window-header-bck-color, transparent);
29
- height: var(--ext-window-header-height, 50px);
30
- cursor: pointer;
31
- display: flex;
32
- }
33
-
34
- /* Body */
35
- .ext-window-body {
36
- background-color: var(--ext-window-body-bck, transparent);
37
- min-height: var(--ext-window-min-height, 200px);
38
- overflow: auto;
39
- }
40
-
41
- /* Footer */
42
- .ext-window-footer {
43
- background-color: var(--ext-window-footer-bck, transparent);
44
- height: var(--ext-window-footer-height, 50px);
45
- border-radius: 0 0 var(--ext-window-border-radius, 12px) var(--ext-window-border-radius, 12px);
46
- }
47
-
48
- /* Scrollbars for WebKit */
49
- ._ewb::-webkit-scrollbar {
50
- width: 6px;
51
- background-color: var(--ext-window-bck-color, white);
52
- }
53
-
54
- ._ewb:hover::-webkit-scrollbar {
55
- width: 6px;
56
- }
57
-
58
- ._ewb::-webkit-scrollbar-thumb {
59
- background-color: var(--ext-window-scrollbar-thumb, white);
60
- border-radius: 12px;
61
- }
62
-
63
- ._ewb:hover::-webkit-scrollbar-thumb {
64
- background-color: var(--ext-window-scrollbar-thumb-hover, #555);
65
- }
66
-
67
- /* Resize handle */
68
- .resize-handle {
69
- width: 7px;
70
- height: 120px;
71
- position: absolute;
72
- top: 50%;
73
- right: 0;
74
- transform: translateY(-50%);
75
- cursor: e-resize;
76
- background-color: transparent;
77
- border-radius: 22px 0 0 22px;
78
- }
79
-
80
- .resize-handle:hover {
81
- background: var(--ext-window-resize-bck, darkgrey);
82
- }