Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 6be52b4

Browse files
authored
Merge pull request #474 from ckeditor/t/ckeditor5/1457
t/ckeditor5/1457: Implemented `ColorGridView` and `ColorTileView` components
2 parents 96ca937 + 09cf4cf commit 6be52b4

File tree

6 files changed

+499
-0
lines changed

6 files changed

+499
-0
lines changed

src/colorgrid/colorgridview.js

+195
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/**
2+
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
3+
* For licensing, see LICENSE.md.
4+
*/
5+
6+
/**
7+
* @module ui/colorgrid/colorgrid
8+
*/
9+
10+
import View from '../view';
11+
import ColorTileView from './colortileview';
12+
import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
13+
import FocusCycler from '../focuscycler';
14+
import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
15+
import '../../theme/components/colorgrid/colorgrid.css';
16+
17+
/**
18+
* A grid of {@link module:ui/colorgrid/colortile~ColorTileView color tiles}.
19+
*
20+
* @extends module:ui/view~View
21+
*/
22+
export default class ColorGridView extends View {
23+
/**
24+
* Creates an instance of a color grid containing {@link module:ui/colorgrid/colortile~ColorTileView tiles}.
25+
*
26+
* @param {module:utils/locale~Locale} [locale] The localization services instance.
27+
* @param {Object} options Component configuration
28+
* @param {Array.<module:ui/colorgrid/colorgrid~ColorDefinition>} [options.colorDefinitions] Array with definitions
29+
* required to create the {@link module:ui/colorgrid/colortile~ColorTileView tiles}.
30+
* @param {Number} options.columns A number of columns to display the tiles.
31+
*/
32+
constructor( locale, options ) {
33+
super( locale );
34+
35+
const colorDefinitions = options && options.colorDefinitions || [];
36+
const viewStyleAttribute = {};
37+
38+
if ( options && options.columns ) {
39+
viewStyleAttribute.gridTemplateColumns = `repeat( ${ options.columns }, 1fr)`;
40+
}
41+
42+
/**
43+
* The color of the currently selected color tile in {@link #items}.
44+
*
45+
* @type {String}
46+
*/
47+
this.set( 'selectedColor' );
48+
49+
/**
50+
* Collection of the child tile views.
51+
*
52+
* @readonly
53+
* @member {module:ui/viewcollection~ViewCollection}
54+
*/
55+
this.items = this.createCollection();
56+
57+
/**
58+
* Tracks information about DOM focus in the grid.
59+
*
60+
* @readonly
61+
* @member {module:utils/focustracker~FocusTracker}
62+
*/
63+
this.focusTracker = new FocusTracker();
64+
65+
/**
66+
* Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
67+
*
68+
* @readonly
69+
* @member {module:utils/keystrokehandler~KeystrokeHandler}
70+
*/
71+
this.keystrokes = new KeystrokeHandler();
72+
73+
/**
74+
* Helps cycling over focusable {@link #items} in the grid.
75+
*
76+
* @readonly
77+
* @protected
78+
* @member {module:ui/focuscycler~FocusCycler}
79+
*/
80+
this._focusCycler = new FocusCycler( {
81+
focusables: this.items,
82+
focusTracker: this.focusTracker,
83+
keystrokeHandler: this.keystrokes,
84+
actions: {
85+
// Navigate grid items backwards using the arrowup key.
86+
focusPrevious: 'arrowleft',
87+
88+
// Navigate grid items forwards using the arrowdown key.
89+
focusNext: 'arrowright',
90+
}
91+
} );
92+
93+
colorDefinitions.forEach( item => {
94+
const colorTile = new ColorTileView();
95+
96+
colorTile.set( {
97+
color: item.color,
98+
label: item.label,
99+
tooltip: true,
100+
hasBorder: item.options.hasBorder
101+
} );
102+
103+
colorTile.on( 'execute', () => {
104+
this.fire( 'execute', {
105+
value: item.color,
106+
hasBorder: item.options.hasBorder,
107+
label: item.label
108+
} );
109+
} );
110+
111+
this.items.add( colorTile );
112+
} );
113+
114+
this.setTemplate( {
115+
tag: 'div',
116+
children: this.items,
117+
attributes: {
118+
class: [
119+
'ck',
120+
'ck-color-grid'
121+
],
122+
style: viewStyleAttribute
123+
}
124+
} );
125+
126+
this.on( 'change:selectedColor', ( evt, name, selectedColor ) => {
127+
for ( const item of this.items ) {
128+
item.isOn = item.color === selectedColor;
129+
}
130+
} );
131+
}
132+
133+
/**
134+
* Focuses the first focusable in {@link #items}.
135+
*/
136+
focus() {
137+
if ( this.items.length ) {
138+
this.items.first.focus();
139+
}
140+
}
141+
142+
/**
143+
* Focuses the last focusable in {@link #items}.
144+
*/
145+
focusLast() {
146+
if ( this.items.length ) {
147+
this.items.last.focus();
148+
}
149+
}
150+
151+
/**
152+
* @inheritDoc
153+
*/
154+
render() {
155+
super.render();
156+
157+
// Items added before rendering should be known to the #focusTracker.
158+
for ( const item of this.items ) {
159+
this.focusTracker.add( item.element );
160+
}
161+
162+
this.items.on( 'add', ( evt, item ) => {
163+
this.focusTracker.add( item.element );
164+
} );
165+
166+
this.items.on( 'remove', ( evt, item ) => {
167+
this.focusTracker.remove( item.element );
168+
} );
169+
170+
// Start listening for the keystrokes coming from #element.
171+
this.keystrokes.listenTo( this.element );
172+
}
173+
}
174+
175+
/**
176+
* A color definition used to create a {@link module:ui/colorgrid/colortile~ColorTileView}.
177+
*
178+
* {
179+
* color: hsl(0, 0%, 75%),
180+
* label: 'Light Grey',
181+
* options: {
182+
* hasBorder: true
183+
* }
184+
* }
185+
*
186+
* @typedef {Object} module:ui/colorgrid/colorgrid~ColorDefinition
187+
* @type Object
188+
*
189+
* @property {String} color String representing a color.
190+
* It is used as value of background-color style in {@link module:ui/colorgrid/colortile~ColorTileView}.
191+
* @property {String} label String used as label for {@link module:ui/colorgrid/colortile~ColorTileView}.
192+
* @property {Object} options Additional options passed to create a {@link module:ui/colorgrid/colortile~ColorTileView}.
193+
* @property {Boolean} options.hasBorder A flag that indicates if special a CSS class should be added
194+
* to {@link module:ui/colorgrid/colortile~ColorTileView}, which renders a border around it.
195+
*/

