@ckeditor/ckeditor5-ui 39.0.2 → 40.1.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.
Files changed (136) hide show
  1. package/LICENSE.md +3 -3
  2. package/lang/contexts.json +5 -1
  3. package/lang/translations/ar.po +16 -0
  4. package/lang/translations/ast.po +16 -0
  5. package/lang/translations/az.po +16 -0
  6. package/lang/translations/bg.po +16 -0
  7. package/lang/translations/bn.po +16 -0
  8. package/lang/translations/ca.po +16 -0
  9. package/lang/translations/cs.po +16 -0
  10. package/lang/translations/da.po +16 -0
  11. package/lang/translations/de-ch.po +16 -0
  12. package/lang/translations/de.po +16 -0
  13. package/lang/translations/el.po +16 -0
  14. package/lang/translations/en-au.po +16 -0
  15. package/lang/translations/en-gb.po +16 -0
  16. package/lang/translations/en.po +16 -0
  17. package/lang/translations/eo.po +16 -0
  18. package/lang/translations/es.po +16 -0
  19. package/lang/translations/et.po +16 -0
  20. package/lang/translations/eu.po +16 -0
  21. package/lang/translations/fa.po +16 -0
  22. package/lang/translations/fi.po +16 -0
  23. package/lang/translations/fr.po +16 -0
  24. package/lang/translations/gl.po +16 -0
  25. package/lang/translations/he.po +16 -0
  26. package/lang/translations/hi.po +16 -0
  27. package/lang/translations/hr.po +16 -0
  28. package/lang/translations/hu.po +16 -0
  29. package/lang/translations/id.po +16 -0
  30. package/lang/translations/it.po +16 -0
  31. package/lang/translations/ja.po +16 -0
  32. package/lang/translations/km.po +16 -0
  33. package/lang/translations/kn.po +16 -0
  34. package/lang/translations/ko.po +16 -0
  35. package/lang/translations/ku.po +16 -0
  36. package/lang/translations/lt.po +16 -0
  37. package/lang/translations/lv.po +16 -0
  38. package/lang/translations/ms.po +16 -0
  39. package/lang/translations/nb.po +16 -0
  40. package/lang/translations/ne.po +16 -0
  41. package/lang/translations/nl.po +16 -0
  42. package/lang/translations/no.po +16 -0
  43. package/lang/translations/pl.po +16 -0
  44. package/lang/translations/pt-br.po +17 -1
  45. package/lang/translations/pt.po +16 -0
  46. package/lang/translations/ro.po +16 -0
  47. package/lang/translations/ru.po +16 -0
  48. package/lang/translations/sk.po +16 -0
  49. package/lang/translations/sl.po +16 -0
  50. package/lang/translations/sq.po +16 -0
  51. package/lang/translations/sr-latn.po +16 -0
  52. package/lang/translations/sr.po +16 -0
  53. package/lang/translations/sv.po +16 -0
  54. package/lang/translations/th.po +16 -0
  55. package/lang/translations/tk.po +16 -0
  56. package/lang/translations/tr.po +16 -0
  57. package/lang/translations/tt.po +16 -0
  58. package/lang/translations/ug.po +38 -22
  59. package/lang/translations/uk.po +16 -0
  60. package/lang/translations/ur.po +16 -0
  61. package/lang/translations/uz.po +16 -0
  62. package/lang/translations/vi.po +16 -0
  63. package/lang/translations/zh-cn.po +16 -0
  64. package/lang/translations/zh.po +16 -0
  65. package/package.json +3 -3
  66. package/src/arialiveannouncer.d.ts +94 -0
  67. package/src/arialiveannouncer.js +113 -0
  68. package/src/autocomplete/autocompleteview.d.ts +81 -0
  69. package/src/autocomplete/autocompleteview.js +153 -0
  70. package/src/button/button.d.ts +0 -6
  71. package/src/button/buttonlabel.d.ts +34 -0
  72. package/src/button/buttonlabel.js +5 -0
  73. package/src/button/buttonlabelview.d.ts +31 -0
  74. package/src/button/buttonlabelview.js +42 -0
  75. package/src/button/buttonview.d.ts +14 -10
  76. package/src/button/buttonview.js +11 -25
  77. package/src/dropdown/dropdownview.js +5 -4
  78. package/src/dropdown/utils.d.ts +15 -1
  79. package/src/dropdown/utils.js +47 -21
  80. package/src/editorui/editorui.d.ts +6 -0
  81. package/src/editorui/editorui.js +2 -0
  82. package/src/editorui/poweredby.js +14 -37
  83. package/src/focuscycler.d.ts +45 -2
  84. package/src/focuscycler.js +34 -9
  85. package/src/formheader/formheaderview.d.ts +6 -0
  86. package/src/formheader/formheaderview.js +6 -0
  87. package/src/highlightedtext/highlightedtextview.d.ts +38 -0
  88. package/src/highlightedtext/highlightedtextview.js +102 -0
  89. package/src/icon/iconview.d.ts +7 -0
  90. package/src/icon/iconview.js +2 -0
  91. package/src/index.d.ts +12 -2
  92. package/src/index.js +8 -0
  93. package/src/input/inputbase.d.ts +107 -0
  94. package/src/input/inputbase.js +110 -0
  95. package/src/input/inputview.d.ts +4 -89
  96. package/src/input/inputview.js +5 -87
  97. package/src/labeledfield/labeledfieldview.d.ts +7 -2
  98. package/src/labeledfield/labeledfieldview.js +2 -2
  99. package/src/labeledfield/utils.d.ts +34 -4
  100. package/src/labeledfield/utils.js +51 -6
  101. package/src/list/listitemgroupview.d.ts +59 -0
  102. package/src/list/listitemgroupview.js +63 -0
  103. package/src/list/listitemview.d.ts +2 -1
  104. package/src/list/listitemview.js +3 -1
  105. package/src/list/listview.d.ts +59 -2
  106. package/src/list/listview.js +105 -8
  107. package/src/panel/balloon/balloonpanelview.js +26 -4
  108. package/src/panel/sticky/stickypanelview.d.ts +1 -3
  109. package/src/panel/sticky/stickypanelview.js +53 -50
  110. package/src/search/filteredview.d.ts +31 -0
  111. package/src/search/filteredview.js +5 -0
  112. package/src/search/searchinfoview.d.ts +45 -0
  113. package/src/search/searchinfoview.js +59 -0
  114. package/src/search/searchresultsview.d.ts +54 -0
  115. package/src/search/searchresultsview.js +65 -0
  116. package/src/search/text/searchtextqueryview.d.ts +76 -0
  117. package/src/search/text/searchtextqueryview.js +75 -0
  118. package/src/search/text/searchtextview.d.ts +219 -0
  119. package/src/search/text/searchtextview.js +201 -0
  120. package/src/spinner/spinnerview.d.ts +25 -0
  121. package/src/spinner/spinnerview.js +38 -0
  122. package/src/textarea/textareaview.d.ts +88 -0
  123. package/src/textarea/textareaview.js +142 -0
  124. package/src/toolbar/block/blocktoolbar.js +30 -26
  125. package/src/toolbar/normalizetoolbarconfig.d.ts +1 -0
  126. package/src/toolbar/normalizetoolbarconfig.js +9 -8
  127. package/src/toolbar/toolbarview.d.ts +1 -0
  128. package/src/toolbar/toolbarview.js +4 -2
  129. package/theme/components/arialiveannouncer/arialiveannouncer.css +10 -0
  130. package/theme/components/autocomplete/autocomplete.css +22 -0
  131. package/theme/components/button/button.css +9 -1
  132. package/theme/components/formheader/formheader.css +4 -0
  133. package/theme/components/highlightedtext/highlightedtext.css +12 -0
  134. package/theme/components/search/search.css +43 -0
  135. package/theme/components/spinner/spinner.css +23 -0
  136. package/theme/components/textarea/textarea.css +10 -0
