@ckeditor/ckeditor5-style 34.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.
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, 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
+ /**
7
+ * @module style/ui/stylegridview
8
+ */
9
+
10
+ import { View } from 'ckeditor5/src/ui';
11
+ import StyleGridButtonView from './stylegridbuttonview';
12
+
13
+ import '../../theme/stylegrid.css';
14
+
15
+ /**
16
+ * A class representing a grid of styles ({@link module:style/ui/stylegridbuttonview~StyleGridButtonView buttons}).
17
+ * Allows users to select a style.
18
+ *
19
+ * @protected
20
+ * @extends module:ui/view~View
21
+ */
22
+ export default class StyleGridView extends View {
23
+ /**
24
+ * Creates an instance of the {@link module:style/ui/stylegridview~StyleGridView} class.
25
+ *
26
+ * @param {module:utils/locale~Locale} locale The localization services instance.
27
+ * @param {Array.<module:style/style~StyleDefinition>} styleDefinitions Definitions of the styles.
28
+ */
29
+ constructor( locale, styleDefinitions ) {
30
+ super( locale );
31
+
32
+ /**
33
+ * Array of active style names. They must correspond to the names of styles from
34
+ * definitions passed to the {@link #constructor}.
35
+ *
36
+ * @observable
37
+ * @readonly
38
+ * @default []
39
+ * @member {Array.<String>} #activeStyles
40
+ */
41
+ this.set( 'activeStyles', [] );
42
+
43
+ /**
44
+ * Array of enabled style names. They must correspond to the names of styles from
45
+ * definitions passed to the {@link #constructor}.
46
+ *
47
+ * @observable
48
+ * @readonly
49
+ * @default []
50
+ * @member {Array.<String>} #enabledStyles
51
+ */
52
+ this.set( 'enabledStyles', [] );
53
+
54
+ /**
55
+ * A collection of style {@link module:style/ui/stylegridbuttonview~StyleGridButtonView buttons}.
56
+ *
57
+ * @readonly
58
+ * @member {module:ui/viewcollection~ViewCollection}
59
+ */
60
+ this.children = this.createCollection();
61
+ this.children.delegate( 'execute' ).to( this );
62
+
63
+ for ( const definition of styleDefinitions ) {
64
+ const gridTileView = new StyleGridButtonView( locale, definition );
65
+
66
+ this.children.add( gridTileView );
67
+ }
68
+
69
+ this.on( 'change:activeStyles', () => {
70
+ for ( const child of this.children ) {
71
+ child.isOn = this.activeStyles.includes( child.styleDefinition.name );
72
+ }
73
+ } );
74
+
75
+ this.on( 'change:enabledStyles', () => {
76
+ for ( const child of this.children ) {
77
+ child.isEnabled = this.enabledStyles.includes( child.styleDefinition.name );
78
+ }
79
+ } );
80
+
81
+ this.setTemplate( {
82
+ tag: 'div',
83
+
84
+ attributes: {
85
+ class: [
86
+ 'ck',
87
+ 'ck-style-grid'
88
+ ],
89
+ role: 'listbox'
90
+ },
91
+
92
+ children: this.children
93
+ } );
94
+
95
+ /**
96
+ * Fired when a {@link module:style/ui/stylegridbuttonview~StyleGridButtonView style} was selected (clicked) by the user.
97
+ *
98
+ * @event execute
99
+ */
100
+ }
101
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, 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
+ /**
7
+ * @module style/ui/stylegroupview
8
+ */
9
+
10
+ import {
11
+ LabelView,
12
+ View
13
+ } from 'ckeditor5/src/ui';
14
+ import StyleGridView from './stylegridview';
15
+
16
+ import '../../theme/stylegroup.css';
17
+
18
+ /**
19
+ * A class representing a group of styles (e.g. "block" or "inline").
20
+ *
21
+ * Renders a {@link module:style/ui/stylegridview~StyleGridView style grid} and a label.
22
+ *
23
+ * @protected
24
+ * @extends module:ui/view~View
25
+ */
26
+ export default class StyleGroupView extends View {
27
+ /**
28
+ * Creates an instance of the {@link module:style/ui/stylegroupview~StyleGroupView} class.
29
+ *
30
+ * @param {module:utils/locale~Locale} locale The localization services instance.
31
+ * @param {String} label The localized label of the group.
32
+ * @param {Array.<module:style/style~StyleDefinition>} styleDefinitions Definitions of the styles in the group.
33
+ */
34
+ constructor( locale, label, styleDefinitions ) {
35
+ super( locale );
36
+
37
+ /**
38
+ * The label of the group.
39
+ *
40
+ * @protected
41
+ * @readonly
42
+ * @member {module:ui/label~LabelView} #labelView
43
+ */
44
+ this.labelView = new LabelView( locale );
45
+ this.labelView.text = label;
46
+
47
+ /**
48
+ * The styles grid of the group.
49
+ *
50
+ * @readonly
51
+ * @member {module:style/ui/stylegridview~StyleGridView} #gridView
52
+ */
53
+ this.gridView = new StyleGridView( locale, styleDefinitions );
54
+
55
+ this.setTemplate( {
56
+ tag: 'div',
57
+
58
+ attributes: {
59
+ class: [
60
+ 'ck',
61
+ 'ck-style-panel__style-group'
62
+ ],
63
+ role: 'group',
64
+ 'aria-labelledby': this.labelView.id
65
+ },
66
+
67
+ children: [
68
+ this.labelView,
69
+ this.gridView
70
+ ]
71
+ } );
72
+ }
73
+ }
@@ -0,0 +1,201 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, 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
+ /**
7
+ * @module style/ui/stylepanelview
8
+ */
9
+
10
+ import {
11
+ FocusCycler,
12
+ View,
13
+ ViewCollection
14
+ } from 'ckeditor5/src/ui';
15
+ import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';
16
+ import StyleGroupView from './stylegroupview';
17
+
18
+ import '../../theme/stylepanel.css';
19
+
20
+ /**
21
+ * A class representing a panel with available content styles. It renders styles in button grids, grouped
22
+ * in categories.
23
+ *
24
+ * @protected
25
+ * @extends module:ui/view~View
26
+ */
27
+ export default class StylePanelView extends View {
28
+ /**
29
+ * Creates an instance of the {@link module:style/ui/stylegroupview~StyleGroupView} class.
30
+ *
31
+ * @param {module:utils/locale~Locale} locale The localization services instance.
32
+ * @param {Object} styleDefinitions Normalized definitions of the styles.
33
+ * @param {Array.<module:style/style~StyleDefinition>} styleDefinitions.block Definitions of block styles.
34
+ * @param {Array.<module:style/style~StyleDefinition>} styleDefinitions.inline Definitions of inline styles.
35
+ */
36
+ constructor( locale, styleDefinitions ) {
37
+ super( locale );
38
+
39
+ const t = locale.t;
40
+
41
+ /**
42
+ * Tracks information about DOM focus in the panel.
43
+ *
44
+ * @readonly
45
+ * @member {module:utils/focustracker~FocusTracker}
46
+ */
47
+ this.focusTracker = new FocusTracker();
48
+
49
+ /**
50
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
51
+ *
52
+ * @readonly
53
+ * @member {module:utils/keystrokehandler~KeystrokeHandler}
54
+ */
55
+ this.keystrokes = new KeystrokeHandler();
56
+
57
+ /**
58
+ * A collection of panel children.
59
+ *
60
+ * @readonly
61
+ * @member {module:ui/viewcollection~ViewCollection}
62
+ */
63
+ this.children = this.createCollection();
64
+
65
+ /**
66
+ * A view representing block styles group.
67
+ *
68
+ * @readonly
69
+ * @member {module:style/ui/stylegroupview~StyleGroupView}
70
+ */
71
+ this.blockStylesGroupView = new StyleGroupView( locale, t( 'Block styles' ), styleDefinitions.block );
72
+
73
+ /**
74
+ * A view representing inline styles group.
75
+ *
76
+ * @readonly
77
+ * @member {module:style/ui/stylegroupview~StyleGroupView}
78
+ */
79
+ this.inlineStylesGroupView = new StyleGroupView( locale, t( 'Text styles' ), styleDefinitions.inline );
80
+
81
+ /**
82
+ * Array of active style names. They must correspond to the names of styles from
83
+ * definitions passed to the {@link #constructor}.
84
+ *
85
+ * @observable
86
+ * @readonly
87
+ * @default []
88
+ * @member {Array.<String>} #activeStyles
89
+ */
90
+ this.set( 'activeStyles', [] );
91
+
92
+ /**
93
+ * Array of enabled style names. They must correspond to the names of styles from
94
+ * definitions passed to the {@link #constructor}.
95
+ *
96
+ * @observable
97
+ * @readonly
98
+ * @default []
99
+ * @member {Array.<String>} #enabledStyles
100
+ */
101
+ this.set( 'enabledStyles', [] );
102
+
103
+ /**
104
+ * A collection of views that can be focused in the panel.
105
+ *
106
+ * @readonly
107
+ * @protected
108
+ * @member {module:ui/viewcollection~ViewCollection}
109
+ */
110
+ this._focusables = new ViewCollection();
111
+
112
+ /**
113
+ * Helps cycling over {@link #_focusables} in the panel.
114
+ *
115
+ * @readonly
116
+ * @protected
117
+ * @member {module:ui/focuscycler~FocusCycler}
118
+ */
119
+ this._focusCycler = new FocusCycler( {
120
+ focusables: this._focusables,
121
+ focusTracker: this.focusTracker,
122
+ keystrokeHandler: this.keystrokes,
123
+ actions: {
124
+ // Navigate style buttons backwards using the ↑ or ← keystrokes.
125
+ focusPrevious: [ 'arrowup', 'arrowleft' ],
126
+
127
+ // Navigate style buttons forward using the Arrow ↓ or → keystrokes.
128
+ focusNext: [ 'arrowdown', 'arrowright' ]
129
+ }
130
+ } );
131
+
132
+ if ( styleDefinitions.block.length ) {
133
+ this.children.add( this.blockStylesGroupView );
134
+ }
135
+
136
+ if ( styleDefinitions.inline.length ) {
137
+ this.children.add( this.inlineStylesGroupView );
138
+ }
139
+
140
+ this.blockStylesGroupView.gridView.delegate( 'execute' ).to( this );
141
+ this.inlineStylesGroupView.gridView.delegate( 'execute' ).to( this );
142
+
143
+ this.blockStylesGroupView.gridView.bind( 'activeStyles', 'enabledStyles' ).to( this );
144
+ this.inlineStylesGroupView.gridView.bind( 'activeStyles', 'enabledStyles' ).to( this );
145
+
146
+ this.setTemplate( {
147
+ tag: 'div',
148
+
149
+ attributes: {
150
+ class: [
151
+ 'ck',
152
+ 'ck-style-panel'
153
+ ]
154
+ },
155
+
156
+ children: this.children
157
+ } );
158
+
159
+ /**
160
+ * Fired when a style was selected (clicked) by the user.
161
+ *
162
+ * @event execute
163
+ */
164
+ }
165
+
166
+ /**
167
+ * @inheritDoc
168
+ */
169
+ render() {
170
+ super.render();
171
+
172
+ const childViews = [
173
+ ...this.blockStylesGroupView.gridView.children,
174
+ ...this.inlineStylesGroupView.gridView.children
175
+ ];
176
+
177
+ childViews.forEach( v => {
178
+ // Register the view as focusable.
179
+ this._focusables.add( v );
180
+
181
+ // Register the view in the focus tracker.
182
+ this.focusTracker.add( v.element );
183
+ } );
184
+
185
+ this.keystrokes.listenTo( this.element );
186
+ }
187
+
188
+ /**
189
+ * Focuses the first focusable element in the panel.
190
+ */
191
+ focus() {
192
+ this._focusCycler.focusFirst();
193
+ }
194
+
195
+ /**
196
+ * Focuses the last focusable element in the panel.
197
+ */
198
+ focusLast() {
199
+ this._focusCycler.focusLast();
200
+ }
201
+ }
package/src/utils.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, 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
+ /**
7
+ * @module style/utils
8
+ */
9
+
10
+ /**
11
+ * Normalizes {@link module:style/style~StyleConfig#definitions} in the configuration of the styles feature.
12
+ * The structure of normalized styles looks as follows:
13
+ *
14
+ * {
15
+ * block: [
16
+ * <module:style/style~StyleDefinition>,
17
+ * <module:style/style~StyleDefinition>,
18
+ * ...
19
+ * ],
20
+ * inline: [
21
+ * <module:style/style~StyleDefinition>,
22
+ * <module:style/style~StyleDefinition>,
23
+ * ...
24
+ * ]
25
+ * }
26
+ *
27
+ * @protected
28
+ * @param {module:html-support/dataschema~DataSchema} dataSchema
29
+ * @param {Array.<module:style/style~StyleDefinition>} styleDefinitions
30
+ * @returns {Object} An object with normalized style definitions grouped into `block` and `inline` categories (arrays).
31
+ */
32
+ export function normalizeConfig( dataSchema, styleDefinitions = [] ) {
33
+ const normalizedDefinitions = {
34
+ block: [],
35
+ inline: []
36
+ };
37
+
38
+ for ( const definition of styleDefinitions ) {
39
+ const matchingDefinitions = Array.from( dataSchema.getDefinitionsForView( definition.element ) );
40
+ const modelElements = matchingDefinitions.map( ( { model } ) => model );
41
+ const isBlock = matchingDefinitions.some( ( { isBlock } ) => isBlock );
42
+
43
+ if ( isBlock ) {
44
+ normalizedDefinitions.block.push( { isBlock, modelElements, ...definition } );
45
+ } else {
46
+ normalizedDefinitions.inline.push( { isBlock, modelElements, ...definition } );
47
+ }
48
+ }
49
+ return normalizedDefinitions;
50
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright (c) 2003-2022, 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
+ :root {
7
+ --ck-style-panel-columns: 3;
8
+ }
9
+
10
+ .ck.ck-style-panel .ck-style-grid {
11
+ display: grid;
12
+ grid-template-columns: repeat(var(--ck-style-panel-columns),auto);
13
+
14
+ & .ck-style-grid__button {
15
+ display: flex;
16
+ justify-content: space-between;
17
+ flex-direction: column;
18
+
19
+ & .ck-style-grid__button__preview {
20
+ display: flex;
21
+ align-content: center;
22
+ justify-content: flex-start;
23
+ align-items: center;
24
+ flex-grow: 1;
25
+ flex-basis: 100%;
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
@@ -0,0 +1,5 @@
1
+ /*
2
+ * Copyright (c) 2003-2022, 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
+