@ckeditor/ckeditor5-ui 39.0.2 → 40.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/lang/contexts.json +5 -1
- package/lang/translations/ar.po +16 -0
- package/lang/translations/ast.po +16 -0
- package/lang/translations/az.po +16 -0
- package/lang/translations/bg.po +16 -0
- package/lang/translations/bn.po +16 -0
- package/lang/translations/ca.po +16 -0
- package/lang/translations/cs.po +16 -0
- package/lang/translations/da.po +16 -0
- package/lang/translations/de-ch.po +16 -0
- package/lang/translations/de.po +16 -0
- package/lang/translations/el.po +16 -0
- package/lang/translations/en-au.po +16 -0
- package/lang/translations/en-gb.po +16 -0
- package/lang/translations/en.po +16 -0
- package/lang/translations/eo.po +16 -0
- package/lang/translations/es.po +16 -0
- package/lang/translations/et.po +16 -0
- package/lang/translations/eu.po +16 -0
- package/lang/translations/fa.po +16 -0
- package/lang/translations/fi.po +16 -0
- package/lang/translations/fr.po +16 -0
- package/lang/translations/gl.po +16 -0
- package/lang/translations/he.po +16 -0
- package/lang/translations/hi.po +16 -0
- package/lang/translations/hr.po +16 -0
- package/lang/translations/hu.po +16 -0
- package/lang/translations/id.po +16 -0
- package/lang/translations/it.po +16 -0
- package/lang/translations/ja.po +16 -0
- package/lang/translations/km.po +16 -0
- package/lang/translations/kn.po +16 -0
- package/lang/translations/ko.po +16 -0
- package/lang/translations/ku.po +16 -0
- package/lang/translations/lt.po +16 -0
- package/lang/translations/lv.po +16 -0
- package/lang/translations/ms.po +16 -0
- package/lang/translations/nb.po +16 -0
- package/lang/translations/ne.po +16 -0
- package/lang/translations/nl.po +16 -0
- package/lang/translations/no.po +16 -0
- package/lang/translations/pl.po +16 -0
- package/lang/translations/pt-br.po +16 -0
- package/lang/translations/pt.po +16 -0
- package/lang/translations/ro.po +16 -0
- package/lang/translations/ru.po +16 -0
- package/lang/translations/sk.po +16 -0
- package/lang/translations/sl.po +16 -0
- package/lang/translations/sq.po +16 -0
- package/lang/translations/sr-latn.po +16 -0
- package/lang/translations/sr.po +16 -0
- package/lang/translations/sv.po +16 -0
- package/lang/translations/th.po +16 -0
- package/lang/translations/tk.po +16 -0
- package/lang/translations/tr.po +16 -0
- package/lang/translations/tt.po +16 -0
- package/lang/translations/ug.po +16 -0
- package/lang/translations/uk.po +16 -0
- package/lang/translations/ur.po +16 -0
- package/lang/translations/uz.po +16 -0
- package/lang/translations/vi.po +16 -0
- package/lang/translations/zh-cn.po +16 -0
- package/lang/translations/zh.po +16 -0
- package/package.json +3 -3
- package/src/augmentation.d.ts +86 -86
- package/src/augmentation.js +5 -5
- package/src/autocomplete/autocompleteview.d.ts +81 -0
- package/src/autocomplete/autocompleteview.js +146 -0
- package/src/bindings/addkeyboardhandlingforgrid.d.ts +27 -27
- package/src/bindings/addkeyboardhandlingforgrid.js +107 -107
- package/src/bindings/clickoutsidehandler.d.ts +28 -28
- package/src/bindings/clickoutsidehandler.js +36 -36
- package/src/bindings/csstransitiondisablermixin.d.ts +40 -40
- package/src/bindings/csstransitiondisablermixin.js +55 -55
- package/src/bindings/injectcsstransitiondisabler.d.ts +59 -59
- package/src/bindings/injectcsstransitiondisabler.js +71 -71
- package/src/bindings/preventdefault.d.ts +33 -33
- package/src/bindings/preventdefault.js +34 -34
- package/src/bindings/submithandler.d.ts +57 -57
- package/src/bindings/submithandler.js +47 -47
- package/src/button/button.d.ts +178 -178
- package/src/button/button.js +5 -5
- package/src/button/buttonlabel.d.ts +34 -0
- package/src/button/buttonlabel.js +5 -0
- package/src/button/buttonlabelview.d.ts +31 -0
- package/src/button/buttonlabelview.js +42 -0
- package/src/button/buttonview.d.ts +185 -177
- package/src/button/buttonview.js +219 -231
- package/src/button/switchbuttonview.d.ts +45 -45
- package/src/button/switchbuttonview.js +75 -75
- package/src/colorgrid/colorgridview.d.ts +132 -132
- package/src/colorgrid/colorgridview.js +124 -124
- package/src/colorgrid/colortileview.d.ts +28 -28
- package/src/colorgrid/colortileview.js +40 -40
- package/src/colorgrid/utils.d.ts +47 -47
- package/src/colorgrid/utils.js +84 -84
- package/src/colorpicker/colorpickerview.d.ts +137 -137
- package/src/colorpicker/colorpickerview.js +270 -270
- package/src/colorpicker/utils.d.ts +43 -43
- package/src/colorpicker/utils.js +99 -99
- package/src/colorselector/colorgridsfragmentview.d.ts +194 -194
- package/src/colorselector/colorgridsfragmentview.js +289 -289
- package/src/colorselector/colorpickerfragmentview.d.ts +128 -128
- package/src/colorselector/colorpickerfragmentview.js +205 -205
- package/src/colorselector/colorselectorview.d.ts +242 -242
- package/src/colorselector/colorselectorview.js +256 -256
- package/src/colorselector/documentcolorcollection.d.ts +70 -70
- package/src/colorselector/documentcolorcollection.js +42 -42
- package/src/componentfactory.d.ts +81 -81
- package/src/componentfactory.js +104 -104
- package/src/dropdown/button/dropdownbutton.d.ts +25 -25
- package/src/dropdown/button/dropdownbutton.js +5 -5
- package/src/dropdown/button/dropdownbuttonview.d.ts +48 -48
- package/src/dropdown/button/dropdownbuttonview.js +66 -66
- package/src/dropdown/button/splitbuttonview.d.ts +161 -161
- package/src/dropdown/button/splitbuttonview.js +152 -152
- package/src/dropdown/dropdownpanelfocusable.d.ts +21 -21
- package/src/dropdown/dropdownpanelfocusable.js +5 -5
- package/src/dropdown/dropdownpanelview.d.ts +62 -62
- package/src/dropdown/dropdownpanelview.js +97 -97
- package/src/dropdown/dropdownview.d.ts +315 -315
- package/src/dropdown/dropdownview.js +379 -378
- package/src/dropdown/utils.d.ts +235 -221
- package/src/dropdown/utils.js +458 -437
- package/src/editableui/editableuiview.d.ts +72 -72
- package/src/editableui/editableuiview.js +112 -112
- package/src/editableui/inline/inlineeditableuiview.d.ts +40 -40
- package/src/editableui/inline/inlineeditableuiview.js +48 -48
- package/src/editorui/bodycollection.d.ts +55 -55
- package/src/editorui/bodycollection.js +84 -84
- package/src/editorui/boxed/boxededitoruiview.d.ts +40 -40
- package/src/editorui/boxed/boxededitoruiview.js +81 -81
- package/src/editorui/editorui.d.ts +282 -282
- package/src/editorui/editorui.js +410 -410
- package/src/editorui/editoruiview.d.ts +39 -39
- package/src/editorui/editoruiview.js +38 -38
- package/src/editorui/poweredby.d.ts +71 -71
- package/src/editorui/poweredby.js +276 -299
- package/src/focuscycler.d.ts +226 -183
- package/src/focuscycler.js +245 -220
- package/src/formheader/formheaderview.d.ts +59 -53
- package/src/formheader/formheaderview.js +69 -63
- package/src/highlightedtext/highlightedtextview.d.ts +38 -0
- package/src/highlightedtext/highlightedtextview.js +102 -0
- package/src/icon/iconview.d.ts +85 -78
- package/src/icon/iconview.js +114 -112
- package/src/iframe/iframeview.d.ts +50 -50
- package/src/iframe/iframeview.js +63 -63
- package/src/index.d.ts +73 -63
- package/src/index.js +70 -62
- package/src/input/inputbase.d.ts +107 -0
- package/src/input/inputbase.js +110 -0
- package/src/input/inputview.d.ts +36 -121
- package/src/input/inputview.js +24 -106
- package/src/inputnumber/inputnumberview.d.ts +49 -49
- package/src/inputnumber/inputnumberview.js +40 -40
- package/src/inputtext/inputtextview.d.ts +18 -18
- package/src/inputtext/inputtextview.js +27 -27
- package/src/label/labelview.d.ts +36 -36
- package/src/label/labelview.js +41 -41
- package/src/labeledfield/labeledfieldview.d.ts +187 -182
- package/src/labeledfield/labeledfieldview.js +157 -157
- package/src/labeledfield/utils.d.ts +123 -93
- package/src/labeledfield/utils.js +176 -131
- package/src/labeledinput/labeledinputview.d.ts +125 -125
- package/src/labeledinput/labeledinputview.js +125 -125
- package/src/list/listitemgroupview.d.ts +51 -0
- package/src/list/listitemgroupview.js +75 -0
- package/src/list/listitemview.d.ts +36 -35
- package/src/list/listitemview.js +42 -40
- package/src/list/listseparatorview.d.ts +18 -18
- package/src/list/listseparatorview.js +28 -28
- package/src/list/listview.d.ts +122 -65
- package/src/list/listview.js +187 -90
- package/src/model.d.ts +22 -22
- package/src/model.js +31 -31
- package/src/notification/notification.d.ts +211 -211
- package/src/notification/notification.js +187 -187
- package/src/panel/balloon/balloonpanelview.d.ts +685 -685
- package/src/panel/balloon/balloonpanelview.js +1010 -988
- package/src/panel/balloon/contextualballoon.d.ts +299 -299
- package/src/panel/balloon/contextualballoon.js +572 -572
- package/src/panel/sticky/stickypanelview.d.ts +156 -158
- package/src/panel/sticky/stickypanelview.js +234 -231
- package/src/search/filteredview.d.ts +31 -0
- package/src/search/filteredview.js +5 -0
- package/src/search/searchinfoview.d.ts +45 -0
- package/src/search/searchinfoview.js +59 -0
- package/src/search/searchresultsview.d.ts +54 -0
- package/src/search/searchresultsview.js +65 -0
- package/src/search/text/searchtextqueryview.d.ts +76 -0
- package/src/search/text/searchtextqueryview.js +75 -0
- package/src/search/text/searchtextview.d.ts +219 -0
- package/src/search/text/searchtextview.js +201 -0
- package/src/spinner/spinnerview.d.ts +25 -0
- package/src/spinner/spinnerview.js +38 -0
- package/src/template.d.ts +942 -942
- package/src/template.js +1294 -1294
- package/src/textarea/textareaview.d.ts +88 -0
- package/src/textarea/textareaview.js +140 -0
- package/src/toolbar/balloon/balloontoolbar.d.ts +122 -122
- package/src/toolbar/balloon/balloontoolbar.js +300 -300
- package/src/toolbar/block/blockbuttonview.d.ts +35 -35
- package/src/toolbar/block/blockbuttonview.js +41 -41
- package/src/toolbar/block/blocktoolbar.d.ts +161 -161
- package/src/toolbar/block/blocktoolbar.js +395 -391
- package/src/toolbar/normalizetoolbarconfig.d.ts +40 -39
- package/src/toolbar/normalizetoolbarconfig.js +51 -51
- package/src/toolbar/toolbarlinebreakview.d.ts +18 -18
- package/src/toolbar/toolbarlinebreakview.js +28 -28
- package/src/toolbar/toolbarseparatorview.d.ts +18 -18
- package/src/toolbar/toolbarseparatorview.js +28 -28
- package/src/toolbar/toolbarview.d.ts +266 -265
- package/src/toolbar/toolbarview.js +719 -717
- package/src/tooltipmanager.d.ts +180 -180
- package/src/tooltipmanager.js +353 -353
- package/src/view.d.ts +422 -422
- package/src/view.js +396 -396
- package/src/viewcollection.d.ts +139 -139
- package/src/viewcollection.js +206 -206
- package/theme/components/autocomplete/autocomplete.css +22 -0
- package/theme/components/formheader/formheader.css +8 -0
- package/theme/components/highlightedtext/highlightedtext.css +12 -0
- package/theme/components/search/search.css +43 -0
- package/theme/components/spinner/spinner.css +23 -0
- package/theme/components/textarea/textarea.css +10 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module ui/search/searchresultsview
|
|
7
|
+
*/
|
|
8
|
+
import View from '../view';
|
|
9
|
+
import type ViewCollection from '../viewcollection';
|
|
10
|
+
import { FocusTracker, type Locale } from '@ckeditor/ckeditor5-utils';
|
|
11
|
+
import { default as FocusCycler, type FocusableView } from '../focuscycler';
|
|
12
|
+
/**
|
|
13
|
+
* A sub-component of {@link module:ui/search/text/searchtextview~SearchTextView}. It hosts the filtered and the information views.
|
|
14
|
+
*/
|
|
15
|
+
export default class SearchResultsView extends View implements FocusableView {
|
|
16
|
+
/**
|
|
17
|
+
* Tracks information about the DOM focus in the view.
|
|
18
|
+
*
|
|
19
|
+
* @readonly
|
|
20
|
+
*/
|
|
21
|
+
focusTracker: FocusTracker;
|
|
22
|
+
/**
|
|
23
|
+
* The collection of the child views inside of the list item {@link #element}.
|
|
24
|
+
*
|
|
25
|
+
* @readonly
|
|
26
|
+
*/
|
|
27
|
+
children: ViewCollection;
|
|
28
|
+
/**
|
|
29
|
+
* Provides the focus management (keyboard navigation) in the view.
|
|
30
|
+
*
|
|
31
|
+
* @readonly
|
|
32
|
+
*/
|
|
33
|
+
protected _focusCycler: FocusCycler;
|
|
34
|
+
/**
|
|
35
|
+
* @inheritDoc
|
|
36
|
+
*/
|
|
37
|
+
constructor(locale: Locale);
|
|
38
|
+
/**
|
|
39
|
+
* @inheritDoc
|
|
40
|
+
*/
|
|
41
|
+
render(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Focuses the view.
|
|
44
|
+
*/
|
|
45
|
+
focus(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Focuses the first child view.
|
|
48
|
+
*/
|
|
49
|
+
focusFirst(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Focuses the last child view.
|
|
52
|
+
*/
|
|
53
|
+
focusLast(): void;
|
|
54
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module ui/search/searchresultsview
|
|
7
|
+
*/
|
|
8
|
+
import View from '../view';
|
|
9
|
+
import { FocusTracker } from '@ckeditor/ckeditor5-utils';
|
|
10
|
+
import { default as FocusCycler } from '../focuscycler';
|
|
11
|
+
/**
|
|
12
|
+
* A sub-component of {@link module:ui/search/text/searchtextview~SearchTextView}. It hosts the filtered and the information views.
|
|
13
|
+
*/
|
|
14
|
+
export default class SearchResultsView extends View {
|
|
15
|
+
/**
|
|
16
|
+
* @inheritDoc
|
|
17
|
+
*/
|
|
18
|
+
constructor(locale) {
|
|
19
|
+
super(locale);
|
|
20
|
+
this.children = this.createCollection();
|
|
21
|
+
this.focusTracker = new FocusTracker();
|
|
22
|
+
this.setTemplate({
|
|
23
|
+
tag: 'div',
|
|
24
|
+
attributes: {
|
|
25
|
+
class: [
|
|
26
|
+
'ck',
|
|
27
|
+
'ck-search__results'
|
|
28
|
+
],
|
|
29
|
+
tabindex: -1
|
|
30
|
+
},
|
|
31
|
+
children: this.children
|
|
32
|
+
});
|
|
33
|
+
this._focusCycler = new FocusCycler({
|
|
34
|
+
focusables: this.children,
|
|
35
|
+
focusTracker: this.focusTracker
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @inheritDoc
|
|
40
|
+
*/
|
|
41
|
+
render() {
|
|
42
|
+
super.render();
|
|
43
|
+
for (const child of this.children) {
|
|
44
|
+
this.focusTracker.add(child.element);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Focuses the view.
|
|
49
|
+
*/
|
|
50
|
+
focus() {
|
|
51
|
+
this._focusCycler.focusFirst();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Focuses the first child view.
|
|
55
|
+
*/
|
|
56
|
+
focusFirst() {
|
|
57
|
+
this._focusCycler.focusFirst();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Focuses the last child view.
|
|
61
|
+
*/
|
|
62
|
+
focusLast() {
|
|
63
|
+
this._focusCycler.focusLast();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module ui/search/text/searchtextqueryview
|
|
7
|
+
*/
|
|
8
|
+
import ButtonView from '../../button/buttonview';
|
|
9
|
+
import IconView from '../../icon/iconview';
|
|
10
|
+
import LabeledFieldView, { type LabeledFieldViewCreator } from '../../labeledfield/labeledfieldview';
|
|
11
|
+
import type InputBase from '../../input/inputbase';
|
|
12
|
+
import type { Locale } from '@ckeditor/ckeditor5-utils';
|
|
13
|
+
/**
|
|
14
|
+
* A search input field for the {@link module:ui/search/text/searchtextview~SearchTextView} component.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
* @extends module:ui/labeledfield/labeledfieldview~LabeledFieldView
|
|
18
|
+
*/
|
|
19
|
+
export default class SearchTextQueryView<TQueryFieldView extends InputBase<HTMLInputElement | HTMLTextAreaElement>> extends LabeledFieldView<TQueryFieldView> {
|
|
20
|
+
/**
|
|
21
|
+
* The loupe icon displayed next to the {@link #fieldView}.
|
|
22
|
+
*/
|
|
23
|
+
iconView?: IconView;
|
|
24
|
+
/**
|
|
25
|
+
* The button that clears and focuses the {@link #fieldView}.
|
|
26
|
+
*/
|
|
27
|
+
resetButtonView?: ButtonView;
|
|
28
|
+
/**
|
|
29
|
+
* A reference to the view configuration.
|
|
30
|
+
*/
|
|
31
|
+
private readonly _viewConfig;
|
|
32
|
+
/**
|
|
33
|
+
* @inheritDoc
|
|
34
|
+
*/
|
|
35
|
+
constructor(locale: Locale, config: SearchTextQueryViewConfig<TQueryFieldView>);
|
|
36
|
+
/**
|
|
37
|
+
* Resets the search field to its default state.
|
|
38
|
+
*/
|
|
39
|
+
reset(): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* An event fired when the field is reset using the
|
|
43
|
+
* {@link module:ui/search/text/searchtextqueryview~SearchTextQueryView#resetButtonView}.
|
|
44
|
+
*
|
|
45
|
+
* @eventName ~SearchTextQueryView#reset
|
|
46
|
+
*/
|
|
47
|
+
export type SearchTextQueryViewResetEvent = {
|
|
48
|
+
name: 'reset';
|
|
49
|
+
args: [];
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* The configuration of the {@link module:ui/search/text/searchtextqueryview~SearchTextQueryView} view.
|
|
53
|
+
*/
|
|
54
|
+
export interface SearchTextQueryViewConfig<TConfigSearchField extends InputBase<HTMLInputElement | HTMLTextAreaElement>> {
|
|
55
|
+
/**
|
|
56
|
+
* The human-readable label of the search field.
|
|
57
|
+
*/
|
|
58
|
+
label: string;
|
|
59
|
+
/**
|
|
60
|
+
* Determines whether the button that resets the search should be visible.
|
|
61
|
+
*
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
showResetButton?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Determines whether the loupe icon should be visible.
|
|
67
|
+
*
|
|
68
|
+
* @default true
|
|
69
|
+
*/
|
|
70
|
+
showIcon?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* The function that creates the search field input view. By default, a plain
|
|
73
|
+
* {@link module:ui/inputtext/inputtextview~InputTextView} is used for this purpose.
|
|
74
|
+
*/
|
|
75
|
+
creator?: LabeledFieldViewCreator<TConfigSearchField>;
|
|
76
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module ui/search/text/searchtextqueryview
|
|
7
|
+
*/
|
|
8
|
+
import ButtonView from '../../button/buttonview';
|
|
9
|
+
import IconView from '../../icon/iconview';
|
|
10
|
+
import LabeledFieldView from '../../labeledfield/labeledfieldview';
|
|
11
|
+
import { createLabeledInputText } from '../../labeledfield/utils';
|
|
12
|
+
import { icons } from '@ckeditor/ckeditor5-core';
|
|
13
|
+
/**
|
|
14
|
+
* A search input field for the {@link module:ui/search/text/searchtextview~SearchTextView} component.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
* @extends module:ui/labeledfield/labeledfieldview~LabeledFieldView
|
|
18
|
+
*/
|
|
19
|
+
export default class SearchTextQueryView extends LabeledFieldView {
|
|
20
|
+
/**
|
|
21
|
+
* @inheritDoc
|
|
22
|
+
*/
|
|
23
|
+
constructor(locale, config) {
|
|
24
|
+
const t = locale.t;
|
|
25
|
+
const viewConfig = Object.assign({}, {
|
|
26
|
+
showResetButton: true,
|
|
27
|
+
showIcon: true,
|
|
28
|
+
creator: createLabeledInputText
|
|
29
|
+
}, config);
|
|
30
|
+
super(locale, viewConfig.creator);
|
|
31
|
+
this.label = config.label;
|
|
32
|
+
this._viewConfig = viewConfig;
|
|
33
|
+
if (this._viewConfig.showIcon) {
|
|
34
|
+
this.iconView = new IconView();
|
|
35
|
+
this.iconView.content = icons.loupe;
|
|
36
|
+
this.fieldWrapperChildren.add(this.iconView, 0);
|
|
37
|
+
this.extendTemplate({
|
|
38
|
+
attributes: {
|
|
39
|
+
class: 'ck-search__query_with-icon'
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (this._viewConfig.showResetButton) {
|
|
44
|
+
this.resetButtonView = new ButtonView(locale);
|
|
45
|
+
this.resetButtonView.set({
|
|
46
|
+
label: t('Clear'),
|
|
47
|
+
icon: icons.cancel,
|
|
48
|
+
class: 'ck-search__reset',
|
|
49
|
+
isVisible: false,
|
|
50
|
+
tooltip: true
|
|
51
|
+
});
|
|
52
|
+
this.resetButtonView.on('execute', () => {
|
|
53
|
+
this.reset();
|
|
54
|
+
this.focus();
|
|
55
|
+
this.fire('reset');
|
|
56
|
+
});
|
|
57
|
+
this.resetButtonView.bind('isVisible').to(this.fieldView, 'isEmpty', isEmpty => !isEmpty);
|
|
58
|
+
this.fieldWrapperChildren.add(this.resetButtonView);
|
|
59
|
+
this.extendTemplate({
|
|
60
|
+
attributes: {
|
|
61
|
+
class: 'ck-search__query_with-reset'
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Resets the search field to its default state.
|
|
68
|
+
*/
|
|
69
|
+
reset() {
|
|
70
|
+
this.fieldView.reset();
|
|
71
|
+
if (this._viewConfig.showResetButton) {
|
|
72
|
+
this.resetButtonView.isVisible = false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module ui/search/text/searchtextview
|
|
7
|
+
*/
|
|
8
|
+
import { FocusTracker, KeystrokeHandler, type Locale } from '@ckeditor/ckeditor5-utils';
|
|
9
|
+
import View from '../../view';
|
|
10
|
+
import { default as SearchTextQueryView, type SearchTextQueryViewConfig } from './searchtextqueryview';
|
|
11
|
+
import SearchResultsView from '../searchresultsview';
|
|
12
|
+
import FocusCycler from '../../focuscycler';
|
|
13
|
+
import type FilteredView from '../filteredview';
|
|
14
|
+
import type ViewCollection from '../../viewcollection';
|
|
15
|
+
import type InputBase from '../../input/inputbase';
|
|
16
|
+
import type InputTextView from '../../inputtext/inputtextview';
|
|
17
|
+
import '../../../theme/components/search/search.css';
|
|
18
|
+
/**
|
|
19
|
+
* A search component that allows filtering of an arbitrary view based on a search query
|
|
20
|
+
* specified by the user in a text field.
|
|
21
|
+
*
|
|
22
|
+
*```ts
|
|
23
|
+
* // This view must specify the `filter()` and `focus()` methods.
|
|
24
|
+
* const filteredView = ...;
|
|
25
|
+
*
|
|
26
|
+
* const searchView = new SearchTextView( locale, {
|
|
27
|
+
* searchFieldLabel: 'Search list items',
|
|
28
|
+
* filteredView
|
|
29
|
+
* } );
|
|
30
|
+
*
|
|
31
|
+
* view.render();
|
|
32
|
+
*
|
|
33
|
+
* document.body.append( view.element );
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export default class SearchTextView<TQueryFieldView extends InputBase<HTMLInputElement | HTMLTextAreaElement> = InputTextView> extends View {
|
|
37
|
+
/**
|
|
38
|
+
* Tracks information about the DOM focus in the view.
|
|
39
|
+
*
|
|
40
|
+
* @readonly
|
|
41
|
+
*/
|
|
42
|
+
focusTracker: FocusTracker;
|
|
43
|
+
/**
|
|
44
|
+
* An instance of the keystroke handler managing user interaction and accessibility.
|
|
45
|
+
*
|
|
46
|
+
* @readonly
|
|
47
|
+
*/
|
|
48
|
+
keystrokes: KeystrokeHandler;
|
|
49
|
+
/**
|
|
50
|
+
* A view hosting the {@link #filteredView} passed in the configuration and the {@link #infoView}.
|
|
51
|
+
*/
|
|
52
|
+
resultsView: SearchResultsView;
|
|
53
|
+
/**
|
|
54
|
+
* The view that is filtered by the search query.
|
|
55
|
+
*/
|
|
56
|
+
filteredView: FilteredView;
|
|
57
|
+
/**
|
|
58
|
+
* The view that displays the information about the search results.
|
|
59
|
+
*/
|
|
60
|
+
infoView: View | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* The view that allows the user to enter the search query.
|
|
63
|
+
*/
|
|
64
|
+
queryView: SearchTextQueryView<TQueryFieldView>;
|
|
65
|
+
/**
|
|
66
|
+
* Controls whether the component is in read-only mode.
|
|
67
|
+
*
|
|
68
|
+
* @default true
|
|
69
|
+
* @observable
|
|
70
|
+
*/
|
|
71
|
+
isEnabled: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* The number of results found for the current search query. Updated upon the {@link #search} event.
|
|
74
|
+
*
|
|
75
|
+
* @default 0
|
|
76
|
+
* @observable
|
|
77
|
+
*/
|
|
78
|
+
resultsCount: number;
|
|
79
|
+
/**
|
|
80
|
+
* The number of the items that can be searched in the {@link #filteredView}. Updated upon the {@link #search} event.
|
|
81
|
+
*
|
|
82
|
+
* @default 0
|
|
83
|
+
* @observable
|
|
84
|
+
*/
|
|
85
|
+
totalItemsCount: number;
|
|
86
|
+
/**
|
|
87
|
+
* The collection of children of the view.
|
|
88
|
+
*
|
|
89
|
+
* @readonly
|
|
90
|
+
*/
|
|
91
|
+
readonly children: ViewCollection;
|
|
92
|
+
/**
|
|
93
|
+
* The collection of focusable children of the view. Used by the focus management logic.
|
|
94
|
+
*
|
|
95
|
+
* @readonly
|
|
96
|
+
*/
|
|
97
|
+
readonly focusableChildren: ViewCollection;
|
|
98
|
+
locale: Locale;
|
|
99
|
+
/**
|
|
100
|
+
* Provides the focus management (keyboard navigation) between {@link #queryView} and {@link #filteredView}.
|
|
101
|
+
*
|
|
102
|
+
* @readonly
|
|
103
|
+
*/
|
|
104
|
+
focusCycler: FocusCycler;
|
|
105
|
+
/**
|
|
106
|
+
* The cached configuration object.
|
|
107
|
+
*
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
protected _config: SearchTextViewConfig<TQueryFieldView>;
|
|
111
|
+
/**
|
|
112
|
+
* Creates an instance of the {@link module:ui/search/text/searchtextview~SearchTextView} class.
|
|
113
|
+
*
|
|
114
|
+
* @param locale The localization services instance.
|
|
115
|
+
* @param config Configuration of the view.
|
|
116
|
+
*/
|
|
117
|
+
constructor(locale: Locale, config: SearchTextViewConfig<TQueryFieldView>);
|
|
118
|
+
/**
|
|
119
|
+
* @inheritDoc
|
|
120
|
+
*/
|
|
121
|
+
render(): void;
|
|
122
|
+
/**
|
|
123
|
+
* Focuses the {@link #queryView}.
|
|
124
|
+
*/
|
|
125
|
+
focus(): void;
|
|
126
|
+
/**
|
|
127
|
+
* Resets the component to its initial state.
|
|
128
|
+
*/
|
|
129
|
+
reset(): void;
|
|
130
|
+
/**
|
|
131
|
+
* Searches the {@link #filteredView} for the given query.
|
|
132
|
+
*
|
|
133
|
+
* @internal
|
|
134
|
+
* @param query The search query string.
|
|
135
|
+
*/
|
|
136
|
+
search(query: string): void;
|
|
137
|
+
/**
|
|
138
|
+
* Creates a search field view based on configured creator..
|
|
139
|
+
*/
|
|
140
|
+
private _createSearchTextQueryView;
|
|
141
|
+
/**
|
|
142
|
+
* Initializes the default {@link #infoView} behavior with default text labels when no custom info view
|
|
143
|
+
* was specified in the view config.
|
|
144
|
+
*/
|
|
145
|
+
private _enableDefaultInfoViewBehavior;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The configuration of the {@link module:ui/search/text/searchtextview~SearchTextView} class.
|
|
149
|
+
*/
|
|
150
|
+
export interface SearchTextViewConfig<TConfigSearchField extends InputBase<HTMLInputElement | HTMLTextAreaElement>> {
|
|
151
|
+
/**
|
|
152
|
+
* The configuration of the view's query field.
|
|
153
|
+
*/
|
|
154
|
+
queryView: SearchTextQueryViewConfig<TConfigSearchField>;
|
|
155
|
+
/**
|
|
156
|
+
* The view that is filtered by the search query.
|
|
157
|
+
*/
|
|
158
|
+
filteredView: FilteredView;
|
|
159
|
+
/**
|
|
160
|
+
* The view that displays the information about the search results.
|
|
161
|
+
*/
|
|
162
|
+
infoView?: {
|
|
163
|
+
/**
|
|
164
|
+
* The view that displays the information about the search results. If not specified,
|
|
165
|
+
* {@link module:ui/search/searchinfoview~SearchInfoView} is used.
|
|
166
|
+
*/
|
|
167
|
+
instance?: View;
|
|
168
|
+
/**
|
|
169
|
+
* The configuration of text labels displayed in the {@link #infoView} in different states
|
|
170
|
+
* of the search component.
|
|
171
|
+
*
|
|
172
|
+
* **Note**: This configuration is only used when the {@link #infoView} is **not** specified.
|
|
173
|
+
* In other cases, please use the {@link module:ui/search/searchview~SearchTextViewSearchEvent} to bring about
|
|
174
|
+
* your own info text logic.
|
|
175
|
+
*/
|
|
176
|
+
text?: {
|
|
177
|
+
notFound?: {
|
|
178
|
+
primary: SearchTextViewDefaultInfoText;
|
|
179
|
+
secondary?: SearchTextViewDefaultInfoText;
|
|
180
|
+
};
|
|
181
|
+
noSearchableItems?: {
|
|
182
|
+
primary: SearchTextViewDefaultInfoText;
|
|
183
|
+
secondary?: SearchTextViewDefaultInfoText;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* The custom CSS class name to be added to the search view element.
|
|
189
|
+
*/
|
|
190
|
+
class?: string;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Describes value of a info text configuration in {@link module:ui/search/text/searchtextview~SearchTextViewConfig}.
|
|
194
|
+
* A string or a function that returns a string with the information about the search results.
|
|
195
|
+
*/
|
|
196
|
+
export type SearchTextViewDefaultInfoText = string | ((query: string, resultsCount: number, totalItemsCount: number) => string);
|
|
197
|
+
/**
|
|
198
|
+
* An event fired when the search query changes fired by {@link module:ui/search/text/searchtextview~SearchTextView#search}.
|
|
199
|
+
*
|
|
200
|
+
* @eventName ~SearchTextView#search
|
|
201
|
+
*/
|
|
202
|
+
export type SearchTextViewSearchEvent = {
|
|
203
|
+
name: 'search';
|
|
204
|
+
args: [SearchTextViewSearchEventData];
|
|
205
|
+
};
|
|
206
|
+
export type SearchTextViewSearchEventData = {
|
|
207
|
+
/**
|
|
208
|
+
* The search query string.
|
|
209
|
+
*/
|
|
210
|
+
query: string;
|
|
211
|
+
/**
|
|
212
|
+
* The number of results found for the current search query.
|
|
213
|
+
*/
|
|
214
|
+
resultsCount: number;
|
|
215
|
+
/**
|
|
216
|
+
* The number of the items that can be searched.
|
|
217
|
+
*/
|
|
218
|
+
totalItemsCount: number;
|
|
219
|
+
};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module ui/search/text/searchtextview
|
|
7
|
+
*/
|
|
8
|
+
import { FocusTracker, KeystrokeHandler } from '@ckeditor/ckeditor5-utils';
|
|
9
|
+
import View from '../../view';
|
|
10
|
+
import { default as SearchTextQueryView } from './searchtextqueryview';
|
|
11
|
+
import SearchInfoView from '../searchinfoview';
|
|
12
|
+
import SearchResultsView from '../searchresultsview';
|
|
13
|
+
import FocusCycler from '../../focuscycler';
|
|
14
|
+
import { escapeRegExp } from 'lodash-es';
|
|
15
|
+
import '../../../theme/components/search/search.css';
|
|
16
|
+
/**
|
|
17
|
+
* A search component that allows filtering of an arbitrary view based on a search query
|
|
18
|
+
* specified by the user in a text field.
|
|
19
|
+
*
|
|
20
|
+
*```ts
|
|
21
|
+
* // This view must specify the `filter()` and `focus()` methods.
|
|
22
|
+
* const filteredView = ...;
|
|
23
|
+
*
|
|
24
|
+
* const searchView = new SearchTextView( locale, {
|
|
25
|
+
* searchFieldLabel: 'Search list items',
|
|
26
|
+
* filteredView
|
|
27
|
+
* } );
|
|
28
|
+
*
|
|
29
|
+
* view.render();
|
|
30
|
+
*
|
|
31
|
+
* document.body.append( view.element );
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export default class SearchTextView extends View {
|
|
35
|
+
/**
|
|
36
|
+
* Creates an instance of the {@link module:ui/search/text/searchtextview~SearchTextView} class.
|
|
37
|
+
*
|
|
38
|
+
* @param locale The localization services instance.
|
|
39
|
+
* @param config Configuration of the view.
|
|
40
|
+
*/
|
|
41
|
+
constructor(locale, config) {
|
|
42
|
+
super(locale);
|
|
43
|
+
this._config = config;
|
|
44
|
+
this.filteredView = config.filteredView;
|
|
45
|
+
this.queryView = this._createSearchTextQueryView();
|
|
46
|
+
this.focusTracker = new FocusTracker();
|
|
47
|
+
this.keystrokes = new KeystrokeHandler();
|
|
48
|
+
this.resultsView = new SearchResultsView(locale);
|
|
49
|
+
this.children = this.createCollection();
|
|
50
|
+
this.focusableChildren = this.createCollection([this.queryView, this.resultsView]);
|
|
51
|
+
this.set('isEnabled', true);
|
|
52
|
+
this.set('resultsCount', 0);
|
|
53
|
+
this.set('totalItemsCount', 0);
|
|
54
|
+
if (config.infoView && config.infoView.instance) {
|
|
55
|
+
this.infoView = config.infoView.instance;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.infoView = new SearchInfoView();
|
|
59
|
+
this._enableDefaultInfoViewBehavior();
|
|
60
|
+
this.on('render', () => {
|
|
61
|
+
// Initial search that determines if there are any searchable items
|
|
62
|
+
// and displays the corresponding info text.
|
|
63
|
+
this.search('');
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
this.resultsView.children.addMany([this.infoView, this.filteredView]);
|
|
67
|
+
this.focusCycler = new FocusCycler({
|
|
68
|
+
focusables: this.focusableChildren,
|
|
69
|
+
focusTracker: this.focusTracker,
|
|
70
|
+
keystrokeHandler: this.keystrokes,
|
|
71
|
+
actions: {
|
|
72
|
+
// Navigate form fields backwards using the Shift + Tab keystroke.
|
|
73
|
+
focusPrevious: 'shift + tab',
|
|
74
|
+
// Navigate form fields forwards using the Tab key.
|
|
75
|
+
focusNext: 'tab'
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
this.on('search', (evt, { resultsCount, totalItemsCount }) => {
|
|
79
|
+
this.resultsCount = resultsCount;
|
|
80
|
+
this.totalItemsCount = totalItemsCount;
|
|
81
|
+
});
|
|
82
|
+
this.setTemplate({
|
|
83
|
+
tag: 'div',
|
|
84
|
+
attributes: {
|
|
85
|
+
class: [
|
|
86
|
+
'ck',
|
|
87
|
+
'ck-search',
|
|
88
|
+
config.class || null
|
|
89
|
+
],
|
|
90
|
+
tabindex: '-1'
|
|
91
|
+
},
|
|
92
|
+
children: this.children
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* @inheritDoc
|
|
97
|
+
*/
|
|
98
|
+
render() {
|
|
99
|
+
super.render();
|
|
100
|
+
this.children.addMany([
|
|
101
|
+
this.queryView,
|
|
102
|
+
this.resultsView
|
|
103
|
+
]);
|
|
104
|
+
const stopPropagation = (data) => data.stopPropagation();
|
|
105
|
+
for (const focusableChild of this.focusableChildren) {
|
|
106
|
+
this.focusTracker.add(focusableChild.element);
|
|
107
|
+
}
|
|
108
|
+
// Start listening for the keystrokes coming from #element.
|
|
109
|
+
this.keystrokes.listenTo(this.element);
|
|
110
|
+
// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's
|
|
111
|
+
// keystroke handler would take over the key management in the URL input. We need to prevent
|
|
112
|
+
// this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.
|
|
113
|
+
this.keystrokes.set('arrowright', stopPropagation);
|
|
114
|
+
this.keystrokes.set('arrowleft', stopPropagation);
|
|
115
|
+
this.keystrokes.set('arrowup', stopPropagation);
|
|
116
|
+
this.keystrokes.set('arrowdown', stopPropagation);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Focuses the {@link #queryView}.
|
|
120
|
+
*/
|
|
121
|
+
focus() {
|
|
122
|
+
this.queryView.focus();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Resets the component to its initial state.
|
|
126
|
+
*/
|
|
127
|
+
reset() {
|
|
128
|
+
this.queryView.reset();
|
|
129
|
+
this.search('');
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Searches the {@link #filteredView} for the given query.
|
|
133
|
+
*
|
|
134
|
+
* @internal
|
|
135
|
+
* @param query The search query string.
|
|
136
|
+
*/
|
|
137
|
+
search(query) {
|
|
138
|
+
const regExp = query ? new RegExp(escapeRegExp(query), 'ig') : null;
|
|
139
|
+
const filteringResults = this.filteredView.filter(regExp);
|
|
140
|
+
this.fire('search', { query, ...filteringResults });
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Creates a search field view based on configured creator..
|
|
144
|
+
*/
|
|
145
|
+
_createSearchTextQueryView() {
|
|
146
|
+
const queryView = new SearchTextQueryView(this.locale, this._config.queryView);
|
|
147
|
+
this.listenTo(queryView.fieldView, 'input', () => {
|
|
148
|
+
this.search(queryView.fieldView.element.value);
|
|
149
|
+
});
|
|
150
|
+
queryView.on('reset', () => this.reset());
|
|
151
|
+
queryView.bind('isEnabled').to(this);
|
|
152
|
+
return queryView;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Initializes the default {@link #infoView} behavior with default text labels when no custom info view
|
|
156
|
+
* was specified in the view config.
|
|
157
|
+
*/
|
|
158
|
+
_enableDefaultInfoViewBehavior() {
|
|
159
|
+
const t = this.locale.t;
|
|
160
|
+
const infoView = this.infoView;
|
|
161
|
+
this.on('search', (evt, data) => {
|
|
162
|
+
if (!data.resultsCount) {
|
|
163
|
+
const defaultTextConfig = this._config.infoView && this._config.infoView.text;
|
|
164
|
+
let primaryText, secondaryText;
|
|
165
|
+
if (data.totalItemsCount) {
|
|
166
|
+
if (defaultTextConfig && defaultTextConfig.notFound) {
|
|
167
|
+
primaryText = defaultTextConfig.notFound.primary;
|
|
168
|
+
secondaryText = defaultTextConfig.notFound.secondary;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
primaryText = t('No results found');
|
|
172
|
+
secondaryText = '';
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
if (defaultTextConfig && defaultTextConfig.noSearchableItems) {
|
|
177
|
+
primaryText = defaultTextConfig.noSearchableItems.primary;
|
|
178
|
+
secondaryText = defaultTextConfig.noSearchableItems.secondary;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
primaryText = t('No searchable items');
|
|
182
|
+
secondaryText = '';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
infoView.set({
|
|
186
|
+
primaryText: normalizeInfoText(primaryText, data),
|
|
187
|
+
secondaryText: normalizeInfoText(secondaryText, data),
|
|
188
|
+
isVisible: true
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
infoView.set({
|
|
193
|
+
isVisible: false
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
function normalizeInfoText(text, { query, resultsCount, totalItemsCount }) {
|
|
198
|
+
return typeof text === 'function' ? text(query, resultsCount, totalItemsCount) : text;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|