@ckeditor/ckeditor5-table 35.0.1 → 35.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.
@@ -7,7 +7,9 @@
7
7
  * @module table/ui/inserttableview
8
8
  */
9
9
 
10
- import { View } from 'ckeditor5/src/ui';
10
+ import { View, addKeyboardHandlingForGrid } from 'ckeditor5/src/ui';
11
+
12
+ import { KeystrokeHandler, FocusTracker, uid } from 'ckeditor5/src/utils';
11
13
 
12
14
  import './../../theme/inserttable.css';
13
15
 
@@ -28,6 +30,16 @@ export default class InsertTableView extends View {
28
30
 
29
31
  const bind = this.bindTemplate;
30
32
 
33
+ /**
34
+ * A unique id of a label element displaying the current geometry of the table.
35
+ * Used by every {@link #items item} of the view as a pointer to an accessible label.
36
+ *
37
+ * @private
38
+ * @readonly
39
+ * @member {String}
40
+ */
41
+ this._geometryLabelId = `ck-editor__label_${ uid() }`;
42
+
31
43
  /**
32
44
  * A collection of table size box items.
33
45
  *
@@ -36,6 +48,16 @@ export default class InsertTableView extends View {
36
48
  */
37
49
  this.items = this._createGridCollection();
38
50
 
51
+ this.keystrokes = new KeystrokeHandler();
52
+
53
+ /**
54
+ * Tracks information about the DOM focus in the grid.
55
+ *
56
+ * @readonly
57
+ * @member {module:utils/focustracker~FocusTracker}
58
+ */
59
+ this.focusTracker = new FocusTracker();
60
+
39
61
  /**
40
62
  * The currently selected number of rows of the new table.
41
63
  *
@@ -81,7 +103,11 @@ export default class InsertTableView extends View {
81
103
  {
82
104
  tag: 'div',
83
105
  attributes: {
84
- class: [ 'ck-insert-table-dropdown__label' ]
106
+ id: this._geometryLabelId,
107
+ class: [
108
+ 'ck',
109
+ 'ck-insert-table-dropdown__label'
110
+ ]
85
111
  },
86
112
  children: [
87
113
  {
@@ -98,13 +124,34 @@ export default class InsertTableView extends View {
98
124
 
99
125
  click: bind.to( () => {
100
126
  this.fire( 'execute' );
127
+ } ),
128
+
129
+ keydown: bind.to( evt => {
130
+ if ( evt.key === 'Enter' ) {
131
+ this.fire( 'execute' );
132
+ evt.preventDefault();
133
+ }
101
134
  } )
102
135
  }
103
136
  } );
104
137
 
138
+ // #rows and #columns are set via changes to #focusTracker on mouse over.
105
139
  this.on( 'boxover', ( evt, domEvt ) => {
106
140
  const { row, column } = domEvt.target.dataset;
107
141
 
142
+ this.items.get( ( row - 1 ) * 10 + ( column - 1 ) ).focus();
143
+ } );
144
+
145
+ // This allows the #rows and #columns to be updated when:
146
+ // * the user navigates the grid using the keyboard,
147
+ // * the user moves the mouse over grid items.
148
+ this.focusTracker.on( 'change:focusedElement', ( evt, name, focusedElement ) => {
149
+ if ( !focusedElement ) {
150
+ return;
151
+ }
152
+
153
+ const { row, column } = focusedElement.dataset;
154
+
108
155
  // As row & column indexes are zero-based transform it to number of selected rows & columns.
109
156
  this.set( {
110
157
  rows: parseInt( row ),
@@ -112,29 +159,39 @@ export default class InsertTableView extends View {
112
159
  } );
113
160
  } );
114
161
 
115
- this.on( 'change:columns', () => {
116
- this._highlightGridBoxes();
117
- } );
162
+ this.on( 'change:columns', () => this._highlightGridBoxes() );
163
+ this.on( 'change:rows', () => this._highlightGridBoxes() );
164
+ }
165
+
166
+ render() {
167
+ super.render();
118
168
 
119
- this.on( 'change:rows', () => {
120
- this._highlightGridBoxes();
169
+ addKeyboardHandlingForGrid( {
170
+ keystrokeHandler: this.keystrokes,
171
+ focusTracker: this.focusTracker,
172
+ gridItems: this.items,
173
+ numberOfColumns: 10
121
174
  } );
175
+
176
+ for ( const item of this.items ) {
177
+ this.focusTracker.add( item.element );
178
+ }
179
+
180
+ this.keystrokes.listenTo( this.element );
122
181
  }
123
182
 
124
183
  /**
125
184
  * @inheritDoc
126
185
  */
127
186
  focus() {
128
- // The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.
129
- // The method should be implemented while working on keyboard support for this view. See #22.
187
+ this.items.get( 0 ).focus();
130
188
  }
131
189
 
132
190
  /**
133
191
  * @inheritDoc
134
192
  */
135
193
  focusLast() {
136
- // The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.
137
- // The method should be implemented while working on keyboard support for this view. See #22.
194
+ this.items.get( 0 ).focus();
138
195
  }
139
196
 
140
197
  /**
@@ -170,7 +227,7 @@ export default class InsertTableView extends View {
170
227
  const row = Math.floor( index / 10 );
171
228
  const column = index % 10;
172
229
 
173
- boxes.push( new TableSizeGridBoxView( this.locale, row + 1, column + 1 ) );
230
+ boxes.push( new TableSizeGridBoxView( this.locale, row + 1, column + 1, this._geometryLabelId ) );
174
231
  }
175
232
 
176
233
  return this.createCollection( boxes );
@@ -194,7 +251,7 @@ class TableSizeGridBoxView extends View {
194
251
  /**
195
252
  * @inheritDoc
196
253
  */
197
- constructor( locale, row, column ) {
254
+ constructor( locale, row, column, ariaLabelledById ) {
198
255
  super( locale );
199
256
 
200
257
  const bind = this.bindTemplate;
@@ -211,12 +268,22 @@ class TableSizeGridBoxView extends View {
211
268
  tag: 'div',
212
269
  attributes: {
213
270
  class: [
271
+ 'ck',
214
272
  'ck-insert-table-dropdown-grid-box',
215
273
  bind.if( 'isOn', 'ck-on' )
216
274
  ],
217
275
  'data-row': row,
218
- 'data-column': column
276
+ 'data-column': column,
277
+ 'tabindex': -1,
278
+ 'aria-labelledby': ariaLabelledById
219
279
  }
220
280
  } );
221
281
  }
282
+
283
+ /**
284
+ * @inheritDoc
285
+ */
286
+ focus() {
287
+ this.element.focus();
288
+ }
222
289
  }
