@ckeditor/ckeditor5-ui 35.2.1 → 35.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/package.json +31 -23
  2. package/src/bindings/addkeyboardhandlingforgrid.js +45 -57
  3. package/src/bindings/clickoutsidehandler.js +15 -21
  4. package/src/bindings/injectcsstransitiondisabler.js +16 -20
  5. package/src/bindings/preventdefault.js +6 -8
  6. package/src/bindings/submithandler.js +5 -7
  7. package/src/button/button.js +5 -0
  8. package/src/button/buttonview.js +220 -259
  9. package/src/button/switchbuttonview.js +56 -71
  10. package/src/colorgrid/colorgridview.js +135 -197
  11. package/src/colorgrid/colortileview.js +37 -47
  12. package/src/colorgrid/utils.js +57 -66
  13. package/src/componentfactory.js +79 -93
  14. package/src/dropdown/button/dropdownbutton.js +5 -0
  15. package/src/dropdown/button/dropdownbuttonview.js +44 -57
  16. package/src/dropdown/button/splitbuttonview.js +159 -207
  17. package/src/dropdown/dropdownpanelfocusable.js +5 -0
  18. package/src/dropdown/dropdownpanelview.js +101 -112
  19. package/src/dropdown/dropdownview.js +396 -438
  20. package/src/dropdown/utils.js +164 -213
  21. package/src/editableui/editableuiview.js +125 -141
  22. package/src/editableui/inline/inlineeditableuiview.js +44 -54
  23. package/src/editorui/bodycollection.js +61 -75
  24. package/src/editorui/boxed/boxededitoruiview.js +91 -104
  25. package/src/editorui/editoruiview.js +30 -39
  26. package/src/focuscycler.js +214 -245
  27. package/src/formheader/formheaderview.js +58 -70
  28. package/src/icon/iconview.js +145 -111
  29. package/src/iframe/iframeview.js +37 -49
  30. package/src/index.js +0 -17
  31. package/src/input/inputview.js +170 -198
  32. package/src/inputnumber/inputnumberview.js +48 -56
  33. package/src/inputtext/inputtextview.js +14 -18
  34. package/src/label/labelview.js +44 -53
  35. package/src/labeledfield/labeledfieldview.js +212 -235
  36. package/src/labeledfield/utils.js +39 -57
  37. package/src/labeledinput/labeledinputview.js +190 -221
  38. package/src/list/listitemview.js +40 -50
  39. package/src/list/listseparatorview.js +15 -19
  40. package/src/list/listview.js +94 -115
  41. package/src/model.js +19 -25
  42. package/src/notification/notification.js +151 -202
  43. package/src/panel/balloon/balloonpanelview.js +535 -628
  44. package/src/panel/balloon/contextualballoon.js +611 -732
  45. package/src/panel/sticky/stickypanelview.js +238 -270
  46. package/src/template.js +1049 -1479
  47. package/src/toolbar/balloon/balloontoolbar.js +337 -424
  48. package/src/toolbar/block/blockbuttonview.js +32 -42
  49. package/src/toolbar/block/blocktoolbar.js +375 -477
  50. package/src/toolbar/normalizetoolbarconfig.js +17 -21
  51. package/src/toolbar/toolbarlinebreakview.js +15 -19
  52. package/src/toolbar/toolbarseparatorview.js +15 -19
  53. package/src/toolbar/toolbarview.js +866 -1053
  54. package/src/tooltipmanager.js +324 -353
  55. package/src/view.js +389 -430
  56. package/src/viewcollection.js +147 -178
  57. package/src/button/button.jsdoc +0 -165
  58. package/src/dropdown/button/dropdownbutton.jsdoc +0 -22
  59. package/src/dropdown/dropdownpanelfocusable.jsdoc +0 -27
@@ -2,13 +2,10 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module ui/focuscycler
8
7
  */
9
-
10
8
  import isVisible from '@ckeditor/ckeditor5-utils/src/dom/isvisible';
