-
Notifications
You must be signed in to change notification settings - Fork 3.6k
/
specialcharactersnavigationview.ts
140 lines (117 loc) · 4.08 KB
/
specialcharactersnavigationview.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module special-characters/ui/specialcharactersnavigationview
*/
import { Collection, type Locale } from 'ckeditor5/src/utils.js';
import {
addListToDropdown,
createDropdown,
ViewModel,
FormHeaderView,
type DropdownView,
type ListDropdownButtonDefinition
} from 'ckeditor5/src/ui.js';
/**
* A class representing the navigation part of the special characters UI. It is responsible
* for describing the feature and allowing the user to select a particular character group.
*/
export default class SpecialCharactersNavigationView extends FormHeaderView {
/**
* A dropdown that allows selecting a group of special characters to be displayed.
*/
public groupDropdownView: GroupDropdownView;
/**
* Creates an instance of the {@link module:special-characters/ui/specialcharactersnavigationview~SpecialCharactersNavigationView}
* class.
*
* @param locale The localization services instance.
* @param groupNames The names of the character groups and their displayed labels.
*/
constructor( locale: Locale, groupNames: GroupNames ) {
super( locale );
const t = locale.t;
this.set( 'class', 'ck-special-characters-navigation' );
this.groupDropdownView = this._createGroupDropdown( groupNames );
this.groupDropdownView.panelPosition = locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw';
this.label = t( 'Special characters' );
this.children.add( this.groupDropdownView );
}
/**
* Returns the name of the character group currently selected in the {@link #groupDropdownView}.
*/
public get currentGroupName(): string {
return this.groupDropdownView.value;
}
/**
* Focuses the character categories dropdown.
*/
public focus(): void {
this.groupDropdownView.focus();
}
/**
* Returns a dropdown that allows selecting character groups.
*
* @param groupNames The names of the character groups and their displayed labels.
*/
private _createGroupDropdown( groupNames: GroupNames ): GroupDropdownView {
const locale = this.locale;
const t = locale!.t;
const dropdown = createDropdown( locale ) as GroupDropdownView;
const groupDefinitions = this._getCharacterGroupListItemDefinitions( dropdown, groupNames );
const accessibleLabel = t( 'Character categories' );
dropdown.set( 'value', groupDefinitions.first!.model.name as string );
dropdown.buttonView.bind( 'label' ).to( dropdown, 'value', value => groupNames.get( value ) );
dropdown.buttonView.set( {
isOn: false,
withText: true,
tooltip: accessibleLabel,
class: [ 'ck-dropdown__button_label-width_auto' ],
ariaLabel: accessibleLabel,
ariaLabelledBy: undefined
} );
dropdown.on( 'execute', evt => {
dropdown.value = ( evt.source as ViewModel ).name as string;
} );
dropdown.delegate( 'execute' ).to( this );
addListToDropdown( dropdown, groupDefinitions, {
ariaLabel: accessibleLabel,
role: 'menu'
} );
return dropdown;
}
/**
* Returns list item definitions to be used in the character group dropdown
* representing specific character groups.
*
* @param dropdown Dropdown view element
* @param groupNames The names of the character groups and their displayed labels.
*/
private _getCharacterGroupListItemDefinitions(
dropdown: GroupDropdownView,
groupNames: GroupNames
): Collection<ListDropdownButtonDefinition> {
const groupDefs = new Collection<ListDropdownButtonDefinition>();
for ( const [ name, label ] of groupNames ) {
const model = new ViewModel( {
name,
label,
withText: true,
role: 'menuitemradio'
} );
model.bind( 'isOn' ).to( dropdown, 'value', value => value === model.name );
groupDefs.add( { type: 'button', model } );
}
return groupDefs;
}
}
/**
* The names of the character groups and their displayed labels.
*/
export type GroupNames = Map<string, string>;
/**
* `DropdownView` with additional field for the name of the currectly selected character group.
*/
export type GroupDropdownView = DropdownView & { value: string };