ckeditor5-elements-menu 0.0.0-stage → 49.0.0
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 +21 -0
- package/README.md +50 -2
- package/dist/augmentation.d.ts +30 -0
- package/dist/augmentation.d.ts.map +1 -0
- package/dist/augmentation.js +2 -0
- package/dist/augmentation.js.map +1 -0
- package/dist/breadcrumbs/breadcrumbItemView.d.ts +47 -0
- package/dist/breadcrumbs/breadcrumbItemView.d.ts.map +1 -0
- package/dist/breadcrumbs/breadcrumbItemView.js +30 -0
- package/dist/breadcrumbs/breadcrumbItemView.js.map +1 -0
- package/dist/breadcrumbs/breadcrumbLabelView.d.ts +29 -0
- package/dist/breadcrumbs/breadcrumbLabelView.d.ts.map +1 -0
- package/dist/breadcrumbs/breadcrumbLabelView.js +39 -0
- package/dist/breadcrumbs/breadcrumbLabelView.js.map +1 -0
- package/dist/breadcrumbs/breadcrumbsView.d.ts +68 -0
- package/dist/breadcrumbs/breadcrumbsView.d.ts.map +1 -0
- package/dist/breadcrumbs/breadcrumbsView.js +134 -0
- package/dist/breadcrumbs/breadcrumbsView.js.map +1 -0
- package/dist/breadcrumbs/elementBreadcrumbs.d.ts +73 -0
- package/dist/breadcrumbs/elementBreadcrumbs.d.ts.map +1 -0
- package/dist/breadcrumbs/elementBreadcrumbs.js +225 -0
- package/dist/breadcrumbs/elementBreadcrumbs.js.map +1 -0
- package/dist/contextMenu/contextMenuObserver.d.ts +19 -0
- package/dist/contextMenu/contextMenuObserver.d.ts.map +1 -0
- package/dist/contextMenu/contextMenuObserver.js +18 -0
- package/dist/contextMenu/contextMenuObserver.js.map +1 -0
- package/dist/contextMenu/elementContextMenu.d.ts +34 -0
- package/dist/contextMenu/elementContextMenu.d.ts.map +1 -0
- package/dist/contextMenu/elementContextMenu.js +88 -0
- package/dist/contextMenu/elementContextMenu.js.map +1 -0
- package/dist/domTarget.d.ts +8 -0
- package/dist/domTarget.d.ts.map +1 -0
- package/dist/domTarget.js +20 -0
- package/dist/domTarget.js.map +1 -0
- package/dist/elementMenu.d.ts +93 -0
- package/dist/elementMenu.d.ts.map +1 -0
- package/dist/elementMenu.js +140 -0
- package/dist/elementMenu.js.map +1 -0
- package/dist/elementMenuView.d.ts +40 -0
- package/dist/elementMenuView.d.ts.map +1 -0
- package/dist/elementMenuView.js +143 -0
- package/dist/elementMenuView.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/quickInsert/elementQuickInsert.d.ts +57 -0
- package/dist/quickInsert/elementQuickInsert.d.ts.map +1 -0
- package/dist/quickInsert/elementQuickInsert.js +96 -0
- package/dist/quickInsert/elementQuickInsert.js.map +1 -0
- package/dist/quickInsert/icons.d.ts +16 -0
- package/dist/quickInsert/icons.d.ts.map +1 -0
- package/dist/quickInsert/icons.js +21 -0
- package/dist/quickInsert/icons.js.map +1 -0
- package/dist/quickInsert/quickInsertCommand.d.ts +47 -0
- package/dist/quickInsert/quickInsertCommand.d.ts.map +1 -0
- package/dist/quickInsert/quickInsertCommand.js +81 -0
- package/dist/quickInsert/quickInsertCommand.js.map +1 -0
- package/dist/quickInsert/quickInsertListView.d.ts +29 -0
- package/dist/quickInsert/quickInsertListView.d.ts.map +1 -0
- package/dist/quickInsert/quickInsertListView.js +44 -0
- package/dist/quickInsert/quickInsertListView.js.map +1 -0
- package/dist/quickInsert/quickInsertPositionCommand.d.ts +33 -0
- package/dist/quickInsert/quickInsertPositionCommand.d.ts.map +1 -0
- package/dist/quickInsert/quickInsertPositionCommand.js +52 -0
- package/dist/quickInsert/quickInsertPositionCommand.js.map +1 -0
- package/dist/quickInsert/quickInsertView.d.ts +20 -0
- package/dist/quickInsert/quickInsertView.d.ts.map +1 -0
- package/dist/quickInsert/quickInsertView.js +52 -0
- package/dist/quickInsert/quickInsertView.js.map +1 -0
- package/package.json +52 -3
- package/src/augmentation.ts +44 -0
- package/src/breadcrumbs/breadcrumbItemView.ts +74 -0
- package/src/breadcrumbs/breadcrumbLabelView.ts +55 -0
- package/src/breadcrumbs/breadcrumbsView.ts +176 -0
- package/src/breadcrumbs/elementBreadcrumbs.ts +323 -0
- package/src/contextMenu/contextMenuObserver.ts +27 -0
- package/src/contextMenu/elementContextMenu.ts +104 -0
- package/src/domTarget.ts +27 -0
- package/src/elementMenu.ts +249 -0
- package/src/elementMenuView.ts +202 -0
- package/src/index.ts +54 -0
- package/src/quickInsert/elementQuickInsert.ts +135 -0
- package/src/quickInsert/icons.ts +26 -0
- package/src/quickInsert/quickInsertCommand.ts +96 -0
- package/src/quickInsert/quickInsertListView.ts +71 -0
- package/src/quickInsert/quickInsertPositionCommand.ts +68 -0
- package/src/quickInsert/quickInsertView.ts +64 -0
- package/theme/menu.css +131 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { type Editor, type ModelPosition } from 'ckeditor5';
|
|
2
|
+
import { ElementOrPositionCommand, selectNewElement, type ElementOrPosition } from 'ckeditor5-elements-core';
|
|
3
|
+
import { insertIcon } from './icons.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Inserts an element by its model name at a position: what the quick insert menu does, when an element is chosen. The
|
|
7
|
+
* menu itself is opened by the `ElementQuickInsert` plugin, with its `open()`.
|
|
8
|
+
*
|
|
9
|
+
* The target comes first, as in every {@link ElementOrPositionCommand}: a position, an element (meaning the position
|
|
10
|
+
* before it), or none (the selection).
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* editor.execute('quickInsert', position, 'heading1'); // Inserts a heading at the position.
|
|
14
|
+
* editor.execute('quickInsert', undefined, 'softBreak'); // Inserts a line break at the selection.
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Only elements that the schema allows at exactly that position are inserted (see {@link getAllowedElements}):
|
|
18
|
+
* nothing is split to make room, so e.g. a heading cannot be inserted inside a paragraph.
|
|
19
|
+
*
|
|
20
|
+
* After inserting, objects are selected; other elements get the selection inside them, in a new paragraph when they
|
|
21
|
+
* can hold blocks.
|
|
22
|
+
*/
|
|
23
|
+
export default class QuickInsertCommand extends ElementOrPositionCommand {
|
|
24
|
+
constructor(editor: Editor) {
|
|
25
|
+
super(editor);
|
|
26
|
+
|
|
27
|
+
this.title = editor.t('Insert element');
|
|
28
|
+
this.icon = insertIcon;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns the names of the model elements allowed at exactly the position (or the selection), in the order they
|
|
33
|
+
* were registered. Generic items (such as `$text` or `$block`) and the excluded names are skipped.
|
|
34
|
+
*/
|
|
35
|
+
public getAllowedElements(elementOrPosition?: ElementOrPosition, exclude: readonly string[] = []): string[] {
|
|
36
|
+
return Array.from(this._getAllowedElements(elementOrPosition, exclude));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Whether an element is allowed at exactly the position (or the selection), as {@link getAllowedElements} returns
|
|
41
|
+
* them: it stops at the first one.
|
|
42
|
+
*/
|
|
43
|
+
public hasAllowedElements(elementOrPosition?: ElementOrPosition, exclude: readonly string[] = []): boolean {
|
|
44
|
+
return !this._getAllowedElements(elementOrPosition, exclude).next().done;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Returns the position where elements are inserted for the target: the position, the position before the element,
|
|
49
|
+
* or the selection.
|
|
50
|
+
*/
|
|
51
|
+
public getInsertPosition(elementOrPosition?: ElementOrPosition): ModelPosition | null {
|
|
52
|
+
return this._getPosition(elementOrPosition);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Inserts the element named `name` at the target, when the schema allows it there.
|
|
57
|
+
*/
|
|
58
|
+
public override execute(elementOrPosition: ElementOrPosition | undefined, name: string): void {
|
|
59
|
+
const model = this.editor.model;
|
|
60
|
+
const target = this._getPosition(elementOrPosition);
|
|
61
|
+
|
|
62
|
+
if (!target || !model.canEditAt(target) || !model.schema.checkChild(target, name)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
model.change(writer => {
|
|
67
|
+
const element = writer.createElement(name);
|
|
68
|
+
|
|
69
|
+
writer.insert(element, target);
|
|
70
|
+
selectNewElement(writer, element);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Yields the names of the elements allowed at exactly the position (or the selection), one by one.
|
|
76
|
+
*/
|
|
77
|
+
private *_getAllowedElements(
|
|
78
|
+
elementOrPosition: ElementOrPosition | undefined,
|
|
79
|
+
exclude: readonly string[]
|
|
80
|
+
): Generator<string> {
|
|
81
|
+
const target = this._getPosition(elementOrPosition);
|
|
82
|
+
|
|
83
|
+
if (!target) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const schema = this.editor.model.schema;
|
|
88
|
+
const excluded = new Set(exclude);
|
|
89
|
+
|
|
90
|
+
for (const name of Object.keys(schema.getDefinitions())) {
|
|
91
|
+
if (!name.startsWith('$') && !excluded.has(name) && schema.checkChild(target, name)) {
|
|
92
|
+
yield name;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ButtonView,
|
|
3
|
+
ListItemView,
|
|
4
|
+
ListView,
|
|
5
|
+
type FilteredView,
|
|
6
|
+
type FilteredViewExecuteEvent,
|
|
7
|
+
type Locale
|
|
8
|
+
} from 'ckeditor5';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* An element that can be inserted: its model name and the label shown in the list.
|
|
12
|
+
*/
|
|
13
|
+
export interface QuickInsertItem {
|
|
14
|
+
name: string;
|
|
15
|
+
label: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A list of insertable elements that can be filtered by a search query.
|
|
20
|
+
*
|
|
21
|
+
* Fires `execute` with `{ value: name }` when an item is chosen.
|
|
22
|
+
*/
|
|
23
|
+
export default class QuickInsertListView extends ListView implements FilteredView {
|
|
24
|
+
private readonly _entries: { item: QuickInsertItem; view: ListItemView; button: ButtonView }[];
|
|
25
|
+
|
|
26
|
+
constructor(locale: Locale, items: readonly QuickInsertItem[]) {
|
|
27
|
+
super(locale);
|
|
28
|
+
|
|
29
|
+
this.role = 'listbox';
|
|
30
|
+
|
|
31
|
+
this._entries = items.map(item => {
|
|
32
|
+
const view = new ListItemView(locale);
|
|
33
|
+
const button = new ButtonView(locale);
|
|
34
|
+
|
|
35
|
+
button.set({ label: item.label, withText: true, role: 'option' });
|
|
36
|
+
button.on('execute', () => {
|
|
37
|
+
this.fire<FilteredViewExecuteEvent>('execute', { value: item.name });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
view.children.add(button);
|
|
41
|
+
|
|
42
|
+
return { item, view, button };
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.items.addMany(this._entries.map(entry => entry.view));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Shows only the items whose label or name matches the expression. `null` shows all items.
|
|
50
|
+
*/
|
|
51
|
+
public filter(regExp: RegExp | null): { resultsCount: number; totalItemsCount: number } {
|
|
52
|
+
let resultsCount = 0;
|
|
53
|
+
|
|
54
|
+
for (const { item, view } of this._entries) {
|
|
55
|
+
view.isVisible = !regExp || regExp.test(item.label) || regExp.test(item.name);
|
|
56
|
+
|
|
57
|
+
if (view.isVisible) {
|
|
58
|
+
resultsCount++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { resultsCount, totalItemsCount: this._entries.length };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Returns the first item that is not filtered out.
|
|
67
|
+
*/
|
|
68
|
+
public getFirstVisibleItem(): QuickInsertItem | null {
|
|
69
|
+
return this._entries.find(entry => entry.view.isVisible)?.item ?? null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type Editor, type ModelPosition } from 'ckeditor5';
|
|
2
|
+
import { ElementOrPositionCommand, type ElementOrPosition } from 'ckeditor5-elements-core';
|
|
3
|
+
import { getDomTarget } from '../domTarget.js';
|
|
4
|
+
import type ElementQuickInsert from './elementQuickInsert.js';
|
|
5
|
+
import { insertAfterIcon, insertBeforeIcon } from './icons.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Where the quick insert menu inserts, relative to the element.
|
|
9
|
+
*/
|
|
10
|
+
export type QuickInsertPlacement = 'before' | 'after';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Opens the quick insert menu for the position before or after an element, next to that element.
|
|
14
|
+
*
|
|
15
|
+
* The element is the given one, the parent of the given position, or the selected element or the parent of the
|
|
16
|
+
* selection (see {@link ElementOrPositionCommand}). Enabled when something can be inserted at that position.
|
|
17
|
+
*
|
|
18
|
+
* The `ElementQuickInsert` plugin registers it as `quickInsertBefore` and `quickInsertAfter`, for its menu.
|
|
19
|
+
*/
|
|
20
|
+
export default class QuickInsertPositionCommand extends ElementOrPositionCommand {
|
|
21
|
+
/**
|
|
22
|
+
* Where the quick insert menu inserts, relative to the element.
|
|
23
|
+
*/
|
|
24
|
+
public readonly placement: QuickInsertPlacement;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The plugin whose menu the command opens.
|
|
28
|
+
*/
|
|
29
|
+
private readonly _quickInsert: ElementQuickInsert;
|
|
30
|
+
|
|
31
|
+
constructor(editor: Editor, placement: QuickInsertPlacement, quickInsert: ElementQuickInsert) {
|
|
32
|
+
super(editor);
|
|
33
|
+
|
|
34
|
+
this.placement = placement;
|
|
35
|
+
this._quickInsert = quickInsert;
|
|
36
|
+
this.title = placement === 'before' ? editor.t('Insert before') : editor.t('Insert after');
|
|
37
|
+
this.icon = placement === 'before' ? insertBeforeIcon : insertAfterIcon;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Opens the quick insert menu for the position before or after the element, next to the element.
|
|
42
|
+
*/
|
|
43
|
+
public override execute(elementOrPosition?: ElementOrPosition): void {
|
|
44
|
+
const element = this._getElement(elementOrPosition);
|
|
45
|
+
const position = this._getInsertPosition(elementOrPosition);
|
|
46
|
+
|
|
47
|
+
if (element && position) {
|
|
48
|
+
this._quickInsert.open(position, getDomTarget(this.editor, element) ?? undefined);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected override _isEnabledFor(elementOrPosition?: ElementOrPosition): boolean {
|
|
53
|
+
const position = this._getInsertPosition(elementOrPosition);
|
|
54
|
+
|
|
55
|
+
return !!position && this.editor.model.canEditAt(position) && this._quickInsert.hasItems(position);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private _getInsertPosition(elementOrPosition?: ElementOrPosition): ModelPosition | null {
|
|
59
|
+
const element = this._getElement(elementOrPosition);
|
|
60
|
+
const model = this.editor.model;
|
|
61
|
+
|
|
62
|
+
if (!element) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return this.placement === 'before' ? model.createPositionBefore(element) : model.createPositionAfter(element);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { SearchTextView, type FilteredViewExecuteEvent, type Locale } from 'ckeditor5';
|
|
2
|
+
import QuickInsertListView, { type QuickInsertItem } from './quickInsertListView.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A search field with a filtered list of insertable elements.
|
|
6
|
+
*
|
|
7
|
+
* In the search field, Enter chooses the first matching item and the down arrow moves the focus to the list.
|
|
8
|
+
* Fires `execute` with `{ value: name }` when an item is chosen.
|
|
9
|
+
*/
|
|
10
|
+
export default class QuickInsertView extends SearchTextView {
|
|
11
|
+
/**
|
|
12
|
+
* The list of elements.
|
|
13
|
+
*/
|
|
14
|
+
public readonly listView: QuickInsertListView;
|
|
15
|
+
|
|
16
|
+
constructor(locale: Locale, items: readonly QuickInsertItem[]) {
|
|
17
|
+
const listView = new QuickInsertListView(locale, items);
|
|
18
|
+
const t = locale.t;
|
|
19
|
+
|
|
20
|
+
super(locale, {
|
|
21
|
+
queryView: { label: t('Insert element') },
|
|
22
|
+
filteredView: listView,
|
|
23
|
+
infoView: {
|
|
24
|
+
text: {
|
|
25
|
+
notFound: { primary: t('No matching elements') },
|
|
26
|
+
noSearchableItems: { primary: t('No elements can be inserted here') }
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
class: 'ck-elements-quick-insert'
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
this.listView = listView;
|
|
33
|
+
listView.delegate('execute').to(this);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Renders the view and sets up Enter (choose the first match) and the down arrow (go to the list) in the search field.
|
|
38
|
+
*/
|
|
39
|
+
public override render(): void {
|
|
40
|
+
super.render();
|
|
41
|
+
|
|
42
|
+
const isInQueryField = (): boolean => this.focusTracker.focusedElement === this.queryView.element;
|
|
43
|
+
|
|
44
|
+
this.keystrokes.set('enter', (data, cancel) => {
|
|
45
|
+
const item = isInQueryField() ? this.listView.getFirstVisibleItem() : null;
|
|
46
|
+
|
|
47
|
+
if (item) {
|
|
48
|
+
this.fire<FilteredViewExecuteEvent>('execute', { value: item.name });
|
|
49
|
+
cancel();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
this.keystrokes.set(
|
|
54
|
+
'arrowdown',
|
|
55
|
+
(data, cancel) => {
|
|
56
|
+
if (isInQueryField()) {
|
|
57
|
+
this.listView.focusFirst();
|
|
58
|
+
cancel();
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{ priority: 'high' }
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
package/theme/menu.css
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The menu of an element is CKEditor's dropdown menu, so CKEditor styles it. Only the alignment of labels is added.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/* In a menu with icons (or a nested menu of it), items without an icon get the space of one, so that all labels line up. */
|
|
6
|
+
:is(.ck.ck-elements-menu, .ck.ck-elements-menu__panel > .ck-dropdown-menu-list):has(
|
|
7
|
+
> .ck-list__item > :is(.ck-button, .ck-dropdown-menu-list__nested-menu > .ck-button) > .ck-button__icon
|
|
8
|
+
)
|
|
9
|
+
> .ck-list__item
|
|
10
|
+
> :is(.ck-button, .ck-dropdown-menu-list__nested-menu > .ck-button):not(:has(> .ck-button__icon))
|
|
11
|
+
> .ck-button__label {
|
|
12
|
+
/* The width of an icon, and the gap after it. */
|
|
13
|
+
margin-inline-start: calc(var(--ck-icon-size) + var(--ck-button-icon-gap));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
* The element path: ancestors are muted, the innermost element (where the cursor is) is emphasised. Items are separated
|
|
18
|
+
* by chevrons. Buttons (with a menu) and labels (without one) look the same, except buttons react to hover and focus.
|
|
19
|
+
*/
|
|
20
|
+
.ck.ck-elements-breadcrumbs {
|
|
21
|
+
--ck-elements-breadcrumbs-item-height: 24px;
|
|
22
|
+
--ck-elements-breadcrumbs-separator-size: 0.38em;
|
|
23
|
+
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
min-width: 0;
|
|
27
|
+
font-size: var(--ck-font-size-sm);
|
|
28
|
+
color: var(--ck-color-text);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ck.ck-toolbar .ck.ck-elements-breadcrumbs {
|
|
32
|
+
min-height: var(--ck-size-control-min-height);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.ck.ck-elements-breadcrumbs__list {
|
|
36
|
+
display: flex;
|
|
37
|
+
flex-wrap: wrap;
|
|
38
|
+
align-items: center;
|
|
39
|
+
gap: 2px 0;
|
|
40
|
+
min-width: 0;
|
|
41
|
+
margin: 0;
|
|
42
|
+
padding: 0;
|
|
43
|
+
list-style: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.ck.ck-elements-breadcrumbs__list-item {
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
min-width: 0;
|
|
50
|
+
margin: 0;
|
|
51
|
+
padding: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Both item kinds: buttons and labels. */
|
|
55
|
+
.ck.ck-elements-breadcrumbs__item,
|
|
56
|
+
.ck.ck-button.ck-elements-breadcrumbs__item {
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
min-width: 0;
|
|
60
|
+
min-height: var(--ck-elements-breadcrumbs-item-height);
|
|
61
|
+
height: var(--ck-elements-breadcrumbs-item-height);
|
|
62
|
+
padding: 0 var(--ck-spacing-sm);
|
|
63
|
+
border-radius: var(--ck-border-radius-control);
|
|
64
|
+
font-family: var(--ck-font-family);
|
|
65
|
+
font-size: inherit;
|
|
66
|
+
line-height: 1;
|
|
67
|
+
white-space: nowrap;
|
|
68
|
+
color: color-mix(in srgb, var(--ck-color-text) 65%, transparent);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.ck.ck-button.ck-elements-breadcrumbs__item .ck-button__label {
|
|
72
|
+
font-size: inherit;
|
|
73
|
+
line-height: 1;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* The innermost element: where the cursor is. */
|
|
77
|
+
.ck.ck-elements-breadcrumbs__item[aria-current] {
|
|
78
|
+
color: var(--ck-color-text);
|
|
79
|
+
font-weight: 600;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Labels cannot be clicked, but can be focused with the keyboard. */
|
|
83
|
+
.ck.ck-elements-breadcrumbs__label {
|
|
84
|
+
cursor: default;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.ck.ck-elements-breadcrumbs__label:focus {
|
|
88
|
+
outline: none;
|
|
89
|
+
box-shadow:
|
|
90
|
+
0 0 0 1px var(--ck-color-focus-border),
|
|
91
|
+
var(--ck-focus-shadow);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* Buttons show they can be clicked. */
|
|
95
|
+
.ck.ck-button.ck-elements-breadcrumbs__item:hover,
|
|
96
|
+
.ck.ck-button.ck-elements-breadcrumbs__item:focus,
|
|
97
|
+
.ck.ck-button.ck-elements-breadcrumbs__item.ck-on {
|
|
98
|
+
color: var(--ck-color-text);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* A chevron between items, in the gap before each item, so it is not part of a button's hover area. */
|
|
102
|
+
.ck.ck-elements-breadcrumbs__list-item + .ck.ck-elements-breadcrumbs__list-item {
|
|
103
|
+
position: relative;
|
|
104
|
+
margin-left: calc(var(--ck-spacing-base) + var(--ck-elements-breadcrumbs-separator-size));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.ck.ck-elements-breadcrumbs__list-item + .ck.ck-elements-breadcrumbs__list-item::before {
|
|
108
|
+
content: '';
|
|
109
|
+
position: absolute;
|
|
110
|
+
top: 50%;
|
|
111
|
+
left: calc(-0.5 * var(--ck-spacing-base) - var(--ck-elements-breadcrumbs-separator-size));
|
|
112
|
+
width: var(--ck-elements-breadcrumbs-separator-size);
|
|
113
|
+
height: var(--ck-elements-breadcrumbs-separator-size);
|
|
114
|
+
border-top: 1.5px solid color-mix(in srgb, var(--ck-color-text) 40%, transparent);
|
|
115
|
+
border-right: 1.5px solid color-mix(in srgb, var(--ck-color-text) 40%, transparent);
|
|
116
|
+
transform: translateY(-50%) rotate(45deg);
|
|
117
|
+
pointer-events: none;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.ck.ck-elements-quick-insert {
|
|
121
|
+
width: 260px;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.ck.ck-elements-quick-insert .ck-search__results {
|
|
125
|
+
max-height: 240px;
|
|
126
|
+
overflow-y: auto;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.ck.ck-elements-quick-insert .ck-list__item > .ck.ck-button {
|
|
130
|
+
width: 100%;
|
|
131
|
+
}
|