11
-
12
9
  /**
13
10
  * A utility class that helps cycling over focusable {@link module:ui/view~View views} in a
14
11
  * {@link module:ui/viewcollection~ViewCollection} when the focus is tracked by the
@@ -56,252 +53,224 @@ import isVisible from '@ckeditor/ckeditor5-utils/src/dom/isvisible';
56
53
  * Check out the {@glink framework/guides/deep-dive/ui/focus-tracking "Deep dive into focus tracking" guide} to learn more.
57
54
  */
58
55
  export default class FocusCycler {
59
- /**
60
- * Creates an instance of the focus cycler utility.
61
- *
62
- * @param {Object} options Configuration options.
63
- * @param {module:utils/collection~Collection|Object} options.focusables
64
- * @param {module:utils/focustracker~FocusTracker} options.focusTracker
65
- * @param {module:utils/keystrokehandler~KeystrokeHandler} [options.keystrokeHandler]
66
- * @param {Object} [options.actions]
67
- */
68
- constructor( options ) {
69
- Object.assign( this, options );
70
-
71
- /**
72
- * A {@link module:ui/view~View view} collection that the cycler operates on.
73
- *
74
- * @readonly
75
- * @member {module:utils/collection~Collection} #focusables
76
- */
77
-
78
- /**
79
- * A focus tracker instance that the cycler uses to determine the current focus
80
- * state in {@link #focusables}.
81
- *
82
- * @readonly
83
- * @member {module:utils/focustracker~FocusTracker} #focusTracker
84
- */
85
-
86
- /**
87
- * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}
88
- * which can respond to certain keystrokes and cycle the focus.
89
- *
90
- * @readonly
91
- * @member {module:utils/keystrokehandler~KeystrokeHandler} #keystrokeHandler
92
- */
93
-
94
- /**
95
- * Actions that the cycler can take when a keystroke is pressed. Requires
96
- * `options.keystrokeHandler` to be passed and working. When an action is
97
- * performed, `preventDefault` and `stopPropagation` will be called on the event
98
- * the keystroke fired in the DOM.
99
- *
100
- * actions: {
101
- * // Will call #focusPrevious() when arrowleft or arrowup is pressed.
102
- * focusPrevious: [ 'arrowleft', 'arrowup' ],
103
- *
104
- * // Will call #focusNext() when arrowdown is pressed.
105
- * focusNext: 'arrowdown'
106
- * }
107
- *
108
- * @readonly
109
- * @member {Object} #actions
110
- */
111
-
112
- if ( options.actions && options.keystrokeHandler ) {
113
- for ( const methodName in options.actions ) {
114
- let actions = options.actions[ methodName ];
115
-
116
- if ( typeof actions == 'string' ) {
117
- actions = [ actions ];
118
- }
119
-
120
- for ( const keystroke of actions ) {
121
- options.keystrokeHandler.set( keystroke, ( data, cancel ) => {
122
- this[ methodName ]();
123
- cancel();
124
- } );
125
- }
126
- }
127
- }
128
- }
129
-
130
- /**
131
- * Returns the first focusable view in {@link #focusables}.
132
- * Returns `null` if there is none.
133
- *
134
- * **Note**: Hidden views (e.g. with `display: none`) are ignored.
135
- *
136
- * @readonly
137
- * @member {module:ui/view~View|null} #first
138
- */
139
- get first() {
140
- return this.focusables.find( isFocusable ) || null;
141
- }
142
-
143
- /**
144
- * Returns the last focusable view in {@link #focusables}.
145
- * Returns `null` if there is none.
146
- *
147
- * **Note**: Hidden views (e.g. with `display: none`) are ignored.
148
- *
149
- * @readonly
150
- * @member {module:ui/view~View|null} #last
151
- */
152
- get last() {
153
- return this.focusables.filter( isFocusable ).slice( -1 )[ 0 ] || null;
154
- }
155
-
156
- /**
157
- * Returns the next focusable view in {@link #focusables} based on {@link #current}.
158
- * Returns `null` if there is none.
159
- *
160
- * **Note**: Hidden views (e.g. with `display: none`) are ignored.
161
- *
162
- * @readonly
163
- * @member {module:ui/view~View|null} #next
164
- */
165
- get next() {
166
- return this._getFocusableItem( 1 );
167
- }
168
-
169
- /**
170
- * Returns the previous focusable view in {@link #focusables} based on {@link #current}.
171
- * Returns `null` if there is none.
172
- *
173
- * **Note**: Hidden views (e.g. with `display: none`) are ignored.
174
- *
175
- * @readonly
176
- * @member {module:ui/view~View|null} #previous
177
- */
178
- get previous() {
179
- return this._getFocusableItem( -1 );
180
- }
181
-
182
- /**
183
- * An index of the view in the {@link #focusables} which is focused according
184
- * to {@link #focusTracker}. Returns `null` when there is no such view.
185
- *
186
- * @readonly
187
- * @member {Number|null} #current
188
- */
189
- get current() {
190
- let index = null;
191
-
192
- // There's no focused view in the focusables.
193
- if ( this.focusTracker.focusedElement === null ) {
194
- return null;
195
- }
196
-
197
- this.focusables.find( ( view, viewIndex ) => {
198
- const focused = view.element === this.focusTracker.focusedElement;
199
-
200
- if ( focused ) {
201
- index = viewIndex;
202
- }
203
-
204
- return focused;
205
- } );
206
-
207
- return index;
208
- }
209
-
210
- /**
211
- * Focuses the {@link #first} item in {@link #focusables}.
212
- *
213
- * **Note**: Hidden views (e.g. with `display: none`) are ignored.
214
- */
215
- focusFirst() {
216
- this._focus( this.first );
217
- }
218
-
219
- /**
220
- * Focuses the {@link #last} item in {@link #focusables}.
221
- *
222
- * **Note**: Hidden views (e.g. with `display: none`) are ignored.
223
- */
224
- focusLast() {
225
- this._focus( this.last );
226
- }
227
-
228
- /**
229
- * Focuses the {@link #next} item in {@link #focusables}.
230
- *
231
- * **Note**: Hidden views (e.g. with `display: none`) are ignored.
232
- */
233
- focusNext() {
234
- this._focus( this.next );
235
- }
236
-
237
- /**
238
- * Focuses the {@link #previous} item in {@link #focusables}.
239
- *
240
- * **Note**: Hidden views (e.g. with `display: none`) are ignored.
241
- */
242
- focusPrevious() {
243
- this._focus( this.previous );
244
- }
245
-
246
- /**
247
- * Focuses the given view if it exists.
248
- *
249
- * @protected
250
- * @param {module:ui/view~View} view
251
- */
252
- _focus( view ) {
253
- if ( view ) {
254
- view.focus();
255
- }
256
- }
257
-
258
- /**
259
- * Returns the next or previous focusable view in {@link #focusables} with respect
260
- * to {@link #current}.
261
- *
262
- * @protected
263
- * @param {Number} step Either `1` for checking forward from {@link #current} or
264
- * `-1` for checking backwards.
265
- * @returns {module:ui/view~View|null}
266
- */
267
- _getFocusableItem( step ) {
268
- // Cache for speed.
269
- const current = this.current;
270
- const collectionLength = this.focusables.length;
271
-
272
- if ( !collectionLength ) {
273
- return null;
274
- }
275
-
276
- // Start from the beginning if no view is focused.
277
- // https://github.com/ckeditor/ckeditor5-ui/issues/206
278
- if ( current === null ) {
279
- return this[ step === 1 ? 'first' : 'last' ];
280
- }
281
-
282
- // Cycle in both directions.
283
- let index = ( current + collectionLength + step ) % collectionLength;
284
-
285
- do {
286
- const view = this.focusables.get( index );
287
-
288
- if ( isFocusable( view ) ) {
289
- return view;
290
- }
291
-
292
- // Cycle in both directions.
293
- index = ( index + collectionLength + step ) % collectionLength;
294
- } while ( index !== current );
295
-
296
- return null;
297
- }
56
+ /**
57
+ * Creates an instance of the focus cycler utility.
58
+ *
59
+ * @param {Object} options Configuration options.
60
+ * @param {module:utils/collection~Collection|Object} options.focusables
61
+ * @param {module:utils/focustracker~FocusTracker} options.focusTracker
62
+ * @param {module:utils/keystrokehandler~KeystrokeHandler} [options.keystrokeHandler]
63
+ * @param {Object} [options.actions]
64
+ */
65
+ constructor(options) {
66
+ this.focusables = options.focusables;
67
+ this.focusTracker = options.focusTracker;
68
+ this.keystrokeHandler = options.keystrokeHandler;
69
+ this.actions = options.actions;
70
+ /**
71
+ * A {@link module:ui/view~View view} collection that the cycler operates on.
72
+ *
73
+ * @readonly
74
+ * @member {module:utils/collection~Collection} #focusables
75
+ */
76
+ /**
77
+ * A focus tracker instance that the cycler uses to determine the current focus
78
+ * state in {@link #focusables}.
79
+ *
80
+ * @readonly
81
+ * @member {module:utils/focustracker~FocusTracker} #focusTracker
82
+ */
83
+ /**
84
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}
85
+ * which can respond to certain keystrokes and cycle the focus.
86
+ *
87
+ * @readonly
88
+ * @member {module:utils/keystrokehandler~KeystrokeHandler} #keystrokeHandler
89
+ */
90
+ /**
91
+ * Actions that the cycler can take when a keystroke is pressed. Requires
92
+ * `options.keystrokeHandler` to be passed and working. When an action is
93
+ * performed, `preventDefault` and `stopPropagation` will be called on the event
94
+ * the keystroke fired in the DOM.
95
+ *
96
+ * actions: {
97
+ * // Will call #focusPrevious() when arrowleft or arrowup is pressed.
98
+ * focusPrevious: [ 'arrowleft', 'arrowup' ],
99
+ *
100
+ * // Will call #focusNext() when arrowdown is pressed.
101
+ * focusNext: 'arrowdown'
102
+ * }
103
+ *
104
+ * @readonly
105
+ * @member {Object} #actions
106
+ */
107
+ if (options.actions && options.keystrokeHandler) {
108
+ for (const methodName in options.actions) {
109
+ let actions = options.actions[methodName];
110
+ if (typeof actions == 'string') {
111
+ actions = [actions];
112
+ }
113
+ for (const keystroke of actions) {
114
+ options.keystrokeHandler.set(keystroke, (data, cancel) => {
115
+ this[methodName]();
116
+ cancel();
117
+ });
118
+ }
119
+ }
120
+ }
121
+ }
122
+ /**
123
+ * Returns the first focusable view in {@link #focusables}.
124
+ * Returns `null` if there is none.
125
+ *
126
+ * **Note**: Hidden views (e.g. with `display: none`) are ignored.
127
+ *
128
+ * @readonly
129
+ * @member {module:ui/view~View|null} #first
130
+ */
131
+ get first() {
132
+ return (this.focusables.find(isFocusable) || null);
133
+ }
134
+ /**
135
+ * Returns the last focusable view in {@link #focusables}.
136
+ * Returns `null` if there is none.
137
+ *
138
+ * **Note**: Hidden views (e.g. with `display: none`) are ignored.
139
+ *
140
+ * @readonly
141
+ * @member {module:ui/view~View|null} #last
142
+ */
143
+ get last() {
144
+ return (this.focusables.filter(isFocusable).slice(-1)[0] || null);
145
+ }
146
+ /**
147
+ * Returns the next focusable view in {@link #focusables} based on {@link #current}.
148
+ * Returns `null` if there is none.
149
+ *
150
+ * **Note**: Hidden views (e.g. with `display: none`) are ignored.
151
+ *
152
+ * @readonly
153
+ * @member {module:ui/view~View|null} #next
154
+ */
155
+ get next() {
156
+ return this._getFocusableItem(1);
157
+ }
158
+ /**
159
+ * Returns the previous focusable view in {@link #focusables} based on {@link #current}.
160
+ * Returns `null` if there is none.
161
+ *
162
+ * **Note**: Hidden views (e.g. with `display: none`) are ignored.
163
+ *
164
+ * @readonly
165
+ * @member {module:ui/view~View|null} #previous
166
+ */
167
+ get previous() {
168
+ return this._getFocusableItem(-1);
169
+ }
170
+ /**
171
+ * An index of the view in the {@link #focusables} which is focused according
172
+ * to {@link #focusTracker}. Returns `null` when there is no such view.
173
+ *
174
+ * @readonly
175
+ * @member {Number|null} #current
176
+ */
177
+ get current() {
178
+ let index = null;
179
+ // There's no focused view in the focusables.
180
+ if (this.focusTracker.focusedElement === null) {
181
+ return null;
182
+ }
183
+ this.focusables.find((view, viewIndex) => {
184
+ const focused = view.element === this.focusTracker.focusedElement;
185
+ if (focused) {
186
+ index = viewIndex;
187
+ }
188
+ return focused;
189
+ });
190
+ return index;
191
+ }
192
+ /**
193
+ * Focuses the {@link #first} item in {@link #focusables}.
194
+ *
195
+ * **Note**: Hidden views (e.g. with `display: none`) are ignored.
196
+ */
197
+ focusFirst() {
198
+ this._focus(this.first);
199
+ }
200
+ /**
201
+ * Focuses the {@link #last} item in {@link #focusables}.
202
+ *
203
+ * **Note**: Hidden views (e.g. with `display: none`) are ignored.
204
+ */
205
+ focusLast() {
206
+ this._focus(this.last);
207
+ }
208
+ /**
209
+ * Focuses the {@link #next} item in {@link #focusables}.
210
+ *
211
+ * **Note**: Hidden views (e.g. with `display: none`) are ignored.
212
+ */
213
+ focusNext() {
214
+ this._focus(this.next);
215
+ }
216
+ /**
217
+ * Focuses the {@link #previous} item in {@link #focusables}.
218
+ *
219
+ * **Note**: Hidden views (e.g. with `display: none`) are ignored.
220
+ */
221
+ focusPrevious() {
222
+ this._focus(this.previous);
223
+ }
224
+ /**
225
+ * Focuses the given view if it exists.
226
+ *
227
+ * @protected
228
+ * @param {module:ui/view~View} view
229
+ */
230
+ _focus(view) {
231
+ if (view) {
232
+ view.focus();
233
+ }
234
+ }
235
+ /**
236
+ * Returns the next or previous focusable view in {@link #focusables} with respect
237
+ * to {@link #current}.
238
+ *
239
+ * @protected
240
+ * @param {Number} step Either `1` for checking forward from {@link #current} or
241
+ * `-1` for checking backwards.
242
+ * @returns {module:ui/view~View|null}
243
+ */
244
+ _getFocusableItem(step) {
245
+ // Cache for speed.
246
+ const current = this.current;
247
+ const collectionLength = this.focusables.length;
248
+ if (!collectionLength) {
249
+ return null;
250
+ }
251
+ // Start from the beginning if no view is focused.
252
+ // https://github.com/ckeditor/ckeditor5-ui/issues/206
253
+ if (current === null) {
254
+ return this[step === 1 ? 'first' : 'last'];
255
+ }
256
+ // Cycle in both directions.
257
+ let index = (current + collectionLength + step) % collectionLength;
258
+ do {
259
+ const view = this.focusables.get(index);
260
+ if (isFocusable(view)) {
261
+ return view;
262
+ }
263
+ // Cycle in both directions.
264
+ index = (index + collectionLength + step) % collectionLength;
265
+ } while (index !== current);
266
+ return null;
267
+ }
298
268
  }
