@ckeditor/ckeditor5-ui 44.3.0 → 45.0.0-alpha.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.
- package/LICENSE.md +1 -1
- package/ckeditor5-metadata.json +1 -1
- package/dist/index-editor.css +28 -0
- package/dist/index.css +33 -0
- package/dist/index.css.map +1 -1
- package/dist/index.js +196 -74
- package/dist/index.js.map +1 -1
- package/dist/translations/be.d.ts +8 -0
- package/dist/translations/be.js +5 -0
- package/dist/translations/be.umd.js +11 -0
- package/lang/translations/be.po +208 -0
- package/package.json +12 -6
- package/src/arialiveannouncer.js +24 -0
- package/src/autocomplete/autocompleteview.js +29 -25
- package/src/badge/badge.js +23 -15
- package/src/bindings/draggableviewmixin.js +12 -12
- package/src/button/buttonview.js +35 -5
- package/src/button/filedialogbuttonview.js +11 -1
- package/src/button/listitembuttonview.js +14 -10
- package/src/button/switchbuttonview.js +4 -0
- package/src/collapsible/collapsibleview.d.ts +1 -4
- package/src/collapsible/collapsibleview.js +13 -2
- package/src/colorgrid/colorgridview.js +18 -2
- package/src/colorgrid/colortileview.d.ts +1 -4
- package/src/colorgrid/colortileview.js +3 -3
- package/src/colorpicker/colorpickerview.js +28 -1
- package/src/colorselector/colorgridsfragmentview.js +80 -4
- package/src/colorselector/colorpickerfragmentview.js +44 -3
- package/src/colorselector/colorselectorview.js +36 -0
- package/src/componentfactory.js +8 -4
- package/src/dialog/dialog.js +18 -0
- package/src/dialog/dialogactionsview.js +20 -0
- package/src/dialog/dialogcontentview.js +4 -0
- package/src/dialog/dialogview.d.ts +1 -1
- package/src/dialog/dialogview.js +56 -11
- package/src/dropdown/button/dropdownbuttonview.d.ts +0 -3
- package/src/dropdown/button/dropdownbuttonview.js +6 -2
- package/src/dropdown/button/splitbuttonview.d.ts +1 -4
- package/src/dropdown/button/splitbuttonview.js +27 -3
- package/src/dropdown/dropdownpanelview.js +8 -0
- package/src/dropdown/dropdownview.js +235 -184
- package/src/dropdown/menu/dropdownmenubuttonview.d.ts +0 -3
- package/src/dropdown/menu/dropdownmenubuttonview.js +6 -2
- package/src/dropdown/menu/dropdownmenulistitembuttonview.js +1 -0
- package/src/dropdown/menu/dropdownmenulistitemview.js +4 -0
- package/src/dropdown/menu/dropdownmenunestedmenuview.js +31 -8
- package/src/dropdown/menu/dropdownmenurootlistview.js +16 -8
- package/src/editableui/editableuiview.js +22 -4
- package/src/editableui/inline/inlineeditableuiview.js +4 -0
- package/src/editorui/accessibilityhelp/accessibilityhelp.js +8 -11
- package/src/editorui/bodycollection.js +13 -0
- package/src/editorui/boxed/boxededitoruiview.js +14 -0
- package/src/editorui/editorui.d.ts +1 -1
- package/src/editorui/editorui.js +56 -25
- package/src/editorui/editoruiview.d.ts +15 -1
- package/src/editorui/editoruiview.js +22 -0
- package/src/editorui/evaluationbadge.js +5 -5
- package/src/editorui/poweredby.d.ts +1 -4
- package/src/editorui/poweredby.js +5 -2
- package/src/focuscycler.js +31 -0
- package/src/formheader/formheaderview.js +8 -0
- package/src/formrow/formrowview.d.ts +57 -0
- package/src/formrow/formrowview.js +56 -0
- package/src/highlightedtext/highlightedtextview.js +1 -1
- package/src/highlightedtext/labelwithhighlightview.js +4 -0
- package/src/icon/iconview.js +25 -16
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/input/inputbase.js +5 -0
- package/src/label/labelview.js +5 -0
- package/src/labeledfield/labeledfieldview.js +20 -0
- package/src/labeledinput/labeledinputview.js +13 -0
- package/src/list/listitemgroupview.js +15 -0
- package/src/list/listitemview.js +4 -0
- package/src/list/listview.js +27 -5
- package/src/menubar/menubarmenubuttonview.d.ts +0 -3
- package/src/menubar/menubarmenubuttonview.js +6 -2
- package/src/menubar/menubarmenupanelview.js +4 -0
- package/src/menubar/menubarmenuview.js +23 -6
- package/src/menubar/menubarview.d.ts +8 -0
- package/src/menubar/menubarview.js +27 -7
- package/src/menubar/utils.d.ts +6 -0
- package/src/menubar/utils.js +16 -3
- package/src/model.js +1 -1
- package/src/panel/balloon/balloonpanelview.js +464 -449
- package/src/panel/balloon/contextualballoon.js +60 -24
- package/src/panel/sticky/stickypanelview.js +14 -0
- package/src/search/searchresultsview.js +18 -0
- package/src/search/text/searchtextqueryview.d.ts +0 -3
- package/src/search/text/searchtextqueryview.js +15 -3
- package/src/search/text/searchtextview.js +43 -3
- package/src/template.js +69 -1
- package/src/textarea/textareaview.js +12 -5
- package/src/toolbar/balloon/balloontoolbar.d.ts +1 -1
- package/src/toolbar/balloon/balloontoolbar.js +38 -11
- package/src/toolbar/block/blocktoolbar.js +24 -8
- package/src/toolbar/toolbarview.d.ts +15 -2
- package/src/toolbar/toolbarview.js +206 -58
- package/src/tooltipmanager.js +50 -32
- package/src/view.js +76 -0
- package/src/viewcollection.js +4 -0
- package/theme/components/form/form.css +87 -0
- package/theme/components/formrow/formrow.css +32 -0
- package/theme/icons/accessibility.svg +0 -1
- package/theme/icons/color-tile-check.svg +0 -1
- package/theme/icons/dropdown-arrow.svg +0 -1
- package/theme/icons/project-logo.svg +0 -1
|
@@ -13,24 +13,77 @@ import preventDefault from '../bindings/preventdefault.js';
|
|
|
13
13
|
import { createDropdown, addToolbarToDropdown } from '../dropdown/utils.js';
|
|
14
14
|
import normalizeToolbarConfig from './normalizetoolbarconfig.js';
|
|
15
15
|
import { FocusTracker, KeystrokeHandler, Rect, ResizeObserver, global, isVisible, logWarning } from '@ckeditor/ckeditor5-utils';
|
|
16
|
-
import {
|
|
17
|
-
import { isObject } from '
|
|
16
|
+
import { IconAlignLeft, IconBold, IconImportExport, IconParagraph, IconPlus, IconText, IconThreeVerticalDots, IconPilcrow, IconDragIndicator } from '@ckeditor/ckeditor5-icons';
|
|
17
|
+
import { isObject } from 'es-toolkit/compat';
|
|
18
18
|
import '../../theme/components/toolbar/toolbar.css';
|
|
19
19
|
export const NESTED_TOOLBAR_ICONS = /* #__PURE__ */ (() => ({
|
|
20
|
-
alignLeft:
|
|
21
|
-
bold:
|
|
22
|
-
importExport:
|
|
23
|
-
paragraph:
|
|
24
|
-
plus:
|
|
25
|
-
text:
|
|
26
|
-
threeVerticalDots:
|
|
27
|
-
pilcrow:
|
|
28
|
-
dragIndicator:
|
|
20
|
+
alignLeft: IconAlignLeft,
|
|
21
|
+
bold: IconBold,
|
|
22
|
+
importExport: IconImportExport,
|
|
23
|
+
paragraph: IconParagraph,
|
|
24
|
+
plus: IconPlus,
|
|
25
|
+
text: IconText,
|
|
26
|
+
threeVerticalDots: IconThreeVerticalDots,
|
|
27
|
+
pilcrow: IconPilcrow,
|
|
28
|
+
dragIndicator: IconDragIndicator
|
|
29
29
|
}))();
|
|
30
30
|
/**
|
|
31
31
|
* The toolbar view class.
|
|
32
32
|
*/
|
|
33
33
|
export default class ToolbarView extends View {
|
|
34
|
+
/**
|
|
35
|
+
* A reference to the options object passed to the constructor.
|
|
36
|
+
*/
|
|
37
|
+
options;
|
|
38
|
+
/**
|
|
39
|
+
* A collection of toolbar items (buttons, dropdowns, etc.).
|
|
40
|
+
*/
|
|
41
|
+
items;
|
|
42
|
+
/**
|
|
43
|
+
* Tracks information about the DOM focus in the toolbar.
|
|
44
|
+
*/
|
|
45
|
+
focusTracker;
|
|
46
|
+
/**
|
|
47
|
+
* An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}
|
|
48
|
+
* to handle keyboard navigation in the toolbar.
|
|
49
|
+
*/
|
|
50
|
+
keystrokes;
|
|
51
|
+
/**
|
|
52
|
+
* A (child) view containing {@link #items toolbar items}.
|
|
53
|
+
*/
|
|
54
|
+
itemsView;
|
|
55
|
+
/**
|
|
56
|
+
* A top–level collection aggregating building blocks of the toolbar.
|
|
57
|
+
*
|
|
58
|
+
* ┌───────────────── ToolbarView ─────────────────┐
|
|
59
|
+
* | ┌──────────────── #children ────────────────┐ |
|
|
60
|
+
* | | ┌──────────── #itemsView ───────────┐ | |
|
|
61
|
+
* | | | [ item1 ] [ item2 ] ... [ itemN ] | | |
|
|
62
|
+
* | | └──────────────────────────────────-┘ | |
|
|
63
|
+
* | └───────────────────────────────────────────┘ |
|
|
64
|
+
* └───────────────────────────────────────────────┘
|
|
65
|
+
*
|
|
66
|
+
* By default, it contains the {@link #itemsView} but it can be extended with additional
|
|
67
|
+
* UI elements when necessary.
|
|
68
|
+
*/
|
|
69
|
+
children;
|
|
70
|
+
/**
|
|
71
|
+
* A collection of {@link #items} that take part in the focus cycling
|
|
72
|
+
* (i.e. navigation using the keyboard). Usually, it contains a subset of {@link #items} with
|
|
73
|
+
* some optional UI elements that also belong to the toolbar and should be focusable
|
|
74
|
+
* by the user.
|
|
75
|
+
*/
|
|
76
|
+
focusables;
|
|
77
|
+
/**
|
|
78
|
+
* Helps cycling over {@link #focusables focusable items} in the toolbar.
|
|
79
|
+
*/
|
|
80
|
+
_focusCycler;
|
|
81
|
+
/**
|
|
82
|
+
* An instance of the active toolbar behavior that shapes its look and functionality.
|
|
83
|
+
*
|
|
84
|
+
* See {@link module:ui/toolbar/toolbarview~ToolbarBehavior} to learn more.
|
|
85
|
+
*/
|
|
86
|
+
_behavior;
|
|
34
87
|
/**
|
|
35
88
|
* Creates an instance of the {@link module:ui/toolbar/toolbarview~ToolbarView} class.
|
|
36
89
|
*
|
|
@@ -47,11 +100,14 @@ export default class ToolbarView extends View {
|
|
|
47
100
|
this.set('ariaLabel', t('Editor toolbar'));
|
|
48
101
|
this.set('maxWidth', 'auto');
|
|
49
102
|
this.set('role', 'toolbar');
|
|
103
|
+
this.set('isGrouping', !!this.options.shouldGroupWhenFull);
|
|
50
104
|
this.items = this.createCollection();
|
|
51
105
|
this.focusTracker = new FocusTracker();
|
|
52
106
|
this.keystrokes = new KeystrokeHandler();
|
|
53
107
|
this.set('class', undefined);
|
|
54
108
|
this.set('isCompact', false);
|
|
109
|
+
// Static toolbar can be vertical when needed.
|
|
110
|
+
this.set('isVertical', false);
|
|
55
111
|
this.itemsView = new ItemsView(locale);
|
|
56
112
|
this.children = this.createCollection();
|
|
57
113
|
this.children.add(this.itemsView);
|
|
@@ -72,7 +128,11 @@ export default class ToolbarView extends View {
|
|
|
72
128
|
'ck',
|
|
73
129
|
'ck-toolbar',
|
|
74
130
|
bind.to('class'),
|
|
75
|
-
bind.if('isCompact', 'ck-toolbar_compact')
|
|
131
|
+
bind.if('isCompact', 'ck-toolbar_compact'),
|
|
132
|
+
// To group items dynamically, the toolbar needs a dedicated CSS class. Only used for dynamic grouping.
|
|
133
|
+
bind.if('isGrouping', 'ck-toolbar_grouping'),
|
|
134
|
+
// When vertical, the toolbar has an additional CSS class. Only used for static layout.
|
|
135
|
+
bind.if('isVertical', 'ck-toolbar_vertical')
|
|
76
136
|
];
|
|
77
137
|
if (this.options.shouldGroupWhenFull && this.options.isFloating) {
|
|
78
138
|
classes.push('ck-toolbar_floating');
|
|
@@ -149,6 +209,25 @@ export default class ToolbarView extends View {
|
|
|
149
209
|
fillFromConfig(itemsOrConfig, factory, removeItems) {
|
|
150
210
|
this.items.addMany(this._buildItemsFromConfig(itemsOrConfig, factory, removeItems));
|
|
151
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Changes the behavior of toolbar if it does not fit into the available space.
|
|
214
|
+
*/
|
|
215
|
+
switchBehavior(newBehaviorType) {
|
|
216
|
+
if (this._behavior.type !== newBehaviorType) {
|
|
217
|
+
this._behavior.destroy();
|
|
218
|
+
this.itemsView.children.clear();
|
|
219
|
+
this.focusables.clear();
|
|
220
|
+
if (newBehaviorType === 'dynamic') {
|
|
221
|
+
this._behavior = new DynamicGrouping(this);
|
|
222
|
+
this._behavior.render(this);
|
|
223
|
+
this._behavior.refreshItems();
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
this._behavior = new StaticLayout(this);
|
|
227
|
+
this._behavior.render(this);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
152
231
|
/**
|
|
153
232
|
* A utility that expands the plain toolbar configuration into a list of view items using a given component factory.
|
|
154
233
|
*
|
|
@@ -336,7 +415,7 @@ export default class ToolbarView extends View {
|
|
|
336
415
|
// Allow disabling icon by passing false.
|
|
337
416
|
if (icon !== false) {
|
|
338
417
|
// A pre-defined icon picked by name, SVG string, a fallback (default) icon.
|
|
339
|
-
dropdownView.buttonView.icon = NESTED_TOOLBAR_ICONS[icon] || icon ||
|
|
418
|
+
dropdownView.buttonView.icon = NESTED_TOOLBAR_ICONS[icon] || icon || IconThreeVerticalDots;
|
|
340
419
|
}
|
|
341
420
|
// If the icon is disabled, display the label automatically.
|
|
342
421
|
else {
|
|
@@ -351,6 +430,10 @@ export default class ToolbarView extends View {
|
|
|
351
430
|
* {@link module:ui/toolbar/toolbarview~ToolbarView#items}.
|
|
352
431
|
*/
|
|
353
432
|
class ItemsView extends View {
|
|
433
|
+
/**
|
|
434
|
+
* A collection of items (buttons, dropdowns, etc.).
|
|
435
|
+
*/
|
|
436
|
+
children;
|
|
354
437
|
/**
|
|
355
438
|
* @inheritDoc
|
|
356
439
|
*/
|
|
@@ -375,6 +458,10 @@ class ItemsView extends View {
|
|
|
375
458
|
* using the {@link module:ui/toolbar/toolbarview~ToolbarView#isVertical} property.
|
|
376
459
|
*/
|
|
377
460
|
class StaticLayout {
|
|
461
|
+
/**
|
|
462
|
+
* Toolbar behavior type.
|
|
463
|
+
*/
|
|
464
|
+
type = 'static';
|
|
378
465
|
/**
|
|
379
466
|
* Creates an instance of the {@link module:ui/toolbar/toolbarview~StaticLayout} toolbar
|
|
380
467
|
* behavior.
|
|
@@ -382,21 +469,11 @@ class StaticLayout {
|
|
|
382
469
|
* @param view An instance of the toolbar that this behavior is added to.
|
|
383
470
|
*/
|
|
384
471
|
constructor(view) {
|
|
385
|
-
|
|
386
|
-
// Static toolbar can be vertical when needed.
|
|
387
|
-
view.set('isVertical', false);
|
|
472
|
+
view.isGrouping = false;
|
|
388
473
|
// 1:1 pass–through binding, all ToolbarView#items are visible.
|
|
389
474
|
view.itemsView.children.bindTo(view.items).using(item => item);
|
|
390
475
|
// 1:1 pass–through binding, all ToolbarView#items are focusable.
|
|
391
476
|
view.focusables.bindTo(view.items).using(item => isFocusable(item) ? item : null);
|
|
392
|
-
view.extendTemplate({
|
|
393
|
-
attributes: {
|
|
394
|
-
class: [
|
|
395
|
-
// When vertical, the toolbar has an additional CSS class.
|
|
396
|
-
bind.if('isVertical', 'ck-toolbar_vertical')
|
|
397
|
-
]
|
|
398
|
-
}
|
|
399
|
-
});
|
|
400
477
|
}
|
|
401
478
|
/**
|
|
402
479
|
* @inheritDoc
|
|
@@ -426,6 +503,91 @@ class StaticLayout {
|
|
|
426
503
|
* ```
|
|
427
504
|
*/
|
|
428
505
|
class DynamicGrouping {
|
|
506
|
+
/**
|
|
507
|
+
* Toolbar behavior type.
|
|
508
|
+
*/
|
|
509
|
+
type = 'dynamic';
|
|
510
|
+
/**
|
|
511
|
+
* A toolbar view this behavior belongs to.
|
|
512
|
+
*/
|
|
513
|
+
view;
|
|
514
|
+
/**
|
|
515
|
+
* A collection of toolbar children.
|
|
516
|
+
*/
|
|
517
|
+
viewChildren;
|
|
518
|
+
/**
|
|
519
|
+
* A collection of focusable toolbar elements.
|
|
520
|
+
*/
|
|
521
|
+
viewFocusables;
|
|
522
|
+
/**
|
|
523
|
+
* A view containing toolbar items.
|
|
524
|
+
*/
|
|
525
|
+
viewItemsView;
|
|
526
|
+
/**
|
|
527
|
+
* Toolbar focus tracker.
|
|
528
|
+
*/
|
|
529
|
+
viewFocusTracker;
|
|
530
|
+
/**
|
|
531
|
+
* Toolbar locale.
|
|
532
|
+
*/
|
|
533
|
+
viewLocale;
|
|
534
|
+
/**
|
|
535
|
+
* A subset of toolbar {@link module:ui/toolbar/toolbarview~ToolbarView#items}.
|
|
536
|
+
* Aggregates items that fit into a single row of the toolbar and were not {@link #groupedItems grouped}
|
|
537
|
+
* into a {@link #groupedItemsDropdown dropdown}. Items of this collection are displayed in the
|
|
538
|
+
* {@link module:ui/toolbar/toolbarview~ToolbarView#itemsView}.
|
|
539
|
+
*
|
|
540
|
+
* When none of the {@link module:ui/toolbar/toolbarview~ToolbarView#items} were grouped, it
|
|
541
|
+
* matches the {@link module:ui/toolbar/toolbarview~ToolbarView#items} collection in size and order.
|
|
542
|
+
*/
|
|
543
|
+
ungroupedItems;
|
|
544
|
+
/**
|
|
545
|
+
* A subset of toolbar {@link module:ui/toolbar/toolbarview~ToolbarView#items}.
|
|
546
|
+
* A collection of the toolbar items that do not fit into a single row of the toolbar.
|
|
547
|
+
* Grouped items are displayed in a dedicated {@link #groupedItemsDropdown dropdown}.
|
|
548
|
+
*
|
|
549
|
+
* When none of the {@link module:ui/toolbar/toolbarview~ToolbarView#items} were grouped,
|
|
550
|
+
* this collection is empty.
|
|
551
|
+
*/
|
|
552
|
+
groupedItems;
|
|
553
|
+
/**
|
|
554
|
+
* The dropdown that aggregates {@link #groupedItems grouped items} that do not fit into a single
|
|
555
|
+
* row of the toolbar. It is displayed on demand as the last of
|
|
556
|
+
* {@link module:ui/toolbar/toolbarview~ToolbarView#children toolbar children} and offers another
|
|
557
|
+
* (nested) toolbar which displays items that would normally overflow.
|
|
558
|
+
*/
|
|
559
|
+
groupedItemsDropdown;
|
|
560
|
+
/**
|
|
561
|
+
* An instance of the resize observer that helps dynamically determine the geometry of the toolbar
|
|
562
|
+
* and manage items that do not fit into a single row.
|
|
563
|
+
*
|
|
564
|
+
* **Note:** Created in {@link #_enableGroupingOnResize}.
|
|
565
|
+
*
|
|
566
|
+
* @readonly
|
|
567
|
+
*/
|
|
568
|
+
resizeObserver = null;
|
|
569
|
+
/**
|
|
570
|
+
* A cached value of the horizontal padding style used by {@link #_updateGrouping}
|
|
571
|
+
* to manage the {@link module:ui/toolbar/toolbarview~ToolbarView#items} that do not fit into
|
|
572
|
+
* a single toolbar line. This value can be reused between updates because it is unlikely that
|
|
573
|
+
* the padding will change and re–using `Window.getComputedStyle()` is expensive.
|
|
574
|
+
*
|
|
575
|
+
* @readonly
|
|
576
|
+
*/
|
|
577
|
+
cachedPadding = null;
|
|
578
|
+
/**
|
|
579
|
+
* A flag indicating that an items grouping update has been queued (e.g. due to the toolbar being visible)
|
|
580
|
+
* and should be executed immediately the next time the toolbar shows up.
|
|
581
|
+
*
|
|
582
|
+
* @readonly
|
|
583
|
+
*/
|
|
584
|
+
shouldUpdateGroupingOnNextResize = false;
|
|
585
|
+
/**
|
|
586
|
+
* Toolbar element.
|
|
587
|
+
*
|
|
588
|
+
* @readonly
|
|
589
|
+
*/
|
|
590
|
+
viewElement;
|
|
429
591
|
/**
|
|
430
592
|
* Creates an instance of the {@link module:ui/toolbar/toolbarview~DynamicGrouping} toolbar
|
|
431
593
|
* behavior.
|
|
@@ -433,37 +595,13 @@ class DynamicGrouping {
|
|
|
433
595
|
* @param view An instance of the toolbar that this behavior is added to.
|
|
434
596
|
*/
|
|
435
597
|
constructor(view) {
|
|
436
|
-
/**
|
|
437
|
-
* An instance of the resize observer that helps dynamically determine the geometry of the toolbar
|
|
438
|
-
* and manage items that do not fit into a single row.
|
|
439
|
-
*
|
|
440
|
-
* **Note:** Created in {@link #_enableGroupingOnResize}.
|
|
441
|
-
*
|
|
442
|
-
* @readonly
|
|
443
|
-
*/
|
|
444
|
-
this.resizeObserver = null;
|
|
445
|
-
/**
|
|
446
|
-
* A cached value of the horizontal padding style used by {@link #_updateGrouping}
|
|
447
|
-
* to manage the {@link module:ui/toolbar/toolbarview~ToolbarView#items} that do not fit into
|
|
448
|
-
* a single toolbar line. This value can be reused between updates because it is unlikely that
|
|
449
|
-
* the padding will change and re–using `Window.getComputedStyle()` is expensive.
|
|
450
|
-
*
|
|
451
|
-
* @readonly
|
|
452
|
-
*/
|
|
453
|
-
this.cachedPadding = null;
|
|
454
|
-
/**
|
|
455
|
-
* A flag indicating that an items grouping update has been queued (e.g. due to the toolbar being visible)
|
|
456
|
-
* and should be executed immediately the next time the toolbar shows up.
|
|
457
|
-
*
|
|
458
|
-
* @readonly
|
|
459
|
-
*/
|
|
460
|
-
this.shouldUpdateGroupingOnNextResize = false;
|
|
461
598
|
this.view = view;
|
|
462
599
|
this.viewChildren = view.children;
|
|
463
600
|
this.viewFocusables = view.focusables;
|
|
464
601
|
this.viewItemsView = view.itemsView;
|
|
465
602
|
this.viewFocusTracker = view.focusTracker;
|
|
466
603
|
this.viewLocale = view.locale;
|
|
604
|
+
this.view.isGrouping = true;
|
|
467
605
|
this.ungroupedItems = view.createCollection();
|
|
468
606
|
this.groupedItems = view.createCollection();
|
|
469
607
|
this.groupedItemsDropdown = this._createGroupedItemsDropdown();
|
|
@@ -505,14 +643,6 @@ class DynamicGrouping {
|
|
|
505
643
|
// some new space is available and we could do some ungrouping.
|
|
506
644
|
this._updateGrouping();
|
|
507
645
|
});
|
|
508
|
-
view.extendTemplate({
|
|
509
|
-
attributes: {
|
|
510
|
-
class: [
|
|
511
|
-
// To group items dynamically, the toolbar needs a dedicated CSS class.
|
|
512
|
-
'ck-toolbar_grouping'
|
|
513
|
-
]
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
646
|
}
|
|
517
647
|
/**
|
|
518
648
|
* Enables dynamic items grouping based on the dimensions of the toolbar.
|
|
@@ -531,8 +661,26 @@ class DynamicGrouping {
|
|
|
531
661
|
// The dropdown may not be in ToolbarView#children at the moment of toolbar destruction
|
|
532
662
|
// so let's make sure it's actually destroyed along with the toolbar.
|
|
533
663
|
this.groupedItemsDropdown.destroy();
|
|
664
|
+
// Do not try to remove the same elements if they are already removed.
|
|
665
|
+
if (this.viewChildren.length > 1) {
|
|
666
|
+
this.viewChildren.remove(this.groupedItemsDropdown);
|
|
667
|
+
this.viewChildren.remove(this.viewChildren.last);
|
|
668
|
+
}
|
|
534
669
|
this.resizeObserver.destroy();
|
|
535
670
|
}
|
|
671
|
+
/**
|
|
672
|
+
* Re-adds all items to the toolbar. Use when the toolbar is re-rendered and the items grouping is lost.
|
|
673
|
+
*/
|
|
674
|
+
refreshItems() {
|
|
675
|
+
const view = this.view;
|
|
676
|
+
if (view.items.length) {
|
|
677
|
+
for (let currentIndex = 0; currentIndex < view.items.length; currentIndex++) {
|
|
678
|
+
const item = [...view.items][currentIndex];
|
|
679
|
+
this.ungroupedItems.add(item, currentIndex);
|
|
680
|
+
}
|
|
681
|
+
this._updateGrouping();
|
|
682
|
+
}
|
|
683
|
+
}
|
|
536
684
|
/**
|
|
537
685
|
* When called, it will check if any of the {@link #ungroupedItems} do not fit into a single row of the toolbar,
|
|
538
686
|
* and it will move them to the {@link #groupedItems} when it happens.
|
|
@@ -694,7 +842,7 @@ class DynamicGrouping {
|
|
|
694
842
|
label: t('Show more items'),
|
|
695
843
|
tooltip: true,
|
|
696
844
|
tooltipPosition: locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw',
|
|
697
|
-
icon:
|
|
845
|
+
icon: IconThreeVerticalDots
|
|
698
846
|
});
|
|
699
847
|
return dropdown;
|
|
700
848
|
}
|
package/src/tooltipmanager.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import View from './view.js';
|
|
9
9
|
import BalloonPanelView from './panel/balloon/balloonpanelview.js';
|
|
10
10
|
import { DomEmitterMixin, first, global, isVisible } from '@ckeditor/ckeditor5-utils';
|
|
11
|
-
import { isElement, debounce } from '
|
|
11
|
+
import { isElement, debounce } from 'es-toolkit/compat';
|
|
12
12
|
import '../theme/components/tooltip/tooltip.css';
|
|
13
13
|
const BALLOON_CLASS = 'ck-tooltip';
|
|
14
14
|
/**
|
|
@@ -74,24 +74,60 @@ const BALLOON_CLASS = 'ck-tooltip';
|
|
|
74
74
|
* {@link module:ui/editorui/editorui~EditorUI} of the first editor.
|
|
75
75
|
*/
|
|
76
76
|
class TooltipManager extends /* #__PURE__ */ DomEmitterMixin() {
|
|
77
|
+
/**
|
|
78
|
+
* The view rendering text of the tooltip.
|
|
79
|
+
*/
|
|
80
|
+
tooltipTextView;
|
|
81
|
+
/**
|
|
82
|
+
* The instance of the balloon panel that renders and positions the tooltip.
|
|
83
|
+
*/
|
|
84
|
+
balloonPanelView;
|
|
85
|
+
/**
|
|
86
|
+
* A set of default {@link module:utils/dom/position~PositioningFunction positioning functions} used by the `TooltipManager`
|
|
87
|
+
* to pin tooltips in different positions.
|
|
88
|
+
*/
|
|
89
|
+
static defaultBalloonPositions = /* #__PURE__ */ BalloonPanelView.generatePositions({
|
|
90
|
+
heightOffset: 5,
|
|
91
|
+
sideOffset: 13
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* Stores the reference to the DOM element the tooltip is attached to. `null` when there's no tooltip
|
|
95
|
+
* in the UI.
|
|
96
|
+
*/
|
|
97
|
+
_currentElementWithTooltip = null;
|
|
98
|
+
/**
|
|
99
|
+
* Stores the current tooltip position. `null` when there's no tooltip in the UI.
|
|
100
|
+
*/
|
|
101
|
+
_currentTooltipPosition = null;
|
|
102
|
+
/**
|
|
103
|
+
* An instance of the mutation observer that keeps track on target element attributes changes.
|
|
104
|
+
*/
|
|
105
|
+
_mutationObserver = null;
|
|
106
|
+
/**
|
|
107
|
+
* A debounced version of {@link #_pinTooltip}. Tooltips show with a delay to avoid flashing and
|
|
108
|
+
* to improve the UX.
|
|
109
|
+
*/
|
|
110
|
+
_pinTooltipDebounced;
|
|
111
|
+
/**
|
|
112
|
+
* A debounced version of {@link #_unpinTooltip}. Tooltips hide with a delay to allow hovering of their titles.
|
|
113
|
+
*/
|
|
114
|
+
_unpinTooltipDebounced;
|
|
115
|
+
_watchdogExcluded;
|
|
116
|
+
/**
|
|
117
|
+
* A set of editors the single tooltip manager instance must listen to.
|
|
118
|
+
* This is mostly to handle `EditorUI#update` listeners from individual editors.
|
|
119
|
+
*/
|
|
120
|
+
static _editors = new Set();
|
|
121
|
+
/**
|
|
122
|
+
* A reference to the `TooltipManager` instance. The class is a singleton and as such,
|
|
123
|
+
* successive attempts at creating instances should return this instance.
|
|
124
|
+
*/
|
|
125
|
+
static _instance = null;
|
|
77
126
|
/**
|
|
78
127
|
* Creates an instance of the tooltip manager.
|
|
79
128
|
*/
|
|
80
129
|
constructor(editor) {
|
|
81
130
|
super();
|
|
82
|
-
/**
|
|
83
|
-
* Stores the reference to the DOM element the tooltip is attached to. `null` when there's no tooltip
|
|
84
|
-
* in the UI.
|
|
85
|
-
*/
|
|
86
|
-
this._currentElementWithTooltip = null;
|
|
87
|
-
/**
|
|
88
|
-
* Stores the current tooltip position. `null` when there's no tooltip in the UI.
|
|
89
|
-
*/
|
|
90
|
-
this._currentTooltipPosition = null;
|
|
91
|
-
/**
|
|
92
|
-
* An instance of the mutation observer that keeps track on target element attributes changes.
|
|
93
|
-
*/
|
|
94
|
-
this._mutationObserver = null;
|
|
95
131
|
TooltipManager._editors.add(editor);
|
|
96
132
|
// TooltipManager must be a singleton. Multiple instances would mean multiple tooltips attached
|
|
97
133
|
// to the same DOM element with data-cke-tooltip-* attributes.
|
|
@@ -383,24 +419,6 @@ class TooltipManager extends /* #__PURE__ */ DomEmitterMixin() {
|
|
|
383
419
|
});
|
|
384
420
|
}
|
|
385
421
|
}
|
|
386
|
-
/**
|
|
387
|
-
* A set of default {@link module:utils/dom/position~PositioningFunction positioning functions} used by the `TooltipManager`
|
|
388
|
-
* to pin tooltips in different positions.
|
|
389
|
-
*/
|
|
390
|
-
TooltipManager.defaultBalloonPositions = BalloonPanelView.generatePositions({
|
|
391
|
-
heightOffset: 5,
|
|
392
|
-
sideOffset: 13
|
|
393
|
-
});
|
|
394
|
-
/**
|
|
395
|
-
* A set of editors the single tooltip manager instance must listen to.
|
|
396
|
-
* This is mostly to handle `EditorUI#update` listeners from individual editors.
|
|
397
|
-
*/
|
|
398
|
-
TooltipManager._editors = new Set();
|
|
399
|
-
/**
|
|
400
|
-
* A reference to the `TooltipManager` instance. The class is a singleton and as such,
|
|
401
|
-
* successive attempts at creating instances should return this instance.
|
|
402
|
-
*/
|
|
403
|
-
TooltipManager._instance = null;
|
|
404
422
|
export default TooltipManager;
|
|
405
423
|
function getDescendantWithTooltip(element) {
|
|
406
424
|
if (!isElement(element)) {
|
package/src/view.js
CHANGED
|
@@ -76,6 +76,82 @@ import '../theme/globals/globals.css';
|
|
|
76
76
|
* ```
|
|
77
77
|
*/
|
|
78
78
|
export default class View extends /* #__PURE__ */ DomEmitterMixin(/* #__PURE__ */ ObservableMixin()) {
|
|
79
|
+
/**
|
|
80
|
+
* An HTML element of the view. `null` until {@link #render rendered}
|
|
81
|
+
* from the {@link #template}.
|
|
82
|
+
*
|
|
83
|
+
* ```ts
|
|
84
|
+
* class SampleView extends View {
|
|
85
|
+
* constructor() {
|
|
86
|
+
* super();
|
|
87
|
+
*
|
|
88
|
+
* // A template instance the #element will be created from.
|
|
89
|
+
* this.setTemplate( {
|
|
90
|
+
* tag: 'p'
|
|
91
|
+
*
|
|
92
|
+
* // ...
|
|
93
|
+
* } );
|
|
94
|
+
* }
|
|
95
|
+
* }
|
|
96
|
+
*
|
|
97
|
+
* const view = new SampleView();
|
|
98
|
+
*
|
|
99
|
+
* // Renders the #template.
|
|
100
|
+
* view.render();
|
|
101
|
+
*
|
|
102
|
+
* // Append the HTML element of the view to <body>.
|
|
103
|
+
* document.body.appendChild( view.element );
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* **Note**: The element of the view can also be assigned directly:
|
|
107
|
+
*
|
|
108
|
+
* ```ts
|
|
109
|
+
* view.element = document.querySelector( '#my-container' );
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
element;
|
|
113
|
+
/**
|
|
114
|
+
* Set `true` when the view has already been {@link module:ui/view~View#render rendered}.
|
|
115
|
+
*
|
|
116
|
+
* @readonly
|
|
117
|
+
*/
|
|
118
|
+
isRendered;
|
|
119
|
+
/**
|
|
120
|
+
* A set of tools to localize the user interface.
|
|
121
|
+
*
|
|
122
|
+
* Also see {@link module:core/editor/editor~Editor#locale}.
|
|
123
|
+
*
|
|
124
|
+
* @readonly
|
|
125
|
+
*/
|
|
126
|
+
locale;
|
|
127
|
+
/**
|
|
128
|
+
* Shorthand for {@link module:utils/locale~Locale#t}.
|
|
129
|
+
*
|
|
130
|
+
* Note: If {@link #locale} instance hasn't been passed to the view this method may not
|
|
131
|
+
* be available.
|
|
132
|
+
*
|
|
133
|
+
* @see module:utils/locale~Locale#t
|
|
134
|
+
*/
|
|
135
|
+
t;
|
|
136
|
+
/**
|
|
137
|
+
* Template of this view. It provides the {@link #element} representing
|
|
138
|
+
* the view in DOM, which is {@link #render rendered}.
|
|
139
|
+
*/
|
|
140
|
+
template;
|
|
141
|
+
/**
|
|
142
|
+
* Collections registered with {@link #createCollection}.
|
|
143
|
+
*/
|
|
144
|
+
_viewCollections;
|
|
145
|
+
/**
|
|
146
|
+
* A collection of view instances, which have been added directly
|
|
147
|
+
* into the {@link module:ui/template~Template#children}.
|
|
148
|
+
*/
|
|
149
|
+
_unboundChildren;
|
|
150
|
+
/**
|
|
151
|
+
* Cached {@link module:ui/template~BindChain bind chain} object created by the
|
|
152
|
+
* {@link #template}. See {@link #bindTemplate}.
|
|
153
|
+
*/
|
|
154
|
+
_bindTemplate;
|
|
79
155
|
/**
|
|
80
156
|
* Creates an instance of the {@link module:ui/view~View} class.
|
|
81
157
|
*
|
package/src/viewcollection.js
CHANGED
|
@@ -47,6 +47,10 @@ import { CKEditorError, Collection } from '@ckeditor/ckeditor5-utils';
|
|
|
47
47
|
* of a {@link module:ui/template~Template template}.
|
|
48
48
|
*/
|
|
49
49
|
export default class ViewCollection extends Collection {
|
|
50
|
+
/**
|
|
51
|
+
* A parent element within which child views are rendered and managed in DOM.
|
|
52
|
+
*/
|
|
53
|
+
_parentElement;
|
|
50
54
|
/**
|
|
51
55
|
* Creates a new instance of the {@link module:ui/viewcollection~ViewCollection}.
|
|
52
56
|
*
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
@import "@ckeditor/ckeditor5-ui/theme/mixins/_rwd.css";
|
|
7
|
+
@import "@ckeditor/ckeditor5-ui/theme/mixins/_dir.css";
|
|
8
|
+
|
|
9
|
+
:root {
|
|
10
|
+
--ck-form-default-width: 340px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.ck.ck-form {
|
|
14
|
+
padding: 0 0 var(--ck-spacing-large);
|
|
15
|
+
|
|
16
|
+
&.ck-form_default-width {
|
|
17
|
+
width: var(--ck-form-default-width);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&:focus {
|
|
21
|
+
outline: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
& .ck.ck-input-text,
|
|
25
|
+
& .ck.ck-input-number {
|
|
26
|
+
min-width: 100%;
|
|
27
|
+
width: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
& .ck.ck-dropdown {
|
|
31
|
+
min-width: 100%;
|
|
32
|
+
|
|
33
|
+
& .ck-dropdown__button {
|
|
34
|
+
&:not(:focus) {
|
|
35
|
+
border: 1px solid var(--ck-color-base-border);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
& .ck-button__label {
|
|
39
|
+
width: 100%;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Default `ck-responsive-form` customization when it lies next to `ck-form` class */
|
|
45
|
+
&.ck-responsive-form {
|
|
46
|
+
& .ck.ck-form__row {
|
|
47
|
+
&.ck-form__row_with-submit {
|
|
48
|
+
@mixin ck-media-phone {
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
align-items: stretch;
|
|
51
|
+
padding: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
> .ck {
|
|
55
|
+
@mixin ck-media-phone {
|
|
56
|
+
margin: var(--ck-spacing-large) var(--ck-spacing-large) 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.ck-button_with-text {
|
|
61
|
+
@mixin ck-media-phone {
|
|
62
|
+
justify-content: center;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&.ck-form__row_large-bottom-padding {
|
|
68
|
+
@mixin ck-media-phone {
|
|
69
|
+
padding-bottom: var(--ck-spacing-large);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@mixin ck-dir ltr {
|
|
75
|
+
& > :not(:first-child) {
|
|
76
|
+
margin-left: 0;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@mixin ck-dir rtl {
|
|
81
|
+
& > :not(:last-child) {
|
|
82
|
+
margin-left: 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/* End of `ck-responsive-form` customization */
|
|
87
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
.ck.ck-form__row {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: row;
|
|
9
|
+
justify-content: space-between;
|
|
10
|
+
align-items: flex-start;
|
|
11
|
+
padding: var(--ck-spacing-standard) var(--ck-spacing-large) 0;
|
|
12
|
+
|
|
13
|
+
&.ck-form__row_large-top-padding {
|
|
14
|
+
padding-top: var(--ck-spacing-large);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&.ck-form__row_large-bottom-padding {
|
|
18
|
+
padding-bottom: var(--ck-spacing-large);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&.ck-form__row_with-submit {
|
|
22
|
+
flex-wrap: nowrap;
|
|
23
|
+
|
|
24
|
+
& > *:not(:first-child) {
|
|
25
|
+
margin-inline-start: var(--ck-spacing-standard);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
& > .ck.ck-form__row {
|
|
30
|
+
padding: 0;
|
|
31
|
+
}
|
|
32
|
+
}
|