wenay-react2 1.0.38 → 1.0.39
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/lib/common/src/components/Input.d.ts +25 -6
- package/lib/common/src/components/Input.js +27 -8
- package/lib/common/src/components/Settings/SettingsDialog.js +12 -1
- package/lib/common/src/grid/columnState/ColumnDots.d.ts +1 -1
- package/lib/common/src/grid/columnState/ColumnDots.js +1 -1
- package/lib/common/src/grid/columnState/ColumnsMenu.js +10 -18
- package/lib/common/src/menu/menuMouse.d.ts +17 -0
- package/lib/common/src/menu/menuMouse.js +70 -3
- package/lib/common/src/styles/tokens.d.ts +79 -1
- package/lib/common/src/styles/tokens.js +79 -1
- package/lib/style/style.css +122 -50
- package/lib/style/tokens.css +76 -2
- package/package.json +1 -1
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
export
|
|
2
|
+
export type TextInputPanelProps = {
|
|
3
3
|
callback: (txt: string) => void;
|
|
4
4
|
name?: string;
|
|
5
5
|
txt?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function
|
|
6
|
+
};
|
|
7
|
+
export declare function useTextInputPanel({ callback, txt }: Pick<TextInputPanelProps, "callback" | "txt">): {
|
|
8
|
+
getValue: () => string;
|
|
9
|
+
setValue: (next: string) => void;
|
|
10
|
+
submit: () => void;
|
|
11
|
+
inputProps: {
|
|
12
|
+
defaultValue: string;
|
|
13
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function TextInputPanel({ callback, name, txt }: TextInputPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare function TextInputModal({ callback, name, outClick, keyForSave, txt }: TextInputPanelProps & {
|
|
8
18
|
outClick: () => any;
|
|
9
19
|
keyForSave?: string;
|
|
10
20
|
}): import("react/jsx-runtime").JSX.Element;
|
|
11
|
-
export declare function FileInputModal({ callback, name, outClick, keyForSave }:
|
|
21
|
+
export declare function FileInputModal({ callback, name, outClick, keyForSave }: FileInputPanelProps & {
|
|
12
22
|
outClick: () => any;
|
|
13
23
|
keyForSave?: string;
|
|
14
24
|
}): import("react/jsx-runtime").JSX.Element;
|
|
15
|
-
export
|
|
25
|
+
export type FileInputPanelProps = {
|
|
16
26
|
callback: (file: File | null) => void;
|
|
17
27
|
name?: string;
|
|
18
|
-
}
|
|
28
|
+
};
|
|
29
|
+
export declare function useFileInputPanel({ callback }: Pick<FileInputPanelProps, "callback">): {
|
|
30
|
+
getFile: () => File | null;
|
|
31
|
+
setFile: (next: File | null) => void;
|
|
32
|
+
submit: () => void;
|
|
33
|
+
inputProps: {
|
|
34
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export declare function FileInputPanel({ callback, name }: FileInputPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
19
38
|
export declare function FreeModal({ outClick, children, zIndex, size, keyForSave }: {
|
|
20
39
|
zIndex?: number;
|
|
21
40
|
outClick: () => any;
|
|
@@ -7,11 +7,21 @@ function ModalWrapper({ outClick, children, zIndex, size = { height: 150, width:
|
|
|
7
7
|
const defaultPosition = position ?? { y: -(size.height / 2), x: -(size.width / 2) };
|
|
8
8
|
return _jsx(OutsideClickArea, { outsideClick: outClick, style: { position: "absolute", top: "50%", left: "50%" }, children: _jsx(FloatingWindow, { keyForSave: keyForSave, size: size, zIndex: zIndex, position: defaultPosition, className: "fon border fonLight", moveOnlyHeader: true, children: children }) });
|
|
9
9
|
}
|
|
10
|
-
export function
|
|
10
|
+
export function useTextInputPanel({ callback, txt = "" }) {
|
|
11
11
|
const txtName = useRef(txt);
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
return {
|
|
13
|
+
getValue: () => txtName.current,
|
|
14
|
+
setValue: (next) => { txtName.current = next; },
|
|
15
|
+
submit: () => callback(txtName.current),
|
|
16
|
+
inputProps: {
|
|
17
|
+
defaultValue: txtName.current,
|
|
18
|
+
onChange: (e) => { txtName.current = e.target.value; },
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function TextInputPanel({ callback, name = "", txt = "" }) {
|
|
23
|
+
const input = useTextInputPanel({ callback, txt });
|
|
24
|
+
return _jsxs("div", { className: "maxSize", style: { padding: 20, }, children: [_jsx("label", { children: name }), _jsx("input", { type: "text", style: { width: "100%" }, ...input.inputProps }), _jsx("div", { style: { marginTop: 20 }, className: "msTradeAlt msTradeActive", onClick: input.submit, children: "send" })] });
|
|
15
25
|
}
|
|
16
26
|
export function TextInputModal({ callback, name, outClick, keyForSave = "TextInputModal", txt }) {
|
|
17
27
|
return _jsx(ModalWrapper, { outClick: outClick, keyForSave: keyForSave, size: { height: 150, width: 300 }, position: { y: -150, x: -250 }, children: _jsx(TextInputPanel, { callback: callback, name: name, txt: txt }) });
|
|
@@ -19,11 +29,20 @@ export function TextInputModal({ callback, name, outClick, keyForSave = "TextInp
|
|
|
19
29
|
export function FileInputModal({ callback, name, outClick, keyForSave = "FileInputModal" }) {
|
|
20
30
|
return _jsx(ModalWrapper, { outClick: outClick, keyForSave: keyForSave, size: { height: 150, width: 300 }, position: { y: -150, x: -250 }, children: _jsx(FileInputPanel, { callback: callback, name: name }) });
|
|
21
31
|
}
|
|
22
|
-
export function
|
|
32
|
+
export function useFileInputPanel({ callback }) {
|
|
23
33
|
const file = useRef(null);
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
return {
|
|
35
|
+
getFile: () => file.current,
|
|
36
|
+
setFile: (next) => { file.current = next; },
|
|
37
|
+
submit: () => callback(file.current),
|
|
38
|
+
inputProps: {
|
|
39
|
+
onChange: (e) => { file.current = e.target.files?.[0] ?? null; },
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function FileInputPanel({ callback, name = "" }) {
|
|
44
|
+
const input = useFileInputPanel({ callback });
|
|
45
|
+
return _jsxs("div", { className: "maxSize", style: { padding: 20, }, children: [_jsx("label", { children: name }), _jsx("input", { type: "file", style: { width: "100%" }, ...input.inputProps }), _jsx("div", { style: { marginTop: 20 }, className: "msTradeAlt msTradeActive", onClick: input.submit, children: "send" })] });
|
|
27
46
|
}
|
|
28
47
|
export function FreeModal({ outClick, children, zIndex, size = { height: 150, width: 300 }, keyForSave = "FreeModal" }) {
|
|
29
48
|
return _jsx(ModalWrapper, { outClick: outClick, keyForSave: keyForSave, size: size, zIndex: zIndex, children: children });
|
|
@@ -233,6 +233,7 @@ export function SettingsDialog(props) {
|
|
|
233
233
|
const [navWidth, setNavWidth] = useState(() => clampSettingsNavWidth(settingsDialogLayout.navWidth));
|
|
234
234
|
const [navResizing, setNavResizing] = useState(false);
|
|
235
235
|
const searchInputRef = useRef(null);
|
|
236
|
+
const searchBoxRef = useRef(null);
|
|
236
237
|
const navResizeRef = useRef(null);
|
|
237
238
|
const navWidthRef = useRef(navWidth);
|
|
238
239
|
updateBy(registry);
|
|
@@ -379,6 +380,16 @@ export function SettingsDialog(props) {
|
|
|
379
380
|
setHistoryOpen(false);
|
|
380
381
|
searchInputRef.current?.focus();
|
|
381
382
|
}
|
|
383
|
+
function closeHistoryWhenSearchFocusLeaves(e) {
|
|
384
|
+
const next = e.relatedTarget;
|
|
385
|
+
if (next && e.currentTarget.contains(next))
|
|
386
|
+
return;
|
|
387
|
+
window.setTimeout(() => {
|
|
388
|
+
const box = searchBoxRef.current;
|
|
389
|
+
if (box == null || !box.contains(document.activeElement))
|
|
390
|
+
setHistoryOpen(false);
|
|
391
|
+
}, 0);
|
|
392
|
+
}
|
|
382
393
|
function cycleTreeTool() {
|
|
383
394
|
if (treeToolState == "expanded")
|
|
384
395
|
collapseOutsideCurrent();
|
|
@@ -415,7 +426,7 @@ export function SettingsDialog(props) {
|
|
|
415
426
|
toggleExpanded(key);
|
|
416
427
|
} }), _jsx("span", { className: "wenayDlgTreeLabel", children: renderHighlightedLabel(node.section.name, searchTerms) })] }), hasChildren && isOpen && node.children.map(renderTreeNode)] }, key);
|
|
417
428
|
}
|
|
418
|
-
return _jsxs(_Fragment, { children: [_jsx("span", { role: "button", tabIndex: 0, "aria-label": props.trigger == null ? "Open settings" : undefined, onClick: openDialog, onKeyDown: onTriggerKeyDown, style: { display: "inline-block", cursor: "pointer" }, children: props.trigger ?? _jsx(DefaultSettingsTrigger, {}) }), open && createPortal(_jsx("div", { className: "wenayDlgScrim", children: _jsx(OutsideClickArea, { outsideClick: () => setOpen(false), status: open, className: "wenayDlgOutside", children: _jsx(FloatingWindowBase, { className: "wenayDlgWindow", size: settingsDialogSize, position: settingsDialogPosition, zIndex: 10000, moveOnlyHeader: true, overflow: false, onCLickClose: () => setOpen(false), header: _jsx("div", { className: "wenayDlgHeader", children: "Settings" }), children: _jsxs("div", { className: classNames(["wenayDlg", navResizing && "wenayDlg_resizing"]), children: [_jsxs("div", { className: "wenayDlgNav", style: { width: navWidth }, children: [_jsxs("div", { className: "wenayDlgNavTop", children: [_jsxs("div", { className: "wenayDlgSearchBox", children: [_jsx("input", { ref: searchInputRef, className: "wenayDlgSearch", value: search, placeholder: "Search", "aria-label": "Search settings", onFocus: () => setHistoryOpen(searchHistory.length != 0), onChange: e => {
|
|
429
|
+
return _jsxs(_Fragment, { children: [_jsx("span", { role: "button", tabIndex: 0, "aria-label": props.trigger == null ? "Open settings" : undefined, onClick: openDialog, onKeyDown: onTriggerKeyDown, style: { display: "inline-block", cursor: "pointer" }, children: props.trigger ?? _jsx(DefaultSettingsTrigger, {}) }), open && createPortal(_jsx("div", { className: "wenayDlgScrim", children: _jsx(OutsideClickArea, { outsideClick: () => setOpen(false), status: open, className: "wenayDlgOutside", children: _jsx(FloatingWindowBase, { className: "wenayDlgWindow", size: settingsDialogSize, position: settingsDialogPosition, zIndex: 10000, moveOnlyHeader: true, overflow: false, onCLickClose: () => setOpen(false), header: _jsx("div", { className: "wenayDlgHeader", children: "Settings" }), children: _jsxs("div", { className: classNames(["wenayDlg", navResizing && "wenayDlg_resizing"]), children: [_jsxs("div", { className: "wenayDlgNav", style: { width: navWidth }, children: [_jsxs("div", { className: "wenayDlgNavTop", children: [_jsxs("div", { ref: searchBoxRef, className: "wenayDlgSearchBox", onBlur: closeHistoryWhenSearchFocusLeaves, children: [_jsx("input", { ref: searchInputRef, className: "wenayDlgSearch", value: search, placeholder: "Search", "aria-label": "Search settings", onFocus: () => setHistoryOpen(searchHistory.length != 0), onChange: e => {
|
|
419
430
|
setSearch(e.currentTarget.value);
|
|
420
431
|
setHistoryOpen(searchHistory.length != 0);
|
|
421
432
|
}, onKeyDown: e => {
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { ColumnStateController } from './columnState';
|
|
3
3
|
export declare function ColumnDots(p: {
|
|
4
4
|
state: ColumnStateController;
|
|
5
|
-
/** max simultaneous dots (default
|
|
5
|
+
/** max simultaneous dots (default 8) */
|
|
6
6
|
max?: number;
|
|
7
7
|
className?: string;
|
|
8
8
|
style?: React.CSSProperties;
|
|
@@ -25,7 +25,7 @@ export function ColumnDots(p) {
|
|
|
25
25
|
const cfg = p.state.api.useConfig();
|
|
26
26
|
const cols = p.state.columns;
|
|
27
27
|
const byKey = new Map(cols.map(c => [c.key, c]));
|
|
28
|
-
const max = p.max ??
|
|
28
|
+
const max = p.max ?? 8;
|
|
29
29
|
const order = cfg.order;
|
|
30
30
|
const n = order.length;
|
|
31
31
|
const visibleKeys = order.filter(k => cfg.visible[k] != false);
|
|
@@ -22,22 +22,17 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
22
22
|
// comes back to life when the column returns. No ag-grid, no storage here.
|
|
23
23
|
import { useRef } from 'react';
|
|
24
24
|
import { useReorder } from '../../hooks/useReorder';
|
|
25
|
+
function colsMenuClass(parts) {
|
|
26
|
+
return parts.filter(Boolean).join(' ');
|
|
27
|
+
}
|
|
25
28
|
function MenuButton(p) {
|
|
26
29
|
const it = p.item;
|
|
27
30
|
const disabled = it.state == 'disabled';
|
|
28
31
|
const on = it.state == 'on';
|
|
32
|
+
const stateClass = disabled ? 'wenayColsMenuBtn_disabled' : on ? 'wenayColsMenuBtn_on' : 'wenayColsMenuBtn_off';
|
|
29
33
|
const abbr = p.compact && it.icon == null
|
|
30
|
-
? _jsx("span", {
|
|
31
|
-
return _jsxs("div", { title: it.title, onClick: disabled ? undefined : e => p.onItem?.(it.key, e), onMouseDown: p.drag?.onMouseDown, onTouchStart: p.drag?.onTouchStart, style: {
|
|
32
|
-
position: 'relative', display: 'flex', alignItems: 'center', gap: 4,
|
|
33
|
-
padding: '3px 9px', borderRadius: 6, fontSize: 12, lineHeight: '16px',
|
|
34
|
-
whiteSpace: 'nowrap', cursor: disabled ? 'default' : 'pointer',
|
|
35
|
-
...(disabled ? { border: '1px dashed #d0d7de', background: '#f6f8fa', color: '#c4ccd4' }
|
|
36
|
-
: on ? { border: '1px solid #24292f', background: '#24292f', color: '#fff' }
|
|
37
|
-
: { border: '1px solid #d0d7de', background: '#fff', color: '#8c959f', textDecoration: 'line-through' }),
|
|
38
|
-
...(it.fixed ? { boxShadow: '0 0 0 2px #eaeef2' } : null),
|
|
39
|
-
...p.style,
|
|
40
|
-
}, children: [it.icon != null && _jsx("span", { style: { display: 'inline-flex', alignItems: 'center' }, children: it.icon }), abbr, !p.compact && _jsx("span", { children: it.short ?? it.title }), it.marks != null && _jsx("span", { style: { fontSize: 9, opacity: 0.9 }, children: it.marks })] });
|
|
34
|
+
? _jsx("span", { className: 'wenayColsMenuAbbr', children: (it.short ?? it.title).slice(0, 3) }) : null;
|
|
35
|
+
return _jsxs("div", { title: it.title, onClick: disabled ? undefined : e => p.onItem?.(it.key, e), onMouseDown: p.drag?.onMouseDown, onTouchStart: p.drag?.onTouchStart, className: colsMenuClass(['wenayColsMenuBtn', stateClass, it.fixed && 'wenayColsMenuBtn_fixed', p.className]), style: p.style, children: [it.icon != null && _jsx("span", { className: 'wenayColsMenuIcon', children: it.icon }), abbr, !p.compact && _jsx("span", { className: 'wenayColsMenuLabel', children: it.short ?? it.title }), it.marks != null && _jsx("span", { className: 'wenayColsMenuMarks', children: it.marks })] });
|
|
41
36
|
}
|
|
42
37
|
/** The presentation layer: renders the buttons in the given order, reports
|
|
43
38
|
* clicks (onItem) and drag-reorders (onMove) - never interprets either.
|
|
@@ -61,7 +56,7 @@ export function MenuStrip(p) {
|
|
|
61
56
|
return;
|
|
62
57
|
p.onItem?.(key, e);
|
|
63
58
|
}
|
|
64
|
-
return _jsxs("div", { className: p.className, style:
|
|
59
|
+
return _jsxs("div", { className: colsMenuClass(['wenayColsMenu', p.className]), style: p.style, children: [_jsx("div", { ref: reorder.listRef, className: 'wenayColsMenuList', children: p.items.map(it => {
|
|
65
60
|
const r = reorder.item(it.key);
|
|
66
61
|
const drag = {
|
|
67
62
|
onMouseDown: (e) => {
|
|
@@ -70,12 +65,9 @@ export function MenuStrip(p) {
|
|
|
70
65
|
},
|
|
71
66
|
onTouchStart: r.props.onTouchStart,
|
|
72
67
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
: r.active ? { transition: 'transform 0.15s ease' } : null),
|
|
77
|
-
} }, it.key);
|
|
78
|
-
}) }), !!p.tail?.length && _jsxs(_Fragment, { children: [_jsx("div", { style: { width: 1, alignSelf: 'stretch', margin: '1px 2px', background: '#d0d7de' } }), p.tail.map(it => _jsx(MenuButton, { item: it, onItem: p.onItem, compact: p.compact }, it.key))] })] });
|
|
68
|
+
const dragClass = r.dragging ? 'wenayColsMenuBtn_dragging' : r.active ? 'wenayColsMenuBtn_shift' : undefined;
|
|
69
|
+
return _jsx(MenuButton, { item: it, onItem: onItem, drag: drag, compact: p.compact, className: dragClass, style: r.style }, it.key);
|
|
70
|
+
}) }), !!p.tail?.length && _jsxs(_Fragment, { children: [_jsx("div", { className: 'wenayColsMenuDivider' }), p.tail.map(it => _jsx(MenuButton, { item: it, onItem: p.onItem, compact: p.compact }, it.key))] })] });
|
|
79
71
|
}
|
|
80
72
|
/** The binding layer: MenuStrip fed by a ColumnStateController. Buttons follow
|
|
81
73
|
* config.order (the grid mirror is free: both sides subscribe to the same
|
|
@@ -28,6 +28,21 @@ export type ContextMenuLayerProps = {
|
|
|
28
28
|
onConsume?: () => void;
|
|
29
29
|
className?: (active?: boolean) => string;
|
|
30
30
|
};
|
|
31
|
+
export type ContextMenuStatsSnapshot = {
|
|
32
|
+
openAt: number;
|
|
33
|
+
openAtPoint: number;
|
|
34
|
+
legacyLayer: number;
|
|
35
|
+
close: number;
|
|
36
|
+
replace: number;
|
|
37
|
+
empty: number;
|
|
38
|
+
sources: Record<string, number>;
|
|
39
|
+
layers: Record<string, number>;
|
|
40
|
+
};
|
|
41
|
+
export type ContextMenuStats = {
|
|
42
|
+
getSnapshot(): ContextMenuStatsSnapshot;
|
|
43
|
+
reset(): void;
|
|
44
|
+
onChange(cb: (snapshot: ContextMenuStatsSnapshot) => void): () => void;
|
|
45
|
+
};
|
|
31
46
|
export declare function createContextMenu(data?: {
|
|
32
47
|
name?: string;
|
|
33
48
|
}): {
|
|
@@ -51,6 +66,7 @@ export declare function createContextMenu(data?: {
|
|
|
51
66
|
layerId?: string;
|
|
52
67
|
}) => boolean;
|
|
53
68
|
close: () => void;
|
|
69
|
+
stats: ContextMenuStats;
|
|
54
70
|
Layer: ({ children, other, statusOn, onUnClick, onConsume, zIndex, className }: ContextMenuLayerProps) => import("react/jsx-runtime").JSX.Element;
|
|
55
71
|
MenuView: typeof Menu;
|
|
56
72
|
};
|
|
@@ -75,6 +91,7 @@ export declare const contextMenu: {
|
|
|
75
91
|
layerId?: string;
|
|
76
92
|
}) => boolean;
|
|
77
93
|
close: () => void;
|
|
94
|
+
stats: ContextMenuStats;
|
|
78
95
|
Layer: ({ children, other, statusOn, onUnClick, onConsume, zIndex, className }: ContextMenuLayerProps) => import("react/jsx-runtime").JSX.Element;
|
|
79
96
|
MenuView: typeof Menu;
|
|
80
97
|
};
|
|
@@ -32,6 +32,17 @@ export function createContextMenu(data) {
|
|
|
32
32
|
const map = new Map();
|
|
33
33
|
const state = { open: false, items: [], point: { x: 0, y: 0 }, seq: 0 };
|
|
34
34
|
const listeners = new Set();
|
|
35
|
+
const statsListeners = new Set();
|
|
36
|
+
const statsState = {
|
|
37
|
+
openAt: 0,
|
|
38
|
+
openAtPoint: 0,
|
|
39
|
+
legacyLayer: 0,
|
|
40
|
+
close: 0,
|
|
41
|
+
replace: 0,
|
|
42
|
+
empty: 0,
|
|
43
|
+
sources: {},
|
|
44
|
+
layers: {},
|
|
45
|
+
};
|
|
35
46
|
const layers = new Set();
|
|
36
47
|
let layerSeq = 0;
|
|
37
48
|
function emit() {
|
|
@@ -43,6 +54,50 @@ export function createContextMenu(data) {
|
|
|
43
54
|
listeners.add(cb);
|
|
44
55
|
return () => { listeners.delete(cb); };
|
|
45
56
|
}
|
|
57
|
+
function statsSnapshot() {
|
|
58
|
+
return {
|
|
59
|
+
openAt: statsState.openAt,
|
|
60
|
+
openAtPoint: statsState.openAtPoint,
|
|
61
|
+
legacyLayer: statsState.legacyLayer,
|
|
62
|
+
close: statsState.close,
|
|
63
|
+
replace: statsState.replace,
|
|
64
|
+
empty: statsState.empty,
|
|
65
|
+
sources: { ...statsState.sources },
|
|
66
|
+
layers: { ...statsState.layers },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function emitStats() {
|
|
70
|
+
const snapshot = statsSnapshot();
|
|
71
|
+
for (const cb of [...statsListeners])
|
|
72
|
+
cb(snapshot);
|
|
73
|
+
}
|
|
74
|
+
function bumpStat(key) {
|
|
75
|
+
statsState[key] += 1;
|
|
76
|
+
emitStats();
|
|
77
|
+
}
|
|
78
|
+
function bumpMapStat(map, key) {
|
|
79
|
+
if (!key)
|
|
80
|
+
return;
|
|
81
|
+
map[key] = (map[key] ?? 0) + 1;
|
|
82
|
+
}
|
|
83
|
+
const stats = {
|
|
84
|
+
getSnapshot: statsSnapshot,
|
|
85
|
+
reset() {
|
|
86
|
+
statsState.openAt = 0;
|
|
87
|
+
statsState.openAtPoint = 0;
|
|
88
|
+
statsState.legacyLayer = 0;
|
|
89
|
+
statsState.close = 0;
|
|
90
|
+
statsState.replace = 0;
|
|
91
|
+
statsState.empty = 0;
|
|
92
|
+
statsState.sources = {};
|
|
93
|
+
statsState.layers = {};
|
|
94
|
+
emitStats();
|
|
95
|
+
},
|
|
96
|
+
onChange(cb) {
|
|
97
|
+
statsListeners.add(cb);
|
|
98
|
+
return () => { statsListeners.delete(cb); };
|
|
99
|
+
},
|
|
100
|
+
};
|
|
46
101
|
function legacyItems() {
|
|
47
102
|
if (map.has("only"))
|
|
48
103
|
return normalizeItems(map.get("only"));
|
|
@@ -56,28 +111,39 @@ export function createContextMenu(data) {
|
|
|
56
111
|
function close() {
|
|
57
112
|
if (!state.open && state.items.length == 0)
|
|
58
113
|
return;
|
|
114
|
+
bumpStat("close");
|
|
59
115
|
state.open = false;
|
|
60
116
|
state.items = [];
|
|
61
117
|
state.layerId = undefined;
|
|
62
118
|
emit();
|
|
63
119
|
}
|
|
64
|
-
function
|
|
120
|
+
function openMenu(anchor, items, opts = {}, kind) {
|
|
65
121
|
preventNative(anchor);
|
|
66
122
|
const nextItems = normalizeItems(items);
|
|
67
123
|
if (nextItems.length == 0) {
|
|
124
|
+
bumpStat("empty");
|
|
68
125
|
close();
|
|
69
126
|
return false;
|
|
70
127
|
}
|
|
128
|
+
if (state.open)
|
|
129
|
+
bumpStat("replace");
|
|
130
|
+
bumpStat(kind);
|
|
71
131
|
state.open = true;
|
|
72
132
|
state.items = nextItems;
|
|
73
133
|
state.point = anchorPoint(anchor);
|
|
74
134
|
state.source = opts.source;
|
|
75
135
|
state.layerId = opts.layerId ?? anchorLayerId(anchor) ?? [...layers][0];
|
|
136
|
+
bumpMapStat(statsState.sources, state.source);
|
|
137
|
+
bumpMapStat(statsState.layers, state.layerId);
|
|
138
|
+
emitStats();
|
|
76
139
|
emit();
|
|
77
140
|
return true;
|
|
78
141
|
}
|
|
142
|
+
function openAt(anchor, items, opts = {}) {
|
|
143
|
+
return openMenu(anchor, items, opts, "openAt");
|
|
144
|
+
}
|
|
79
145
|
function openAtPoint(point, items, opts = {}) {
|
|
80
|
-
return
|
|
146
|
+
return openMenu(point, items, opts, "openAtPoint");
|
|
81
147
|
}
|
|
82
148
|
function getState() {
|
|
83
149
|
return {
|
|
@@ -123,7 +189,7 @@ export function createContextMenu(data) {
|
|
|
123
189
|
return other ? normalizeItems(other()) : legacyItems();
|
|
124
190
|
}
|
|
125
191
|
function openQueued(anchor) {
|
|
126
|
-
const opened =
|
|
192
|
+
const opened = openMenu(anchor, queuedItems(), { source: "layer", layerId }, "legacyLayer");
|
|
127
193
|
if (opened) {
|
|
128
194
|
map.clear();
|
|
129
195
|
onConsume?.();
|
|
@@ -194,6 +260,7 @@ export function createContextMenu(data) {
|
|
|
194
260
|
openAt,
|
|
195
261
|
openAtPoint,
|
|
196
262
|
close,
|
|
263
|
+
stats,
|
|
197
264
|
Layer,
|
|
198
265
|
MenuView: Menu,
|
|
199
266
|
};
|
|
@@ -75,7 +75,85 @@ export declare const tokens: {
|
|
|
75
75
|
readonly popRadius: "8px";
|
|
76
76
|
readonly popShadow: "0 8px 28px rgba(0, 0, 0, 0.5)";
|
|
77
77
|
};
|
|
78
|
-
/**
|
|
78
|
+
/** Column-state compact menu (ColumnsMenu/MenuStrip) chrome (--cols-menu-*). */
|
|
79
|
+
readonly colsMenu: {
|
|
80
|
+
readonly gap: "6px";
|
|
81
|
+
readonly btnGap: "4px";
|
|
82
|
+
readonly btnPadding: "3px 9px";
|
|
83
|
+
readonly btnRadius: "6px";
|
|
84
|
+
readonly btnFontSize: "12px";
|
|
85
|
+
readonly btnLineHeight: "16px";
|
|
86
|
+
readonly onBorder: "1px solid #24292f";
|
|
87
|
+
readonly onBg: "#24292f";
|
|
88
|
+
readonly onColor: "#fff";
|
|
89
|
+
readonly offBorder: "1px solid #d0d7de";
|
|
90
|
+
readonly offBg: "#fff";
|
|
91
|
+
readonly offColor: "#8c959f";
|
|
92
|
+
readonly disabledBorder: "1px dashed #d0d7de";
|
|
93
|
+
readonly disabledBg: "#f6f8fa";
|
|
94
|
+
readonly disabledColor: "#c4ccd4";
|
|
95
|
+
readonly fixedShadow: "0 0 0 2px #eaeef2";
|
|
96
|
+
readonly dragShadow: "0 3px 10px rgba(0, 0, 0, 0.35)";
|
|
97
|
+
readonly divider: "#d0d7de";
|
|
98
|
+
readonly abbrFontSize: "10px";
|
|
99
|
+
readonly abbrFontWeight: 700;
|
|
100
|
+
readonly abbrLetterSpacing: "0.5px";
|
|
101
|
+
readonly marksFontSize: "9px";
|
|
102
|
+
readonly marksOpacity: 0.9;
|
|
103
|
+
};
|
|
104
|
+
/** ColumnDots chrome (--cols-dots-*). Defaults preserve restored card-29 look. */
|
|
105
|
+
readonly colsDots: {
|
|
106
|
+
readonly text: "#24292f";
|
|
107
|
+
readonly headGap: "10px";
|
|
108
|
+
readonly headMarginBottom: "6px";
|
|
109
|
+
readonly headFontSize: "12px";
|
|
110
|
+
readonly metaColor: "#57606a";
|
|
111
|
+
readonly sortBorder: "1px solid #6e7781";
|
|
112
|
+
readonly sortRadius: "6px";
|
|
113
|
+
readonly sortPadding: "2px 8px";
|
|
114
|
+
readonly sortFontSize: "12px";
|
|
115
|
+
readonly sortBg: "#fff";
|
|
116
|
+
readonly trackHeight: "56px";
|
|
117
|
+
readonly trackMargin: "0 14px";
|
|
118
|
+
readonly rail: "#d0d7de";
|
|
119
|
+
readonly markWidth: "44px";
|
|
120
|
+
readonly markHeight: "56px";
|
|
121
|
+
readonly markMarginLeft: "-22px";
|
|
122
|
+
readonly sortMarkColor: "#0969da";
|
|
123
|
+
readonly sortMarkFontSize: "11px";
|
|
124
|
+
readonly pin: "#afb8c1";
|
|
125
|
+
readonly labelColor: "#8c959f";
|
|
126
|
+
readonly labelActiveColor: "#24292f";
|
|
127
|
+
readonly labelFontSize: "10px";
|
|
128
|
+
readonly dotSize: "18px";
|
|
129
|
+
readonly dotRadius: "9px";
|
|
130
|
+
readonly dotBg: "#24292f";
|
|
131
|
+
readonly dotShadow: "0 3px 10px rgba(0, 0, 0, 0.35)";
|
|
132
|
+
readonly selectedBg: "#0969da";
|
|
133
|
+
readonly selectedBorder: "#b6d4fe";
|
|
134
|
+
readonly fixedBorder: "#afb8c1";
|
|
135
|
+
};
|
|
136
|
+
/** CardList chrome (--cols-card-*). Defaults preserve restored card-29 look. */
|
|
137
|
+
readonly colsCard: {
|
|
138
|
+
readonly gap: "8px";
|
|
139
|
+
readonly border: "1px solid #d0d7de";
|
|
140
|
+
readonly radius: "8px";
|
|
141
|
+
readonly padding: "8px 10px";
|
|
142
|
+
readonly bg: "#fff";
|
|
143
|
+
readonly headerGap: "8px";
|
|
144
|
+
readonly headerMarginBottom: "6px";
|
|
145
|
+
readonly titleFontSize: "14px";
|
|
146
|
+
readonly accentFontSize: "11px";
|
|
147
|
+
readonly accentPadding: "1px 8px";
|
|
148
|
+
readonly accentRadius: "10px";
|
|
149
|
+
readonly accentBg: "#ddf4ff";
|
|
150
|
+
readonly accentColor: "#0969da";
|
|
151
|
+
readonly fieldGap: "10px";
|
|
152
|
+
readonly fieldFontSize: "12px";
|
|
153
|
+
readonly fieldLineHeight: 1.7;
|
|
154
|
+
readonly labelColor: "#57606a";
|
|
155
|
+
readonly labelMinWidth: "72px";
|
|
156
|
+
};
|
|
79
157
|
readonly logs: {
|
|
80
158
|
readonly notificationText: "#fff";
|
|
81
159
|
readonly notificationAccent: "#5D9FFA";
|
|
@@ -77,7 +77,85 @@ export const tokens = {
|
|
|
77
77
|
popRadius: '8px',
|
|
78
78
|
popShadow: '0 8px 28px rgba(0, 0, 0, 0.5)',
|
|
79
79
|
},
|
|
80
|
-
/**
|
|
80
|
+
/** Column-state compact menu (ColumnsMenu/MenuStrip) chrome (--cols-menu-*). */
|
|
81
|
+
colsMenu: {
|
|
82
|
+
gap: '6px',
|
|
83
|
+
btnGap: '4px',
|
|
84
|
+
btnPadding: '3px 9px',
|
|
85
|
+
btnRadius: '6px',
|
|
86
|
+
btnFontSize: '12px',
|
|
87
|
+
btnLineHeight: '16px',
|
|
88
|
+
onBorder: '1px solid #24292f',
|
|
89
|
+
onBg: '#24292f',
|
|
90
|
+
onColor: '#fff',
|
|
91
|
+
offBorder: '1px solid #d0d7de',
|
|
92
|
+
offBg: '#fff',
|
|
93
|
+
offColor: '#8c959f',
|
|
94
|
+
disabledBorder: '1px dashed #d0d7de',
|
|
95
|
+
disabledBg: '#f6f8fa',
|
|
96
|
+
disabledColor: '#c4ccd4',
|
|
97
|
+
fixedShadow: '0 0 0 2px #eaeef2',
|
|
98
|
+
dragShadow: '0 3px 10px rgba(0, 0, 0, 0.35)',
|
|
99
|
+
divider: '#d0d7de',
|
|
100
|
+
abbrFontSize: '10px',
|
|
101
|
+
abbrFontWeight: 700,
|
|
102
|
+
abbrLetterSpacing: '0.5px',
|
|
103
|
+
marksFontSize: '9px',
|
|
104
|
+
marksOpacity: 0.9,
|
|
105
|
+
},
|
|
106
|
+
/** ColumnDots chrome (--cols-dots-*). Defaults preserve restored card-29 look. */
|
|
107
|
+
colsDots: {
|
|
108
|
+
text: '#24292f',
|
|
109
|
+
headGap: '10px',
|
|
110
|
+
headMarginBottom: '6px',
|
|
111
|
+
headFontSize: '12px',
|
|
112
|
+
metaColor: '#57606a',
|
|
113
|
+
sortBorder: '1px solid #6e7781',
|
|
114
|
+
sortRadius: '6px',
|
|
115
|
+
sortPadding: '2px 8px',
|
|
116
|
+
sortFontSize: '12px',
|
|
117
|
+
sortBg: '#fff',
|
|
118
|
+
trackHeight: '56px',
|
|
119
|
+
trackMargin: '0 14px',
|
|
120
|
+
rail: '#d0d7de',
|
|
121
|
+
markWidth: '44px',
|
|
122
|
+
markHeight: '56px',
|
|
123
|
+
markMarginLeft: '-22px',
|
|
124
|
+
sortMarkColor: '#0969da',
|
|
125
|
+
sortMarkFontSize: '11px',
|
|
126
|
+
pin: '#afb8c1',
|
|
127
|
+
labelColor: '#8c959f',
|
|
128
|
+
labelActiveColor: '#24292f',
|
|
129
|
+
labelFontSize: '10px',
|
|
130
|
+
dotSize: '18px',
|
|
131
|
+
dotRadius: '9px',
|
|
132
|
+
dotBg: '#24292f',
|
|
133
|
+
dotShadow: '0 3px 10px rgba(0, 0, 0, 0.35)',
|
|
134
|
+
selectedBg: '#0969da',
|
|
135
|
+
selectedBorder: '#b6d4fe',
|
|
136
|
+
fixedBorder: '#afb8c1',
|
|
137
|
+
},
|
|
138
|
+
/** CardList chrome (--cols-card-*). Defaults preserve restored card-29 look. */
|
|
139
|
+
colsCard: {
|
|
140
|
+
gap: '8px',
|
|
141
|
+
border: '1px solid #d0d7de',
|
|
142
|
+
radius: '8px',
|
|
143
|
+
padding: '8px 10px',
|
|
144
|
+
bg: '#fff',
|
|
145
|
+
headerGap: '8px',
|
|
146
|
+
headerMarginBottom: '6px',
|
|
147
|
+
titleFontSize: '14px',
|
|
148
|
+
accentFontSize: '11px',
|
|
149
|
+
accentPadding: '1px 8px',
|
|
150
|
+
accentRadius: '10px',
|
|
151
|
+
accentBg: '#ddf4ff',
|
|
152
|
+
accentColor: '#0969da',
|
|
153
|
+
fieldGap: '10px',
|
|
154
|
+
fieldFontSize: '12px',
|
|
155
|
+
fieldLineHeight: 1.7,
|
|
156
|
+
labelColor: '#57606a',
|
|
157
|
+
labelMinWidth: '72px',
|
|
158
|
+
}, /** Logs chrome (--logs-*). Defaults preserve the old logger look; apps re-skin via CSS vars. */
|
|
81
159
|
logs: {
|
|
82
160
|
notificationText: '#fff',
|
|
83
161
|
notificationAccent: '#5D9FFA',
|
package/lib/style/style.css
CHANGED
|
@@ -745,32 +745,103 @@ body {
|
|
|
745
745
|
overflow: auto;
|
|
746
746
|
}
|
|
747
747
|
|
|
748
|
+
/* Column state compact menu (ColumnsMenu/MenuStrip). Visual defaults moved from
|
|
749
|
+
component inline styles; runtime drag transforms remain inline. */
|
|
750
|
+
.wenayColsMenu,
|
|
751
|
+
.wenayColsMenuList {
|
|
752
|
+
display: flex;
|
|
753
|
+
align-items: center;
|
|
754
|
+
gap: var(--cols-menu-gap, 6px);
|
|
755
|
+
flex-wrap: wrap;
|
|
756
|
+
}
|
|
757
|
+
.wenayColsMenu {
|
|
758
|
+
user-select: none;
|
|
759
|
+
}
|
|
760
|
+
.wenayColsMenuBtn {
|
|
761
|
+
position: relative;
|
|
762
|
+
display: flex;
|
|
763
|
+
align-items: center;
|
|
764
|
+
gap: var(--cols-menu-btn-gap, 4px);
|
|
765
|
+
padding: var(--cols-menu-btn-padding, 3px 9px);
|
|
766
|
+
border-radius: var(--cols-menu-btn-radius, 6px);
|
|
767
|
+
font-size: var(--cols-menu-btn-font-size, 12px);
|
|
768
|
+
line-height: var(--cols-menu-btn-line-height, 16px);
|
|
769
|
+
white-space: nowrap;
|
|
770
|
+
cursor: pointer;
|
|
771
|
+
}
|
|
772
|
+
.wenayColsMenuBtn_on {
|
|
773
|
+
border: var(--cols-menu-on-border, 1px solid #24292f);
|
|
774
|
+
background: var(--cols-menu-on-bg, #24292f);
|
|
775
|
+
color: var(--cols-menu-on-color, #fff);
|
|
776
|
+
}
|
|
777
|
+
.wenayColsMenuBtn_off {
|
|
778
|
+
border: var(--cols-menu-off-border, 1px solid #d0d7de);
|
|
779
|
+
background: var(--cols-menu-off-bg, #fff);
|
|
780
|
+
color: var(--cols-menu-off-color, #8c959f);
|
|
781
|
+
text-decoration: line-through;
|
|
782
|
+
}
|
|
783
|
+
.wenayColsMenuBtn_disabled {
|
|
784
|
+
border: var(--cols-menu-disabled-border, 1px dashed #d0d7de);
|
|
785
|
+
background: var(--cols-menu-disabled-bg, #f6f8fa);
|
|
786
|
+
color: var(--cols-menu-disabled-color, #c4ccd4);
|
|
787
|
+
cursor: default;
|
|
788
|
+
}
|
|
789
|
+
.wenayColsMenuBtn_fixed {
|
|
790
|
+
box-shadow: var(--cols-menu-fixed-shadow, 0 0 0 2px #eaeef2);
|
|
791
|
+
}
|
|
792
|
+
.wenayColsMenuBtn_dragging {
|
|
793
|
+
z-index: 3;
|
|
794
|
+
box-shadow: var(--cols-menu-drag-shadow, 0 3px 10px rgba(0, 0, 0, 0.35));
|
|
795
|
+
}
|
|
796
|
+
.wenayColsMenuBtn_shift {
|
|
797
|
+
transition: transform 0.15s ease;
|
|
798
|
+
}
|
|
799
|
+
.wenayColsMenuIcon {
|
|
800
|
+
display: inline-flex;
|
|
801
|
+
align-items: center;
|
|
802
|
+
}
|
|
803
|
+
.wenayColsMenuAbbr {
|
|
804
|
+
font-size: var(--cols-menu-abbr-font-size, 10px);
|
|
805
|
+
font-weight: var(--cols-menu-abbr-font-weight, 700);
|
|
806
|
+
letter-spacing: var(--cols-menu-abbr-letter-spacing, 0.5px);
|
|
807
|
+
text-transform: uppercase;
|
|
808
|
+
}
|
|
809
|
+
.wenayColsMenuMarks {
|
|
810
|
+
font-size: var(--cols-menu-marks-font-size, 9px);
|
|
811
|
+
opacity: var(--cols-menu-marks-opacity, 0.9);
|
|
812
|
+
}
|
|
813
|
+
.wenayColsMenuDivider {
|
|
814
|
+
width: 1px;
|
|
815
|
+
align-self: stretch;
|
|
816
|
+
margin: 1px 2px;
|
|
817
|
+
background: var(--cols-menu-divider, #d0d7de);
|
|
818
|
+
}
|
|
748
819
|
/* Column state mobile primitives (ColumnDots/CardList). Visual defaults mirror the
|
|
749
|
-
|
|
820
|
+
restored stand-29 look and are tokenized through --cols-dots-* / --cols-card-*. */
|
|
750
821
|
.wenayColDots {
|
|
751
822
|
user-select: none;
|
|
752
|
-
color: #24292f;
|
|
823
|
+
color: var(--cols-dots-text, #24292f);
|
|
753
824
|
}
|
|
754
825
|
.wenayColDotsHead {
|
|
755
826
|
display: flex;
|
|
756
827
|
align-items: center;
|
|
757
|
-
gap: 10px;
|
|
758
|
-
margin-bottom: 6px;
|
|
759
|
-
font-size: 12px;
|
|
828
|
+
gap: var(--cols-dots-head-gap, 10px);
|
|
829
|
+
margin-bottom: var(--cols-dots-head-margin-bottom, 6px);
|
|
830
|
+
font-size: var(--cols-dots-head-font-size, 12px);
|
|
760
831
|
}
|
|
761
832
|
.wenayColDotsMeta {
|
|
762
|
-
color: #57606a;
|
|
833
|
+
color: var(--cols-dots-meta-color, #57606a);
|
|
763
834
|
}
|
|
764
835
|
.wenayColDotsSpacer {
|
|
765
836
|
flex: 1;
|
|
766
837
|
}
|
|
767
838
|
.wenayColDotsSort {
|
|
768
|
-
border: 1px solid #6e7781;
|
|
769
|
-
border-radius: 6px;
|
|
770
|
-
padding: 2px 8px;
|
|
771
|
-
font-size: 12px;
|
|
839
|
+
border: var(--cols-dots-sort-border, 1px solid #6e7781);
|
|
840
|
+
border-radius: var(--cols-dots-sort-radius, 6px);
|
|
841
|
+
padding: var(--cols-dots-sort-padding, 2px 8px);
|
|
842
|
+
font-size: var(--cols-dots-sort-font-size, 12px);
|
|
772
843
|
cursor: pointer;
|
|
773
|
-
background: #fff;
|
|
844
|
+
background: var(--cols-dots-sort-bg, #fff);
|
|
774
845
|
}
|
|
775
846
|
.wenayColDotsSort:disabled {
|
|
776
847
|
cursor: default;
|
|
@@ -778,8 +849,8 @@ body {
|
|
|
778
849
|
}
|
|
779
850
|
.wenayColDotsTrack {
|
|
780
851
|
position: relative;
|
|
781
|
-
height: 56px;
|
|
782
|
-
margin: 0 14px;
|
|
852
|
+
height: var(--cols-dots-track-height, 56px);
|
|
853
|
+
margin: var(--cols-dots-track-margin, 0 14px);
|
|
783
854
|
touch-action: none;
|
|
784
855
|
}
|
|
785
856
|
.wenayColDotsRail {
|
|
@@ -789,14 +860,14 @@ body {
|
|
|
789
860
|
top: 27px;
|
|
790
861
|
height: 2px;
|
|
791
862
|
border-radius: 1px;
|
|
792
|
-
background: #d0d7de;
|
|
863
|
+
background: var(--cols-dots-rail, #d0d7de);
|
|
793
864
|
}
|
|
794
865
|
.wenayColDotsMark {
|
|
795
866
|
position: absolute;
|
|
796
867
|
top: 0;
|
|
797
|
-
width: 44px;
|
|
798
|
-
height: 56px;
|
|
799
|
-
margin-left: -22px;
|
|
868
|
+
width: var(--cols-dots-mark-width, 44px);
|
|
869
|
+
height: var(--cols-dots-mark-height, 56px);
|
|
870
|
+
margin-left: var(--cols-dots-mark-margin-left, -22px);
|
|
800
871
|
}
|
|
801
872
|
.wenayColDotsSortMark {
|
|
802
873
|
position: absolute;
|
|
@@ -804,8 +875,8 @@ body {
|
|
|
804
875
|
right: 0;
|
|
805
876
|
top: 0;
|
|
806
877
|
text-align: center;
|
|
807
|
-
font-size: 11px;
|
|
808
|
-
color: #0969da;
|
|
878
|
+
font-size: var(--cols-dots-sort-mark-font-size, 11px);
|
|
879
|
+
color: var(--cols-dots-sort-mark-color, #0969da);
|
|
809
880
|
font-weight: 700;
|
|
810
881
|
}
|
|
811
882
|
.wenayColDotsMarkPin {
|
|
@@ -816,7 +887,7 @@ body {
|
|
|
816
887
|
height: 8px;
|
|
817
888
|
margin-left: -4px;
|
|
818
889
|
border-radius: 4px;
|
|
819
|
-
background: #afb8c1;
|
|
890
|
+
background: var(--cols-dots-pin, #afb8c1);
|
|
820
891
|
}
|
|
821
892
|
.wenayColDotsMark_on .wenayColDotsMarkPin {
|
|
822
893
|
background: transparent;
|
|
@@ -827,14 +898,14 @@ body {
|
|
|
827
898
|
right: 0;
|
|
828
899
|
top: 40px;
|
|
829
900
|
text-align: center;
|
|
830
|
-
font-size: 10px;
|
|
831
|
-
color: #8c959f;
|
|
901
|
+
font-size: var(--cols-dots-label-font-size, 10px);
|
|
902
|
+
color: var(--cols-dots-label-color, #8c959f);
|
|
832
903
|
overflow: hidden;
|
|
833
904
|
text-overflow: ellipsis;
|
|
834
905
|
white-space: nowrap;
|
|
835
906
|
}
|
|
836
907
|
.wenayColDotsMark_on .wenayColDotsMarkLabel {
|
|
837
|
-
color: #24292f;
|
|
908
|
+
color: var(--cols-dots-label-active-color, #24292f);
|
|
838
909
|
}
|
|
839
910
|
.wenayColDotsDotWrap {
|
|
840
911
|
position: absolute;
|
|
@@ -860,37 +931,37 @@ body {
|
|
|
860
931
|
opacity: 0.4;
|
|
861
932
|
}
|
|
862
933
|
.wenayColDotsDot {
|
|
863
|
-
width: 18px;
|
|
864
|
-
height: 18px;
|
|
865
|
-
border-radius: 9px;
|
|
866
|
-
background: #24292f;
|
|
934
|
+
width: var(--cols-dots-dot-size, 18px);
|
|
935
|
+
height: var(--cols-dots-dot-size, 18px);
|
|
936
|
+
border-radius: var(--cols-dots-dot-radius, 9px);
|
|
937
|
+
background: var(--cols-dots-dot-bg, #24292f);
|
|
867
938
|
border: 2px solid transparent;
|
|
868
939
|
}
|
|
869
940
|
.wenayColDotsDotWrap_dragging .wenayColDotsDot {
|
|
870
|
-
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
|
|
941
|
+
box-shadow: var(--cols-dots-dot-shadow, 0 3px 10px rgba(0, 0, 0, 0.35));
|
|
871
942
|
}
|
|
872
943
|
.wenayColDotsDot_selected {
|
|
873
|
-
background: #0969da;
|
|
874
|
-
border-color: #b6d4fe;
|
|
944
|
+
background: var(--cols-dots-selected-bg, #0969da);
|
|
945
|
+
border-color: var(--cols-dots-selected-border, #b6d4fe);
|
|
875
946
|
}
|
|
876
947
|
.wenayColDotsDot_fixed {
|
|
877
|
-
border-color: #afb8c1;
|
|
948
|
+
border-color: var(--cols-dots-fixed-border, #afb8c1);
|
|
878
949
|
}
|
|
879
950
|
.wenayCardList {
|
|
880
951
|
display: grid;
|
|
881
|
-
gap: 8px;
|
|
952
|
+
gap: var(--cols-card-gap, 8px);
|
|
882
953
|
}
|
|
883
954
|
.wenayCardListItem {
|
|
884
|
-
border: 1px solid #d0d7de;
|
|
885
|
-
border-radius: 8px;
|
|
886
|
-
padding: 8px 10px;
|
|
887
|
-
background: #fff;
|
|
955
|
+
border: var(--cols-card-border, 1px solid #d0d7de);
|
|
956
|
+
border-radius: var(--cols-card-radius, 8px);
|
|
957
|
+
padding: var(--cols-card-padding, 8px 10px);
|
|
958
|
+
background: var(--cols-card-bg, #fff);
|
|
888
959
|
}
|
|
889
960
|
.wenayCardListHeader {
|
|
890
961
|
display: flex;
|
|
891
962
|
align-items: center;
|
|
892
|
-
gap: 8px;
|
|
893
|
-
margin-bottom: 6px;
|
|
963
|
+
gap: var(--cols-card-header-gap, 8px);
|
|
964
|
+
margin-bottom: var(--cols-card-header-margin-bottom, 6px);
|
|
894
965
|
}
|
|
895
966
|
.wenayCardListHeader_compact {
|
|
896
967
|
margin-bottom: 0;
|
|
@@ -900,32 +971,33 @@ body {
|
|
|
900
971
|
overflow: hidden;
|
|
901
972
|
text-overflow: ellipsis;
|
|
902
973
|
white-space: nowrap;
|
|
903
|
-
font-size: 14px;
|
|
974
|
+
font-size: var(--cols-card-title-font-size, 14px);
|
|
904
975
|
}
|
|
905
976
|
.wenayCardListAccent {
|
|
906
|
-
font-size: 11px;
|
|
907
|
-
padding: 1px 8px;
|
|
908
|
-
border-radius: 10px;
|
|
909
|
-
background: #ddf4ff;
|
|
910
|
-
color: #0969da;
|
|
977
|
+
font-size: var(--cols-card-accent-font-size, 11px);
|
|
978
|
+
padding: var(--cols-card-accent-padding, 1px 8px);
|
|
979
|
+
border-radius: var(--cols-card-accent-radius, 10px);
|
|
980
|
+
background: var(--cols-card-accent-bg, #ddf4ff);
|
|
981
|
+
color: var(--cols-card-accent-color, #0969da);
|
|
911
982
|
white-space: nowrap;
|
|
912
983
|
}
|
|
913
984
|
.wenayCardListField {
|
|
914
985
|
display: flex;
|
|
915
|
-
gap: 10px;
|
|
916
|
-
font-size: 12px;
|
|
917
|
-
line-height: 1.7;
|
|
986
|
+
gap: var(--cols-card-field-gap, 10px);
|
|
987
|
+
font-size: var(--cols-card-field-font-size, 12px);
|
|
988
|
+
line-height: var(--cols-card-field-line-height, 1.7);
|
|
918
989
|
}
|
|
919
990
|
.wenayCardListLabel {
|
|
920
|
-
color: #57606a;
|
|
921
|
-
min-width: 72px;
|
|
991
|
+
color: var(--cols-card-label-color, #57606a);
|
|
992
|
+
min-width: var(--cols-card-label-min-width, 72px);
|
|
922
993
|
}
|
|
923
994
|
.wenayCardListValue {
|
|
924
995
|
flex: 1;
|
|
925
996
|
text-align: right;
|
|
926
997
|
overflow: hidden;
|
|
927
998
|
text-overflow: ellipsis;
|
|
928
|
-
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
929
1001
|
/* Toolbar (createToolbar). Themed via --tb-* (tokens.css), dark defaults. */
|
|
930
1002
|
.wenayTb {
|
|
931
1003
|
display: inline-flex;
|
package/lib/style/tokens.css
CHANGED
|
@@ -85,9 +85,83 @@
|
|
|
85
85
|
--tb-pop-bg: var(--color-bg-dark);
|
|
86
86
|
--tb-pop-border: 1px solid var(--color-border-common);
|
|
87
87
|
--tb-pop-radius: 8px;
|
|
88
|
-
--tb-pop-shadow: 0 8px 28px rgba(0, 0, 0, 0.5);
|
|
89
|
-
|
|
88
|
+
--tb-pop-shadow: 0 8px 28px rgba(0, 0, 0, 0.5);
|
|
89
|
+
|
|
90
|
+
/* Column-state compact menu (ColumnsMenu/MenuStrip). Defaults preserve the
|
|
91
|
+
previous GitHub-like inline look; apps can override via --cols-menu-*. */
|
|
92
|
+
--cols-menu-gap: 6px;
|
|
93
|
+
--cols-menu-btn-gap: 4px;
|
|
94
|
+
--cols-menu-btn-padding: 3px 9px;
|
|
95
|
+
--cols-menu-btn-radius: 6px;
|
|
96
|
+
--cols-menu-btn-font-size: 12px;
|
|
97
|
+
--cols-menu-btn-line-height: 16px;
|
|
98
|
+
--cols-menu-on-border: 1px solid #24292f;
|
|
99
|
+
--cols-menu-on-bg: #24292f;
|
|
100
|
+
--cols-menu-on-color: #fff;
|
|
101
|
+
--cols-menu-off-border: 1px solid #d0d7de;
|
|
102
|
+
--cols-menu-off-bg: #fff;
|
|
103
|
+
--cols-menu-off-color: #8c959f;
|
|
104
|
+
--cols-menu-disabled-border: 1px dashed #d0d7de;
|
|
105
|
+
--cols-menu-disabled-bg: #f6f8fa;
|
|
106
|
+
--cols-menu-disabled-color: #c4ccd4;
|
|
107
|
+
--cols-menu-fixed-shadow: 0 0 0 2px #eaeef2;
|
|
108
|
+
--cols-menu-drag-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
|
|
109
|
+
--cols-menu-divider: #d0d7de;
|
|
110
|
+
--cols-menu-abbr-font-size: 10px;
|
|
111
|
+
--cols-menu-abbr-font-weight: 700;
|
|
112
|
+
--cols-menu-abbr-letter-spacing: 0.5px;
|
|
113
|
+
--cols-menu-marks-font-size: 9px;
|
|
114
|
+
--cols-menu-marks-opacity: 0.9;
|
|
90
115
|
|
|
116
|
+
/* Column-state mobile/card primitives (ColumnDots/CardList). Defaults preserve
|
|
117
|
+
the restored card-29 look; apps can override via --cols-dots-* / --cols-card-*. */
|
|
118
|
+
--cols-dots-text: #24292f;
|
|
119
|
+
--cols-dots-head-gap: 10px;
|
|
120
|
+
--cols-dots-head-margin-bottom: 6px;
|
|
121
|
+
--cols-dots-head-font-size: 12px;
|
|
122
|
+
--cols-dots-meta-color: #57606a;
|
|
123
|
+
--cols-dots-sort-border: 1px solid #6e7781;
|
|
124
|
+
--cols-dots-sort-radius: 6px;
|
|
125
|
+
--cols-dots-sort-padding: 2px 8px;
|
|
126
|
+
--cols-dots-sort-font-size: 12px;
|
|
127
|
+
--cols-dots-sort-bg: #fff;
|
|
128
|
+
--cols-dots-track-height: 56px;
|
|
129
|
+
--cols-dots-track-margin: 0 14px;
|
|
130
|
+
--cols-dots-rail: #d0d7de;
|
|
131
|
+
--cols-dots-mark-width: 44px;
|
|
132
|
+
--cols-dots-mark-height: 56px;
|
|
133
|
+
--cols-dots-mark-margin-left: -22px;
|
|
134
|
+
--cols-dots-sort-mark-color: #0969da;
|
|
135
|
+
--cols-dots-sort-mark-font-size: 11px;
|
|
136
|
+
--cols-dots-pin: #afb8c1;
|
|
137
|
+
--cols-dots-label-color: #8c959f;
|
|
138
|
+
--cols-dots-label-active-color: #24292f;
|
|
139
|
+
--cols-dots-label-font-size: 10px;
|
|
140
|
+
--cols-dots-dot-size: 18px;
|
|
141
|
+
--cols-dots-dot-radius: 9px;
|
|
142
|
+
--cols-dots-dot-bg: #24292f;
|
|
143
|
+
--cols-dots-dot-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
|
|
144
|
+
--cols-dots-selected-bg: #0969da;
|
|
145
|
+
--cols-dots-selected-border: #b6d4fe;
|
|
146
|
+
--cols-dots-fixed-border: #afb8c1;
|
|
147
|
+
--cols-card-gap: 8px;
|
|
148
|
+
--cols-card-border: 1px solid #d0d7de;
|
|
149
|
+
--cols-card-radius: 8px;
|
|
150
|
+
--cols-card-padding: 8px 10px;
|
|
151
|
+
--cols-card-bg: #fff;
|
|
152
|
+
--cols-card-header-gap: 8px;
|
|
153
|
+
--cols-card-header-margin-bottom: 6px;
|
|
154
|
+
--cols-card-title-font-size: 14px;
|
|
155
|
+
--cols-card-accent-font-size: 11px;
|
|
156
|
+
--cols-card-accent-padding: 1px 8px;
|
|
157
|
+
--cols-card-accent-radius: 10px;
|
|
158
|
+
--cols-card-accent-bg: #ddf4ff;
|
|
159
|
+
--cols-card-accent-color: #0969da;
|
|
160
|
+
--cols-card-field-gap: 10px;
|
|
161
|
+
--cols-card-field-font-size: 12px;
|
|
162
|
+
--cols-card-field-line-height: 1.7;
|
|
163
|
+
--cols-card-label-color: #57606a;
|
|
164
|
+
--cols-card-label-min-width: 72px;
|
|
91
165
|
/* Logs. Defaults preserve the old logger look; apps can override in their theme. */
|
|
92
166
|
--logs-notification-text: #fff;
|
|
93
167
|
--logs-notification-accent: #5D9FFA;
|