299
-
300
269
  // Checks whether a view is focusable.
301
270
  //
302
271
  // @private
303
272
  // @param {module:ui/view~View} view A view to be checked.
304
273
  // @returns {Boolean}
305
- function isFocusable( view ) {
306
- return !!( view.focus && isVisible( view.element ) );
274
+ function isFocusable(view) {
275
+ return !!(view.focus && isVisible(view.element));
307
276
  }
@@ -2,15 +2,11 @@
2
2
  * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module ui/formheader/formheaderview
8
7
  */
9
-
10
8
  import View from '../view';
11
-
12
9
  import '../../theme/components/formheader/formheader.css';
13
-
14
10
  /**
15
11
  * The class component representing a form header view. It should be used in more advanced forms to
16
12
  * describe the main purpose of the form.
@@ -27,70 +23,62 @@ import '../../theme/components/formheader/formheader.css';
27
23
  * @extends module:ui/view~View
28
24
  */
29
25
  export default class FormHeaderView extends View {
30
- /**
31
- * Creates an instance of the form header class.
32
- *
33
- * @param {module:utils/locale~Locale} locale The locale instance.
34
- * @param {Object} options
35
- * @param {String} options.label A label.
36
- * @param {String} [options.class] An additional class.
37
- */
38
- constructor( locale, options = {} ) {
39
- super( locale );
40
-
41
- const bind = this.bindTemplate;
42
-
43
- /**
44
- * The label of the header.
45
- *
46
- * @observable
47
- * @member {String} #label
48
- */
49
- this.set( 'label', options.label || '' );
50
-
51
- /**
52
- * An additional CSS class added to the {@link #element}.
53
- *
54
- * @observable
55
- * @member {String} #class
56
- */
57
- this.set( 'class', options.class || null );
58
-
59
- /**
60
- * A collection of header items.
61
- *
62
- * @readonly
63
- * @member {module:ui/viewcollection~ViewCollection}
64
- */
65
- this.children = this.createCollection();
66
-
67
- this.setTemplate( {
68
- tag: 'div',
69
- attributes: {
70
- class: [
71
- 'ck',
72
- 'ck-form__header',
73
- bind.to( 'class' )
74
- ]
75
- },
76
- children: this.children
77
- } );
78
-
79
- const label = new View( locale );
80
-
81
- label.setTemplate( {
82
- tag: 'span',
83
- attributes: {
84
- class: [
85
- 'ck',
86
- 'ck-form__header__label'
87
- ]
88
- },
89
- children: [
90
- { text: bind.to( 'label' ) }
91
- ]
92
- } );
93
-
94
- this.children.add( label );
95
- }
26
+ /**
27
+ * Creates an instance of the form header class.
28
+ *
29
+ * @param {module:utils/locale~Locale} locale The locale instance.
30
+ * @param {Object} options
31
+ * @param {String} options.label A label.
32
+ * @param {String} [options.class] An additional class.
33
+ */
34
+ constructor(locale, options = {}) {
35
+ super(locale);
36
+ const bind = this.bindTemplate;
37
+ /**
38
+ * The label of the header.
39
+ *
40
+ * @observable
41
+ * @member {String} #label
42
+ */
43
+ this.set('label', options.label || '');
44
+ /**
45
+ * An additional CSS class added to the {@link #element}.
46
+ *
47
+ * @observable
48
+ * @member {String} #class
49
+ */
50
+ this.set('class', options.class || null);
51
+ /**
52
+ * A collection of header items.
53
+ *
54
+ * @readonly
55
+ * @member {module:ui/viewcollection~ViewCollection}
56
+ */
57
+ this.children = this.createCollection();
58
+ this.setTemplate({
59
+ tag: 'div',
60
+ attributes: {
61
+ class: [
62
+ 'ck',
63
+ 'ck-form__header',
64
+ bind.to('class')
65
+ ]
66
+ },
67
+ children: this.children
68
+ });
69
+ const label = new View(locale);
70
+ label.setTemplate({
71
+ tag: 'span',
72
+ attributes: {
73
+ class: [
74
+ 'ck',
75
+ 'ck-form__header__label'
76
+ ]
77
+ },
78
+ children: [
79
+ { text: bind.to('label') }
80
+ ]
81
+ });
82
+ this.children.add(label);
83
+ }
96
84
  }