flexlayout-react 0.5.19 → 0.6.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.
Files changed (83) hide show
  1. package/ChangeLog.txt +22 -0
  2. package/README.md +61 -56
  3. package/declarations/Types.d.ts +1 -0
  4. package/declarations/model/IJsonModel.d.ts +3 -0
  5. package/declarations/model/Model.d.ts +2 -0
  6. package/declarations/view/Icons.d.ts +6 -0
  7. package/declarations/view/Layout.d.ts +6 -4
  8. package/declarations/view/MenuTabButton.d.ts +1 -0
  9. package/declarations/view/TabButtonStamp.d.ts +1 -0
  10. package/declarations/view/Utils.d.ts +1 -0
  11. package/dist/flexlayout.js +50 -14
  12. package/dist/flexlayout_min.js +1 -1
  13. package/lib/PopupMenu.js +11 -7
  14. package/lib/PopupMenu.js.map +1 -1
  15. package/lib/Types.js +1 -0
  16. package/lib/Types.js.map +1 -1
  17. package/lib/model/Model.js +8 -0
  18. package/lib/model/Model.js.map +1 -1
  19. package/lib/model/TabNode.js +6 -1
  20. package/lib/model/TabNode.js.map +1 -1
  21. package/lib/view/BorderButton.js +11 -41
  22. package/lib/view/BorderButton.js.map +1 -1
  23. package/lib/view/BorderTabSet.js +7 -7
  24. package/lib/view/BorderTabSet.js.map +1 -1
  25. package/lib/view/FloatingWindow.js +13 -5
  26. package/lib/view/FloatingWindow.js.map +1 -1
  27. package/lib/view/Icons.js +36 -0
  28. package/lib/view/Icons.js.map +1 -0
  29. package/lib/view/Layout.js +80 -25
  30. package/lib/view/Layout.js.map +1 -1
  31. package/lib/view/MenuTabButton.js +22 -0
  32. package/lib/view/MenuTabButton.js.map +1 -0
  33. package/lib/view/Splitter.js +3 -3
  34. package/lib/view/Splitter.js.map +1 -1
  35. package/lib/view/Tab.js +9 -6
  36. package/lib/view/Tab.js.map +1 -1
  37. package/lib/view/TabButton.js +13 -46
  38. package/lib/view/TabButton.js.map +1 -1
  39. package/lib/view/TabButtonStamp.js +22 -0
  40. package/lib/view/TabButtonStamp.js.map +1 -0
  41. package/lib/view/TabFloating.js +7 -5
  42. package/lib/view/TabFloating.js.map +1 -1
  43. package/lib/view/TabOverflowHook.js +1 -1
  44. package/lib/view/TabSet.js +15 -25
  45. package/lib/view/TabSet.js.map +1 -1
  46. package/lib/view/Utils.js +61 -0
  47. package/lib/view/Utils.js.map +1 -0
  48. package/package.json +11 -6
  49. package/src/I18nLabel.ts +1 -1
  50. package/src/PopupMenu.tsx +30 -10
  51. package/src/Types.ts +1 -0
  52. package/src/model/IJsonModel.ts +3 -0
  53. package/src/model/Model.ts +12 -0
  54. package/src/model/TabNode.ts +6 -1
  55. package/src/view/BorderButton.tsx +19 -43
  56. package/src/view/BorderTabSet.tsx +14 -4
  57. package/src/view/FloatingWindow.tsx +14 -6
  58. package/src/view/Icons.tsx +36 -0
  59. package/src/view/Layout.tsx +108 -41
  60. package/src/view/Splitter.tsx +4 -1
  61. package/src/view/Tab.tsx +17 -6
  62. package/src/view/TabButton.tsx +27 -55
  63. package/src/view/TabButtonStamp.tsx +47 -0
  64. package/src/view/TabFloating.tsx +12 -5
  65. package/src/view/TabOverflowHook.tsx +1 -1
  66. package/src/view/TabSet.tsx +27 -17
  67. package/src/view/Utils.tsx +71 -0
  68. package/style/_base.scss +82 -52
  69. package/style/dark.css +82 -76
  70. package/style/dark.css.map +1 -1
  71. package/style/dark.scss +15 -5
  72. package/style/gray.css +79 -73
  73. package/style/gray.css.map +1 -1
  74. package/style/gray.scss +10 -3
  75. package/style/light.css +83 -77
  76. package/style/light.css.map +1 -1
  77. package/style/light.scss +16 -6
  78. package/images/close.png +0 -0
  79. package/images/maximize.png +0 -0
  80. package/images/more.png +0 -0
  81. package/images/more2.png +0 -0
  82. package/images/popout.png +0 -0
  83. package/images/restore.png +0 -0