src/colorgrid/colortileview.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
3+
* For licensing, see LICENSE.md.
4+
*/
5+
6+
/**
7+
* @module ui/colorgrid/colortile
8+
*/
9+
10+
import ButtonView from '../button/buttonview';
11+
import checkIcon from '../../theme/icons/color-tile-check.svg';
12+
13+
/**
14+
* This class represents a single color tile in the {@link module:ui/colorgrid/colorgrid~ColorGridView}.
15+
*
16+
* @extends module:ui/button/buttonview~ButtonView
17+
*/
18+
export default class ColorTileView extends ButtonView {
19+
constructor( locale ) {
20+
super( locale );
21+
22+
const bind = this.bindTemplate;
23+
24+
/**
25+
* String representing a color shown as tile's background.
26+
*
27+
* @type {String}
28+
*/
29+
this.set( 'color' );
30+
31+
/**
32+
* A flag that toggles a special CSS class responsible for displaying
33+
* a border around the button.
34+
*
35+
* @type {Boolean}
36+
*/
37+
this.set( 'hasBorder' );
38+
39+
this.icon = checkIcon;
40+
41+
this.extendTemplate( {
42+
attributes: {
43+
style: {
44+
backgroundColor: bind.to( 'color' )
45+
},
46+
class: [
47+
'ck',
48+
'ck-color-grid__tile',
49+
bind.if( 'hasBorder', 'ck-color-table__color-tile_bordered' )
50+
]
51+
}
52+
} );
53+
}
54+
}

0 commit comments

Comments
 (0)