@@ -12,9 +12,12 @@
12
12
  --ck-table-column-resizer-position-offset: calc(var(--ck-table-column-resizer-width) * -0.5 - 0.5px);
13
13
  }
14
14
 
15
+ .ck-content .table .ck-table-resized {
16
+ table-layout: fixed;
17
+ }
18
+
15
19
  .ck-content .table table {
16
20
  overflow: hidden;
17
- table-layout: fixed;
18
21
  }
19
22
 
20
23
  .ck-content .table td,
@@ -22,7 +25,7 @@
22
25
  position: relative;
23
26
  }
24
27
 
25
- .ck-content .table .table-column-resizer {
28
+ .ck.ck-editor__editable .table .ck-table-column-resizer {
26
29
  position: absolute;
27
30
  /* The resizer element resides in each cell so to occupy the entire height of the table, which is unknown from a CSS point of view,
28
31
  it is extended to an extremely high height. Even for screens with a very high pixel density, the resizer will fulfill its role as
@@ -37,23 +40,23 @@
37
40
  z-index: var(--ck-z-default);
38
41
  }
39
42
 
43
+ .ck.ck-editor__editable.ck-column-resize_disabled .table .ck-table-column-resizer {
44
+ display: none;
45
+ }
46
+
40
47
  /* The resizer elements, which are extended to an extremely high height, break the drag & drop feature in Chrome. To make it work again,
41
48
  all resizers must be hidden while the table is dragged. */
42
- .ck-content .table[draggable] .table-column-resizer {
49
+ .ck.ck-editor__editable .table[draggable] .ck-table-column-resizer {
43
50
  display: none;
44
51
  }
45
52
 
46
- .ck-content .table .table-column-resizer:hover,
47
- .ck-content .table .table-column-resizer__active {
53
+ .ck.ck-editor__editable .table .ck-table-column-resizer:hover,
54
+ .ck.ck-editor__editable .table .ck-table-column-resizer__active {
48
55
  background-color: var(--ck-color-table-column-resizer-hover);
49
56
  opacity: 0.25;
50
57
  }
51
58
 
52
- .ck-content[dir=rtl] .table .table-column-resizer {
59
+ .ck.ck-editor__editable[dir=rtl] .table .ck-table-column-resizer {
53
60
  left: var(--ck-table-column-resizer-position-offset);
54
61
  right: unset;
55
62
  }
56
-
57
- .ck-content.ck-read-only .table .table-column-resizer {
58
- display: none;
59
- }