@@ -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
+ }
@@ -0,0 +1,25 @@
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/spinner/spinnerview
7
+ */
8
+ import View from '../view';
9
+ import '../../theme/components/spinner/spinner.css';
10
+ /**
11
+ * The spinner view class.
12
+ */
13
+ export default class SpinnerView extends View {
14
+ /**
15
+ * Controls whether the spinner is visible.
16
+ *
17
+ * @observable
18
+ * @default false
19
+ */
20
+ isVisible: boolean;
21
+ /**
22
+ * @inheritDoc
23
+ */
24
+ constructor();
25
+ }
@@ -0,0 +1,38 @@
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/spinner/spinnerview
7
+ */
8
+ import View from '../view';
9
+ import '../../theme/components/spinner/spinner.css';
10
+ /**
11
+ * The spinner view class.
12
+ */
13
+ export default class SpinnerView extends View {
14
+ /**
15
+ * @inheritDoc
16
+ */
17
+ constructor() {
18
+ super();
19
+ this.set('isVisible', false);
20
+ const bind = this.bindTemplate;
21
+ this.setTemplate({
22
+ tag: 'span',
23
+ attributes: {
24
+ class: [
25
+ 'ck',
26
+ 'ck-spinner-container',
27
+ bind.if('isVisible', 'ck-hidden', value => !value)
28
+ ]
29
+ },
30
+ children: [{
31
+ tag: 'span',
32
+ attributes: {
33
+ class: ['ck', 'ck-spinner']
34
+ }
35
+ }]
36
+ });
37
+ }
38
+ }
@@ -0,0 +1,88 @@
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/textarea/textareaview
7
+ */
8
+ import { type Locale } from '@ckeditor/ckeditor5-utils';
9
+ import InputBase from '../input/inputbase';
10
+ import '../../theme/components/input/input.css';
11
+ import '../../theme/components/textarea/textarea.css';
12
+ /**
13
+ * The textarea view class.
14
+ *
15
+ * ```ts
16
+ * const textareaView = new TextareaView();
17
+ *
18
+ * textareaView.minRows = 2;
19
+ * textareaView.maxRows = 10;
20
+ *
21
+ * textareaView.render();
22
+ *
23
+ * document.body.append( textareaView.element );
24
+ * ```
25
+ */
26
+ export default class TextareaView extends InputBase<HTMLTextAreaElement> {
27
+ /**
28
+ * Specifies the visible height of a text area, in lines.
29
+ *
30
+ * @observable
31
+ * @default 2
32
+ */
33
+ minRows: number;
34
+ /**
35
+ * Specifies the maximum number of rows.
36
+ *
37
+ * @observable
38
+ * @default 5
39
+ */
40
+ maxRows: number;
41
+ /**
42
+ * Specifies the value of HTML attribute that indicates whether the user can resize the element.
43
+ *
44
+ * @observable
45
+ * @default 'none'
46
+ */
47
+ resize: 'both' | 'horizontal' | 'vertical' | 'none';
48
+ /**
49
+ * An internal property that stores the current height of the textarea. Used for the DOM binding.
50
+ *
51
+ * @observable
52
+ * @default null
53
+ * @internal
54
+ */
55
+ _height: number | null;
56
+ /**
57
+ * @inheritDoc
58
+ */
59
+ constructor(locale?: Locale);
60
+ /**
61
+ * @inheritDoc
62
+ */
63
+ render(): void;
64
+ /**
65
+ * @inheritDoc
66
+ */
67
+ reset(): void;
68
+ /**
69
+ * Updates the {@link #_height} of the view depending on {@link #minRows}, {@link #maxRows}, and the current content size.
70
+ *
71
+ * **Note**: This method overrides manual resize done by the user using a handle. It's a known bug.
72
+ */
73
+ private _updateAutoGrowHeight;
74
+ /**
75
+ * Validates the {@link #minRows} and {@link #maxRows} properties and warns in the console if the configuration is incorrect.
76
+ */
77
+ private _validateMinMaxRows;
78
+ }
79
+ /**
80
+ * Fired every time the layout of the {@link module:ui/textarea/textareaview~TextareaView} possibly changed as a result
81
+ * of the user input or the value change via {@link module:ui/textarea/textareaview~TextareaView#value}.
82
+ *
83
+ * @eventName ~TextareaView#update
84
+ */
85
+ export type TextareaViewUpdateEvent = {
86
+ name: 'update';
87
+ args: [];
88
+ };