@@ -5,17 +5,19 @@ import TabSetNode from "../model/TabSetNode";
5
5
  import { CLASSES } from "../Types";
6
6
  import { ILayoutCallbacks } from "./Layout";
7
7
  import { I18nLabel } from "../I18nLabel";
8
+ import { hideElement } from "./Utils";
8
9
 
9
10
  /** @hidden @internal */
10
11
  export interface ITabFloatingProps {
11
12
  layout: ILayoutCallbacks;
12
13
  selected: boolean;
13
14
  node: TabNode;
15
+ path: string;
14
16
  }
15
17
 
16
18
  /** @hidden @internal */
17
19
  export const TabFloating = (props: ITabFloatingProps) => {
18
- const { layout, selected, node } = props;
20
+ const { layout, selected, node, path } = props;
19
21
 
20
22
  const showPopout = () => {
21
23
  if (node.getWindow()) {
@@ -48,9 +50,10 @@ export const TabFloating = (props: ITabFloatingProps) => {
48
50
 
49
51
  const cm = layout.getClassName;
50
52
 
51
- const style: Record<string, any> = node._styleWithPosition({
52
- display: selected ? "flex" : "none",
53
- });
53
+ const style: Record<string, any> = node._styleWithPosition();
54
+ if (!selected) {
55
+ hideElement(style, node.getModel().isUseVisibility());
56
+ }
54
57
 
55
58
  const message = layout.i18nName(I18nLabel.Floating_Window_Message);
56
59
  const showMessage = layout.i18nName(I18nLabel.Floating_Window_Show_Window);
@@ -65,7 +68,11 @@ export const TabFloating = (props: ITabFloatingProps) => {
65
68
  );
66
69
  } else {
67
70
  return (
68
- <div className={cm(CLASSES.FLEXLAYOUT__TAB_FLOATING)} onMouseDown={onMouseDown} onTouchStart={onMouseDown} style={style}>
71
+ <div className={cm(CLASSES.FLEXLAYOUT__TAB_FLOATING)}
72
+ data-layout-path={path}
73
+ onMouseDown={onMouseDown}
74
+ onTouchStart={onMouseDown}
75
+ style={style}>
69
76
  <div className={cm(CLASSES.FLEXLAYOUT__TAB_FLOATING_INNER)}>
70
77
  <div>{message}</div>
71
78
  <div>
@@ -92,7 +92,7 @@ export const useTabOverflow = (
92
92
  return; // nothing to do all tabs are shown in available space
93
93
  }
94
94
 
95
- endPos -= hiddenTabs.length > 0 ? (orientation === Orientation.HORZ ? 10 : 0) : 45; // will need hidden tabs
95
+ endPos -= hiddenTabs.length > 0 ? (orientation === Orientation.HORZ ? 16 : 0) : 45; // will need hidden tabs
96
96
 
97
97
  let shiftPos = 0;
98
98
 
@@ -9,6 +9,7 @@ import { TabButton } from "./TabButton";
9
9
  import { useTabOverflow } from "./TabOverflowHook";
10
10
  import Orientation from "../Orientation";
11
11
  import { CLASSES } from "../Types";
12
+ import { hideElement, isAuxMouseEvent } from "./Utils";
12
13
 
13
14
  /** @hidden @internal */
14
15
  export interface ITabSetProps {
@@ -18,11 +19,12 @@ export interface ITabSetProps {
18
19
  titleFactory?: (node: TabNode) => React.ReactNode | undefined;
19
20
  icons?: IIcons;
20
21
  editingTab?: TabNode;
22
+ path?: string;
21
23
  }
22
24
 
23
25
  /** @hidden @internal */
24
26
  export const TabSet = (props: ITabSetProps) => {
25
- const { node, layout, iconFactory, titleFactory, icons } = props;
27
+ const { node, layout, iconFactory, titleFactory, icons, path } = props;
26
28
 
27
29
  const toolbarRef = React.useRef<HTMLDivElement | null>(null);
28
30
  const overflowbuttonRef = React.useRef<HTMLButtonElement | null>(null);
@@ -33,7 +35,14 @@ export const TabSet = (props: ITabSetProps) => {
33
35
 
34
36
  const onOverflowClick = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
35
37
  const element = overflowbuttonRef.current!;
36
- showPopup(layout.getRootDiv(), element, hiddenTabs, onOverflowItemSelect, layout.getClassName);
38
+ showPopup(
39
+ element,
40
+ hiddenTabs,
41
+ onOverflowItemSelect,
42
+ layout,
43
+ iconFactory,
44
+ titleFactory,
45
+ );
37
46
  event.stopPropagation();
38
47
  };
39
48
 
@@ -43,7 +52,6 @@ export const TabSet = (props: ITabSetProps) => {
43
52
  };
44
53
 
45
54
  const onMouseDown = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>) => {
46
-
47
55
  if (!isAuxMouseEvent(event)) {
48
56
  let name = node.getName();
49
57
  if (name === undefined) {
@@ -110,7 +118,7 @@ export const TabSet = (props: ITabSetProps) => {
110
118
  let style = node._styleWithPosition();
111
119
 
112
120
  if (node.getModel().getMaximizedTabset() !== undefined && !node.isMaximized()) {
113
- style.display = "none";
121
+ hideElement(style, node.getModel().isUseVisibility())
114
122
  }
115
123
 
116
124
  const tabs = [];
@@ -122,9 +130,9 @@ export const TabSet = (props: ITabSetProps) => {
122
130
  <TabButton
123
131
  layout={layout}
124
132
  node={child}
133
+ path={path + "/tb" + i}
125
134
  key={child.getId()}
126
135
  selected={isSelected}
127
- show={true}
128
136
  height={node.getTabStripHeight()}
129
137
  iconFactory={iconFactory}
130
138
  titleFactory={titleFactory}
@@ -170,8 +178,10 @@ export const TabSet = (props: ITabSetProps) => {
170
178
  buttons.push(
171
179
  <button
172
180
  key="overflowbutton"
181
+ data-layout-path={path + "/button/overflow"}
182
+
173
183
  ref={overflowbuttonRef}
174
- className={cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW)}
184
+ className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW)}
175
185
  title={overflowTitle}
176
186
  onClick={onOverflowClick}
177
187
  onMouseDown={onInterceptMouseDown}
@@ -188,6 +198,7 @@ export const TabSet = (props: ITabSetProps) => {
188
198
  buttons.push(
189
199
  <button
190
200
  key="float"
201
+ data-layout-path={path + "/button/float"}
191
202
  title={floatTitle}
192
203
  className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_FLOAT)}
193
204
  onClick={onFloatTab}
@@ -205,6 +216,7 @@ export const TabSet = (props: ITabSetProps) => {
205
216
  btns.push(
206
217
  <button
207
218
  key="max"
219
+ data-layout-path={path + "/button/max"}
208
220
  title={node.isMaximized() ? minTitle : maxTitle}
209
221
  className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_ + (node.isMaximized() ? "max" : "min"))}
210
222
  onClick={onMaximizeToggle}
@@ -222,6 +234,7 @@ export const TabSet = (props: ITabSetProps) => {
222
234
  btns.push(
223
235
  <button
224
236
  key="close"
237
+ data-layout-path={path + "/button/close"}
225
238
  title={title}
226
239
  className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_CLOSE)}
227
240
  onClick={onClose}
@@ -287,6 +300,7 @@ export const TabSet = (props: ITabSetProps) => {
287
300
 
288
301
  header = (
289
302
  <div className={tabHeaderClasses} style={{ height: node.getHeaderHeight() + "px" }}
303
+ data-layout-path={path + "/header"}
290
304
  onMouseDown={onMouseDown}
291
305
  onContextMenu={onContextMenu}
292
306
  onClick={onAuxMouseClick}
@@ -307,6 +321,7 @@ export const TabSet = (props: ITabSetProps) => {
307
321
  }
308
322
  tabStrip = (
309
323
  <div className={tabStripClasses} style={tabStripStyle}
324
+ data-layout-path={path + "/tabstrip"}
310
325
  onMouseDown={onMouseDown}
311
326
  onContextMenu={onContextMenu}
312
327
  onClick={onAuxMouseClick}
@@ -327,21 +342,16 @@ export const TabSet = (props: ITabSetProps) => {
327
342
  style = layout.styleFont(style);
328
343
 
329
344
  return (
330
- <div ref={selfRef} dir="ltr" style={style} className={cm(CLASSES.FLEXLAYOUT__TABSET)} onWheel={onMouseWheel}>
345
+ <div ref={selfRef}
346
+ dir="ltr"
347
+ data-layout-path={path}
348
+ style={style}
349
+ className={cm(CLASSES.FLEXLAYOUT__TABSET)}
350
+ onWheel={onMouseWheel}>
331
351
  {header}
332
352
  {tabStrip}
333
353
  </div>
334
354
  );
335
355
  };
336
356
 
337
- /** @hidden @internal */
338
- export function isAuxMouseEvent(event: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>) {
339
- let auxEvent = false;
340
- if (event.nativeEvent instanceof MouseEvent) {
341
- if (event.nativeEvent.button !== 0 || event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) {
342
- auxEvent = true;
343
- }
344
- }
345
- return auxEvent;
346
- }
347
357
 
@@ -0,0 +1,71 @@
1
+ import * as React from "react";
2
+ import TabNode from "../model/TabNode";
3
+ import { ILayoutCallbacks, ITitleObject } from "./Layout";
4
+
5
+ /** @hidden @internal */
6
+ export function getRenderStateEx (
7
+ layout: ILayoutCallbacks,
8
+ node: TabNode,
9
+ iconFactory?: (node: TabNode) => React.ReactNode | undefined,
10
+ titleFactory?: (node: TabNode) => React.ReactNode | undefined
11
+ ) {
12
+ let leadingContent = iconFactory ? iconFactory(node) : undefined;
13
+ let titleContent: React.ReactNode = node.getName();
14
+ let name = node.getName();
15
+
16
+ function isTitleObject(obj: any): obj is ITitleObject {
17
+ return obj.titleContent !== undefined
18
+ }
19
+
20
+ if (titleFactory !== undefined) {
21
+ const titleObj = titleFactory(node);
22
+ if (titleObj !== undefined) {
23
+ if (typeof titleObj === "string") {
24
+ titleContent = titleObj as string;
25
+ name = titleObj as string;
26
+ } else if (isTitleObject(titleObj)) {
27
+ titleContent = titleObj.titleContent;
28
+ name = titleObj.name;
29
+ } else {
30
+ titleContent = titleObj;
31
+ }
32
+ }
33
+ }
34
+
35
+ if (leadingContent === undefined && node.getIcon() !== undefined) {
36
+ leadingContent = <img style={{width:"1em", height:"1em"}} src={node.getIcon()} alt="leadingContent" />;
37
+ }
38
+
39
+ let buttons: any[] = [];
40
+
41
+ // allow customization of leading contents (icon) and contents
42
+ const renderState = { leading: leadingContent, content: titleContent, name, buttons };
43
+ layout.customizeTab(node, renderState);
44
+
45
+ node._setRenderedName(renderState.name);
46
+
47
+ return renderState;
48
+
49
+ }
50
+
51
+ /** @hidden @internal */
52
+ export function hideElement(style: Record<string, any>, useVisibility: ConstrainBoolean ) {
53
+ if (useVisibility) {
54
+ style.visibility = "hidden";
55
+ } else {
56
+ style.display = "none";
57
+ }
58
+ }
59
+
60
+
61
+ /** @hidden @internal */
62
+ export function isAuxMouseEvent(event: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>) {
63
+ let auxEvent = false;
64
+ if (event.nativeEvent instanceof MouseEvent) {
65
+ if (event.nativeEvent.button !== 0 || event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) {
66
+ auxEvent = true;
67
+ }
68
+ }
69
+ return auxEvent;
70
+ }
71
+
package/style/_base.scss CHANGED
@@ -19,6 +19,8 @@
19
19
  --color-6: #{$color_6};
20
20
  --color-drag1: #{$color_drag1};
21
21
  --color-drag2: #{$color_drag2};
22
+ --color-drag1-background: #{$color_drag1_background};
23
+ --color-drag2-background: #{$color_drag2_background};
22
24
 
23
25
  --font-size: #{$font-size};
24
26
  --font-family: #{$font-family};
@@ -55,14 +57,14 @@
55
57
  pointer-events: none;
56
58
  box-sizing: border-box;
57
59
  border: 2px solid var(--color-drag1);
58
- box-shadow: inset 0 0 60px rgba(0, 0, 0, 0.2);
60
+ background: var(--color-drag1-background);
59
61
  border-radius: 5px;
60
62
  z-index: 1000;
61
63
 
62
64
  &_edge {
63
65
  pointer-events: none;
64
66
  border: 2px solid var(--color-drag2);
65
- box-shadow: inset 0 0 60px rgba(0, 0, 0, 0.2);
67
+ background: var(--color-drag2-background);
66
68
  border-radius: 5px;
67
69
  z-index: 1000;
68
70
  box-sizing: border-box;
@@ -94,7 +96,7 @@
94
96
  justify-content: center;
95
97
  flex-direction: column;
96
98
  overflow: hidden;
97
- padding: 10px;
99
+ padding: 0.5em 1em;
98
100
  word-wrap: break-word;
99
101
  font-size: var(--font-size);
100
102
  font-family: var(--font-family);
@@ -157,6 +159,9 @@
157
159
 
158
160
  &_tab_container {
159
161
  display: flex;
162
+ gap: 4px;
163
+ padding-left: 4px;
164
+ padding-right: 4px;
160
165
  box-sizing: border-box;
161
166
  position: absolute;
162
167
  top: 0;
@@ -182,6 +187,14 @@
182
187
  }
183
188
  }
184
189
 
190
+ &__tab_button_stamp {
191
+ display: inline-flex;
192
+ align-items: center;
193
+ gap: 0.3em;
194
+ white-space: nowrap;
195
+ box-sizing: border-box;
196
+ }
197
+
185
198
  &__tab {
186
199
  overflow: auto;
187
200
  position: absolute;
@@ -190,11 +203,12 @@
190
203
  background-color: var(--color-background);
191
204
 
192
205
  &_button {
193
- display: inline-flex;
206
+ display: flex;
207
+ gap: 0.3em;
194
208
  align-items: center;
195
209
  box-sizing: border-box;
196
- padding: 3px 8px; // if you change top or bottom update the tabset_sizer above
197
- margin: 0px 2px;
210
+ padding: 3px 0.5em; // if you change top or bottom update the tabset_sizer above
211
+
198
212
  cursor: pointer;
199
213
  @include tab_button_mixin;
200
214
 
@@ -220,11 +234,11 @@
220
234
  }
221
235
 
222
236
  &_leading {
223
- display: inline-block;
237
+ display: flex;
224
238
  }
225
239
 
226
240
  &_content {
227
- display: inline-block;
241
+ display: flex;
228
242
  }
229
243
 
230
244
  &_textbox {
@@ -242,66 +256,75 @@
242
256
  }
243
257
 
244
258
  &_trailing {
245
- display: inline-block;
246
- margin-left: 8px;
247
- min-width: 8px;
248
- min-height: 8px;
259
+ display: flex;
260
+ visibility: hidden;
261
+ border-radius: 4px;
262
+ &:hover {
263
+ @include close_button_hovered_mixin;
264
+ }
249
265
  }
250
266
  @media (pointer: coarse) {
251
267
  &_trailing {
252
- min-width: 20px;
253
- min-height: 20px;
254
268
  }
255
269
  }
256
270
  @media (hover: hover) {
257
271
  &:hover &_trailing {
258
- background: transparent url("../images/close.png") no-repeat center;
272
+ visibility: visible;
259
273
  }
260
274
  }
261
275
 
262
276
  &--selected &_trailing {
263
- background: transparent url("../images/close.png") no-repeat center;
277
+ visibility: visible;
264
278
  }
265
279
 
266
280
  &_overflow {
267
- margin-left: 10px;
268
- padding-left: 12px;
281
+ display: flex;
282
+ align-items: center;
269
283
  border: none;
270
284
  color: gray;
271
285
  font-size: inherit;
272
- background: transparent url("../images/more2.png") no-repeat left;
286
+ background-color: transparent;
273
287
  }
274
288
  }
275
289
 
276
290
  &_toolbar {
277
291
  display: flex;
278
292
  align-items: center;
293
+ gap: .3em;
294
+ padding-left: .5em;
295
+ padding-right: .3em;
279
296
 
280
297
  &_button {
281
- min-width: 20px;
282
- min-height: 20px;
283
298
  border: none;
284
299
  outline: none;
300
+ font-size: inherit;
301
+ margin: 0px;
302
+ background-color: transparent;
303
+ border-radius: 4px;
304
+ padding: 1px;
305
+ @media (hover: hover) {
306
+ &:hover {
307
+ @include toolbar_button_hovered_mixin;
308
+ }
309
+ }
285
310
 
286
311
  &-min {
287
- background: transparent url("../images/maximize.png") no-repeat center;
288
312
  }
289
313
 
290
314
  &-max {
291
- background: transparent url("../images/restore.png") no-repeat center;
292
315
  }
293
316
 
294
317
  &-float {
295
- background: transparent url("../images/popout.png") no-repeat center;
296
318
  }
297
319
 
298
320
  &-close {
299
- background: transparent url("../images/close.png") no-repeat center;
300
321
  }
301
322
  }
302
323
 
303
324
  &_sticky_buttons_container {
304
325
  display: flex;
326
+ gap: 0.3em;
327
+ padding-left: 2px;
305
328
  align-items: center;
306
329
  }
307
330
  }
@@ -375,6 +398,9 @@
375
398
  &_tab_container {
376
399
  white-space: nowrap;
377
400
  display: flex;
401
+ gap: 4px;
402
+ padding-left: 2px;
403
+ padding-right: 2px;
378
404
  box-sizing: border-box;
379
405
  position: absolute;
380
406
  top: 0;
@@ -395,10 +421,11 @@
395
421
 
396
422
  &_button {
397
423
  display: flex;
424
+ gap: 0.3em;
398
425
  align-items: center;
399
426
  cursor: pointer;
400
- padding: 3px 8px;
401
- margin: 2px;
427
+ padding: 3px 0.5em;
428
+ margin: 2px 0px;
402
429
  box-sizing: border-box;
403
430
  white-space: nowrap;
404
431
  @include border_button_mixin;
@@ -417,77 +444,80 @@
417
444
  }
418
445
 
419
446
  &_leading {
420
- display: inline;
447
+ display: flex;
421
448
  }
422
449
 
423
450
  &_content {
424
- display: inline-block;
451
+ display: flex;
425
452
  }
426
453
 
427
454
  &_trailing {
428
- display: inline-block;
429
- margin-left: 8px;
430
- min-width: 8px;
431
- min-height: 8px;
455
+ display: flex;
456
+ border-radius: 4px;
457
+ visibility: hidden;
458
+ &:hover {
459
+ @include close_button_hovered_mixin;
460
+ }
432
461
  }
433
-
434
462
  @media (pointer: coarse) {
435
463
  &_trailing {
436
- min-width: 20px;
437
- min-height: 20px;
438
464
  }
439
465
  }
440
-
441
466
  @media (hover: hover) {
442
467
  &:hover &_trailing {
443
- background: transparent url("../images/close.png") no-repeat center;
468
+ visibility: visible;
444
469
  }
445
470
  }
446
471
 
447
472
  &--selected &_trailing {
448
- background: transparent url("../images/close.png") no-repeat center;
473
+ visibility: visible;
449
474
  }
450
475
  }
451
476
 
452
477
  &_toolbar {
453
478
  display: flex;
479
+ gap: .3em;
454
480
  align-items: center;
455
481
 
456
- &_left {
482
+ &_left,
483
+ &_right {
457
484
  flex-direction: column;
485
+ padding-top: .5em;
486
+ padding-bottom: .3em;
458
487
  }
459
488
 
460
- &_right {
461
- flex-direction: column;
489
+ &_top,
490
+ &_bottom {
491
+ padding-left: .5em;
492
+ padding-right: .3em;
462
493
  }
463
494
 
464
495
  &_button {
465
- min-width: 20px;
466
- min-height: 20px;
467
496
  border: none;
468
497
  outline: none;
498
+ font-size: inherit;
499
+ background-color: transparent;
500
+ border-radius: 4px;
501
+ padding: 1px;
469
502
 
470
503
  &-float {
471
- background: transparent url("../images/popout.png") no-repeat center;
472
504
  }
473
505
 
474
506
  &_overflow {
507
+ display: flex;
508
+ align-items: center;
475
509
  border: none;
476
- padding-left: 12px;
477
510
  color: gray;
478
511
  font-size: inherit;
479
- background: transparent url("../images/more2.png") no-repeat left;
512
+ background-color: transparent;
480
513
  }
481
514
 
482
515
  &_overflow_top,
483
516
  &_overflow_bottom {
484
- margin-left: 10px;
485
517
  }
486
518
 
487
519
  &_overflow_right,
488
520
  &_overflow_left {
489
- padding-right: 0px;
490
- margin-top: 5px;
491
521
  }
492
522
  }
493
523
  }
@@ -498,8 +528,7 @@
498
528
  font-family: var(--font-family);
499
529
 
500
530
  &_item {
501
- margin: 2px;
502
- padding: 2px 10px 2px 10px;
531
+ padding: 2px 0.5em;
503
532
  white-space: nowrap;
504
533
  cursor: pointer;
505
534
  border-radius: 2px;
@@ -522,6 +551,7 @@
522
551
  max-height: 50%;
523
552
  min-width: 100px;
524
553
  overflow: auto;
554
+ padding: 2px;
525
555
  }
526
556
  }
527
557