@syncfusion/ej2-inputs 30.2.4 → 31.1.17
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.
- package/dist/ej2-inputs.min.js +2 -2
- package/dist/ej2-inputs.umd.min.js +2 -2
- package/dist/ej2-inputs.umd.min.js.map +1 -1
- package/dist/es6/ej2-inputs.es2015.js +1 -1
- package/dist/es6/ej2-inputs.es2015.js.map +1 -1
- package/dist/es6/ej2-inputs.es5.js +1 -1
- package/dist/es6/ej2-inputs.es5.js.map +1 -1
- package/dist/global/ej2-inputs.min.js +2 -2
- package/dist/global/ej2-inputs.min.js.map +1 -1
- package/dist/global/index.d.ts +1 -1
- package/dist/ts/color-picker/color-picker-model.d.ts +186 -0
- package/dist/ts/color-picker/color-picker.d.ts +398 -0
- package/dist/ts/color-picker/color-picker.ts +2209 -0
- package/dist/ts/color-picker/index.d.ts +5 -0
- package/dist/ts/color-picker/index.ts +5 -0
- package/dist/ts/common/index.d.ts +4 -0
- package/dist/ts/common/index.ts +4 -0
- package/dist/ts/common/signature-base.d.ts +340 -0
- package/dist/ts/common/signature-base.ts +1170 -0
- package/dist/ts/form-validator/form-validator-model.d.ts +121 -0
- package/dist/ts/form-validator/form-validator.d.ts +312 -0
- package/dist/ts/form-validator/form-validator.ts +1068 -0
- package/dist/ts/form-validator/index.d.ts +5 -0
- package/dist/ts/form-validator/index.ts +5 -0
- package/dist/ts/index.d.ts +18 -0
- package/dist/ts/index.ts +18 -0
- package/dist/ts/input/index.d.ts +4 -0
- package/dist/ts/input/index.ts +4 -0
- package/dist/ts/input/input.d.ts +345 -0
- package/dist/ts/input/input.ts +1277 -0
- package/dist/ts/maskedtextbox/base/index.d.ts +4 -0
- package/dist/ts/maskedtextbox/base/index.ts +4 -0
- package/dist/ts/maskedtextbox/base/mask-base.d.ts +134 -0
- package/dist/ts/maskedtextbox/base/mask-base.ts +1207 -0
- package/dist/ts/maskedtextbox/index.d.ts +5 -0
- package/dist/ts/maskedtextbox/index.ts +5 -0
- package/dist/ts/maskedtextbox/maskedtextbox/index.d.ts +5 -0
- package/dist/ts/maskedtextbox/maskedtextbox/index.ts +5 -0
- package/dist/ts/maskedtextbox/maskedtextbox/maskedtextbox-model.d.ts +167 -0
- package/dist/ts/maskedtextbox/maskedtextbox/maskedtextbox.d.ts +307 -0
- package/dist/ts/maskedtextbox/maskedtextbox/maskedtextbox.ts +709 -0
- package/dist/ts/numerictextbox/index.d.ts +5 -0
- package/dist/ts/numerictextbox/index.ts +5 -0
- package/dist/ts/numerictextbox/numerictextbox-model.d.ts +228 -0
- package/dist/ts/numerictextbox/numerictextbox.d.ts +431 -0
- package/dist/ts/numerictextbox/numerictextbox.ts +1672 -0
- package/dist/ts/otp-input/index.d.ts +5 -0
- package/dist/ts/otp-input/index.ts +5 -0
- package/dist/ts/otp-input/otp-input-model.d.ts +165 -0
- package/dist/ts/otp-input/otp-input.d.ts +365 -0
- package/dist/ts/otp-input/otp-input.ts +924 -0
- package/dist/ts/rating/index.d.ts +5 -0
- package/dist/ts/rating/index.ts +5 -0
- package/dist/ts/rating/rating-model.d.ts +239 -0
- package/dist/ts/rating/rating.d.ts +416 -0
- package/dist/ts/rating/rating.ts +1101 -0
- package/dist/ts/signature/index.d.ts +5 -0
- package/dist/ts/signature/index.ts +5 -0
- package/dist/ts/signature/signature-model.d.ts +131 -0
- package/dist/ts/signature/signature.d.ts +167 -0
- package/dist/ts/signature/signature.ts +266 -0
- package/dist/ts/slider/index.d.ts +5 -0
- package/dist/ts/slider/index.ts +5 -0
- package/dist/ts/slider/slider-model.d.ts +401 -0
- package/dist/ts/slider/slider.d.ts +721 -0
- package/dist/ts/slider/slider.ts +3497 -0
- package/dist/ts/smart-textarea/caret-helper.d.ts +17 -0
- package/dist/ts/smart-textarea/caret-helper.ts +95 -0
- package/dist/ts/smart-textarea/index.d.ts +5 -0
- package/dist/ts/smart-textarea/index.ts +5 -0
- package/dist/ts/smart-textarea/smart-textarea-model.d.ts +44 -0
- package/dist/ts/smart-textarea/smart-textarea.d.ts +80 -0
- package/dist/ts/smart-textarea/smart-textarea.ts +518 -0
- package/dist/ts/speech-to-text/index.d.ts +5 -0
- package/dist/ts/speech-to-text/index.ts +5 -0
- package/dist/ts/speech-to-text/speech-to-text-model.d.ts +270 -0
- package/dist/ts/speech-to-text/speech-to-text.d.ts +487 -0
- package/dist/ts/speech-to-text/speech-to-text.ts +1008 -0
- package/dist/ts/textarea/index.d.ts +5 -0
- package/dist/ts/textarea/index.ts +5 -0
- package/dist/ts/textarea/textarea-model.d.ts +161 -0
- package/dist/ts/textarea/textarea.d.ts +237 -0
- package/dist/ts/textarea/textarea.ts +812 -0
- package/dist/ts/textbox/index.d.ts +5 -0
- package/dist/ts/textbox/index.ts +5 -0
- package/dist/ts/textbox/textbox-model.d.ts +155 -0
- package/dist/ts/textbox/textbox.d.ts +288 -0
- package/dist/ts/textbox/textbox.ts +872 -0
- package/dist/ts/uploader/index.d.ts +5 -0
- package/dist/ts/uploader/index.ts +5 -0
- package/dist/ts/uploader/uploader-model.d.ts +555 -0
- package/dist/ts/uploader/uploader.d.ts +1216 -0
- package/dist/ts/uploader/uploader.ts +4391 -0
- package/package.json +62 -12
- package/src/input/input.js +1 -1
- package/styles/bootstrap5.3-lite.css +3 -3
- package/styles/bootstrap5.3.css +5 -5
- package/styles/input/_layout.scss +0 -1
- package/styles/input/tailwind3.css +0 -1
- package/styles/tailwind-dark-lite.css +3 -3
- package/styles/tailwind-dark.css +5 -5
- package/styles/tailwind-lite.css +3 -3
- package/styles/tailwind.css +5 -5
- package/styles/tailwind3-lite.css +0 -1
- package/styles/tailwind3.css +0 -1
- package/styles/uploader/_bootstrap5.3-definition.scss +1 -1
- package/styles/uploader/_tailwind-definition.scss +1 -1
- package/styles/uploader/bootstrap5.3.css +5 -5
- package/styles/uploader/tailwind-dark.css +5 -5
- package/styles/uploader/tailwind.css +5 -5
|
@@ -0,0 +1,2209 @@
|
|
|
1
|
+
/* eslint-disable prefer-spread */
|
|
2
|
+
import { BaseEventArgs, Component, EmitType, Event, INotifyPropertyChanged, NotifyPropertyChanges, Property } from '@syncfusion/ej2-base';
|
|
3
|
+
import { Browser, closest, detach, EventHandler, getInstance, select, selectAll, formatUnit } from '@syncfusion/ej2-base';
|
|
4
|
+
import { addClass, attributes, classList, isNullOrUndefined, L10n } from '@syncfusion/ej2-base';
|
|
5
|
+
import { remove, removeClass, rippleEffect } from '@syncfusion/ej2-base';
|
|
6
|
+
import { SplitButton, BeforeOpenCloseMenuEventArgs, getModel } from '@syncfusion/ej2-splitbuttons';
|
|
7
|
+
import { Deferred } from '@syncfusion/ej2-splitbuttons';
|
|
8
|
+
import { Tooltip, TooltipEventArgs, getZindexPartial, Popup, isCollide } from '@syncfusion/ej2-popups';
|
|
9
|
+
import { Input } from './../input/index';
|
|
10
|
+
import { NumericTextBox, NumericTextBoxModel, ChangeEventArgs } from './../numerictextbox/index';
|
|
11
|
+
import { Slider, SliderChangeEventArgs } from './../slider/slider';
|
|
12
|
+
import { ColorPickerModel } from './color-picker-model';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Defines the ColorPicker Mode
|
|
16
|
+
* ```props
|
|
17
|
+
* Picker :- Specifies that the ColorPicker component should be rendered with the picker mode.
|
|
18
|
+
* Palette :- Specifies that the ColorPicker component should be rendered with the palette mode.
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export type ColorPickerMode = 'Picker' | 'Palette';
|
|
22
|
+
|
|
23
|
+
const APPLY: string = 'e-apply';
|
|
24
|
+
const CANCEL: string = 'e-cancel';
|
|
25
|
+
const CURRENT: string = 'e-current';
|
|
26
|
+
const CONTAINER: string = 'e-container';
|
|
27
|
+
const CTRLBTN: string = 'e-ctrl-btn';
|
|
28
|
+
const CTRLSWITCH: string = 'e-switch-ctrl-btn';
|
|
29
|
+
const DISABLED: string = 'e-disabled';
|
|
30
|
+
const FORMATSWITCH: string = 'e-value-switch-btn';
|
|
31
|
+
const HANDLER: string = 'e-handler';
|
|
32
|
+
const HEX: string = 'e-hex';
|
|
33
|
+
const HIDEHEX: string = 'e-hide-hex-value';
|
|
34
|
+
const HIDEOPACITY: string = 'e-hide-opacity';
|
|
35
|
+
const HIDERGBA: string = 'e-hide-switchable-value';
|
|
36
|
+
const HIDEVALUE: string = 'e-hide-value';
|
|
37
|
+
const HIDEVALUESWITCH: string = 'e-hide-valueswitcher';
|
|
38
|
+
const HSVAREA: string = 'e-hsv-color';
|
|
39
|
+
const HSVCONTAINER: string = 'e-hsv-container';
|
|
40
|
+
const INPUTWRAPPER: string = 'e-selected-value';
|
|
41
|
+
const MODESWITCH: string = 'e-mode-switch-btn';
|
|
42
|
+
const NOCOLOR: string = 'e-nocolor-item';
|
|
43
|
+
const OPACITY: string = 'e-opacity-value';
|
|
44
|
+
const PALETTES: string = 'e-palette';
|
|
45
|
+
const PALETTECONTENT: string = 'e-color-palette';
|
|
46
|
+
const PICKERCONTENT: string = 'e-color-picker';
|
|
47
|
+
const PREVIEW: string = 'e-preview-container';
|
|
48
|
+
const PREVIOUS: string = 'e-previous';
|
|
49
|
+
const RTL: string = 'e-rtl';
|
|
50
|
+
const SHOWVALUE: string = 'e-show-value';
|
|
51
|
+
const SELECT: string = 'e-selected';
|
|
52
|
+
const SPLITPREVIEW: string = 'e-split-preview';
|
|
53
|
+
const TILE: string = 'e-tile';
|
|
54
|
+
|
|
55
|
+
const presets: { [key: string]: string[] } = {
|
|
56
|
+
default: ['#000000', '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#ffeb3b',
|
|
57
|
+
'#ffffff', '#ffebee', '#fce4ec', '#f3e5f5', '#ede7f6', '#e3f2fd', '#e1f5fe', '#e0f7fa', '#e0f2f1', '#fffde7',
|
|
58
|
+
'#f2f2f2', '#ffcdd2', '#f8bbd0', '#e1bee7', '#d1c4e9', '#bbdefb', '#b3e5fc', '#b2ebf2', '#b2dfdb', '#fff9c4',
|
|
59
|
+
'#e6e6e6', '#ef9a9a', '#f48fb1', '#ce93d8', '#b39ddb', '#90caf9', '#81d4fa', '#80deea', '#80cbc4', '#fff59d',
|
|
60
|
+
'#cccccc', '#e57373', '#f06292', '#ba68c8', '#9575cd', '#64b5f6', '#4fc3f7', '#4dd0e1', '#4db6ac', '#fff176',
|
|
61
|
+
'#b3b3b3', '#ef5350', '#ec407a', '#ab47bc', '#7e57c2', '#42a5f5', '#29b6f6', '#26c6da', '#26a69a', '#ffee58',
|
|
62
|
+
'#999999', '#e53935', '#d81b60', '#8e24aa', '#5e35b1', '#1e88e5', '#039be5', '#00acc1', '#00897b', '#fdd835',
|
|
63
|
+
'#808080', '#d32f2f', '#c2185b', '#7b1fa2', '#512da8', '#1976d2', '#0288d1', '#0097a7', '#00796b', '#fbc02d',
|
|
64
|
+
'#666666', '#c62828', '#ad1457', '#6a1b9a', '#4527a0', '#1565c0', '#0277bd', '#00838f', '#00695c', '#f9a825',
|
|
65
|
+
'#4d4d4d', '#b71c1c', '#880e4f', '#4a148c', '#311b92', '#0d47a1', '#01579b', '#006064', '#004d40', '#f57f17']
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* ColorPicker component is a user interface to select and adjust color values. It provides supports for various
|
|
70
|
+
* color specification like Red Green Blue, Hue Saturation Value and Hex codes.
|
|
71
|
+
* ```html
|
|
72
|
+
* <input type="color" id="color-picker">
|
|
73
|
+
* ```
|
|
74
|
+
* ```typescript
|
|
75
|
+
* <script>
|
|
76
|
+
* let colorPickerObj: ColorPicker = new ColorPicker(null , "#color-picker");
|
|
77
|
+
* </script>
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
@NotifyPropertyChanges
|
|
82
|
+
export class ColorPicker extends Component<HTMLInputElement> implements INotifyPropertyChanged {
|
|
83
|
+
/* Private variables */
|
|
84
|
+
private splitBtn: SplitButton;
|
|
85
|
+
private hueSlider: Slider;
|
|
86
|
+
private opacitySlider: Slider;
|
|
87
|
+
private tooltipEle: HTMLElement;
|
|
88
|
+
private container: HTMLElement;
|
|
89
|
+
private modal: HTMLElement;
|
|
90
|
+
private isRgb: boolean;
|
|
91
|
+
private l10n: L10n;
|
|
92
|
+
private tileRipple: Function;
|
|
93
|
+
private ctrlBtnRipple: Function;
|
|
94
|
+
private clientX: number;
|
|
95
|
+
private clientY: number;
|
|
96
|
+
private rgb: number[];
|
|
97
|
+
private hsv: number[];
|
|
98
|
+
private formElement: HTMLFormElement;
|
|
99
|
+
private initialInputValue: string;
|
|
100
|
+
private recentColors: string[] = [];
|
|
101
|
+
/**
|
|
102
|
+
* It is used to set the color value for ColorPicker. It should be specified as Hex code.
|
|
103
|
+
*
|
|
104
|
+
* @default '#008000ff'
|
|
105
|
+
*/
|
|
106
|
+
@Property('#008000ff')
|
|
107
|
+
public value: string;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* This property sets the CSS classes to root element of the ColorPicker
|
|
111
|
+
* which helps to customize the UI styles.
|
|
112
|
+
*
|
|
113
|
+
* @default ''
|
|
114
|
+
*/
|
|
115
|
+
@Property('')
|
|
116
|
+
public cssClass: string;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* It is used to enable / disable ColorPicker component. If it is disabled the ColorPicker popup won’t open.
|
|
120
|
+
*
|
|
121
|
+
* @default false
|
|
122
|
+
*/
|
|
123
|
+
@Property(false)
|
|
124
|
+
public disabled: boolean;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* It is used to render the ColorPicker with the specified mode.
|
|
128
|
+
*
|
|
129
|
+
* @default 'Picker'
|
|
130
|
+
*/
|
|
131
|
+
@Property('Picker')
|
|
132
|
+
public mode: ColorPickerMode;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* It is used to show / hide the mode switcher button of ColorPicker component.
|
|
136
|
+
*
|
|
137
|
+
* @default true
|
|
138
|
+
*/
|
|
139
|
+
@Property(true)
|
|
140
|
+
public modeSwitcher: boolean;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* It is used to load custom colors to palette.
|
|
144
|
+
*
|
|
145
|
+
* @default null
|
|
146
|
+
*/
|
|
147
|
+
@Property(null)
|
|
148
|
+
public presetColors: { [key: string]: string[] };
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* It is used to show / hide the control buttons (apply / cancel) of ColorPicker component.
|
|
152
|
+
*
|
|
153
|
+
* @default true
|
|
154
|
+
*/
|
|
155
|
+
@Property(true)
|
|
156
|
+
public showButtons: boolean;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* It is used to render the ColorPicker palette with specified columns.
|
|
160
|
+
*
|
|
161
|
+
* @default 10
|
|
162
|
+
*/
|
|
163
|
+
@Property(10)
|
|
164
|
+
public columns: number;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* It is used to render the ColorPicker component as inline.
|
|
168
|
+
*
|
|
169
|
+
* @default false
|
|
170
|
+
*/
|
|
171
|
+
@Property(false)
|
|
172
|
+
public inline: boolean;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* It is used to enable / disable the no color option of ColorPicker component.
|
|
176
|
+
*
|
|
177
|
+
* @default false
|
|
178
|
+
*/
|
|
179
|
+
@Property(false)
|
|
180
|
+
public noColor: boolean;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* To enable or disable persisting component's state between page reloads and it is extended from component class.
|
|
184
|
+
*
|
|
185
|
+
* @default false
|
|
186
|
+
*/
|
|
187
|
+
@Property(false)
|
|
188
|
+
public enablePersistence: boolean;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* It is used to enable / disable the opacity option of ColorPicker component.
|
|
192
|
+
*
|
|
193
|
+
* @default true
|
|
194
|
+
*/
|
|
195
|
+
@Property(true)
|
|
196
|
+
public enableOpacity: boolean;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Specifies the popup element creation on open.
|
|
200
|
+
*
|
|
201
|
+
* @default false
|
|
202
|
+
*/
|
|
203
|
+
@Property(false)
|
|
204
|
+
public createPopupOnClick: boolean;
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Specifies to show the recent color options in the color picker in the palate mode.
|
|
208
|
+
* It accepts boolean value to configure recent colors. The default value is false.
|
|
209
|
+
* If this property value is false, then the recent color user interface is not rendered in color picker component.
|
|
210
|
+
* This recent color option is rendered only in the palette mode.
|
|
211
|
+
*
|
|
212
|
+
* @default false
|
|
213
|
+
*/
|
|
214
|
+
@Property(false)
|
|
215
|
+
public showRecentColors: boolean;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Triggers while selecting the color in picker / palette, when showButtons property is enabled.
|
|
219
|
+
*
|
|
220
|
+
* @event select
|
|
221
|
+
* @blazorProperty 'Selected'
|
|
222
|
+
*/
|
|
223
|
+
@Event()
|
|
224
|
+
public select: EmitType<ColorPickerEventArgs>;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Triggers while changing the colors. It will be triggered based on the showButtons property.
|
|
228
|
+
* If the property is false, the event will be triggered while selecting the colors.
|
|
229
|
+
* If the property is true, the event will be triggered while apply the selected color.
|
|
230
|
+
*
|
|
231
|
+
* @event change
|
|
232
|
+
* @blazorProperty 'ValueChange'
|
|
233
|
+
*/
|
|
234
|
+
@Event()
|
|
235
|
+
public change: EmitType<ColorPickerEventArgs>;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Trigger while rendering each palette tile.
|
|
239
|
+
*
|
|
240
|
+
* @event beforeTileRender
|
|
241
|
+
* @blazorProperty 'OnTileRender'
|
|
242
|
+
*/
|
|
243
|
+
@Event()
|
|
244
|
+
public beforeTileRender: EmitType<PaletteTileEventArgs>;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Triggers before opening the ColorPicker popup.
|
|
248
|
+
*
|
|
249
|
+
* @event beforeOpen
|
|
250
|
+
* @blazorProperty 'OnOpen'
|
|
251
|
+
*/
|
|
252
|
+
@Event()
|
|
253
|
+
public beforeOpen: EmitType<BeforeOpenCloseEventArgs>;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Triggers while opening the ColorPicker popup.
|
|
257
|
+
*
|
|
258
|
+
* @event open
|
|
259
|
+
* @blazorProperty 'Opened'
|
|
260
|
+
*/
|
|
261
|
+
@Event()
|
|
262
|
+
public open: EmitType<OpenEventArgs>;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Triggers before closing the ColorPicker popup.
|
|
266
|
+
*
|
|
267
|
+
* @event beforeClose
|
|
268
|
+
* @blazorProperty 'OnClose'
|
|
269
|
+
*/
|
|
270
|
+
@Event()
|
|
271
|
+
public beforeClose: EmitType<BeforeOpenCloseEventArgs>;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Triggers before Switching between ColorPicker mode.
|
|
275
|
+
*
|
|
276
|
+
* @event beforeModeSwitch
|
|
277
|
+
* @blazorProperty 'OnModeSwitch'
|
|
278
|
+
*/
|
|
279
|
+
@Event()
|
|
280
|
+
public beforeModeSwitch: EmitType<ModeSwitchEventArgs>;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Triggers after Switching between ColorPicker mode.
|
|
284
|
+
*
|
|
285
|
+
* @event onModeSwitch
|
|
286
|
+
* @blazorProperty 'ModeSwitched'
|
|
287
|
+
*/
|
|
288
|
+
@Event()
|
|
289
|
+
public onModeSwitch: EmitType<ModeSwitchEventArgs>;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Triggers once the component rendering is completed.
|
|
293
|
+
*
|
|
294
|
+
* @event created
|
|
295
|
+
* @blazorProperty 'Created'
|
|
296
|
+
*/
|
|
297
|
+
@Event()
|
|
298
|
+
public created: EmitType<Event>;
|
|
299
|
+
|
|
300
|
+
constructor(options?: ColorPickerModel, element?: string | HTMLInputElement) {
|
|
301
|
+
super(options, <HTMLInputElement | string>element);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
protected preRender(): void {
|
|
305
|
+
const ele: Element = this.element;
|
|
306
|
+
this.formElement = <HTMLFormElement>closest(this.element, 'form');
|
|
307
|
+
if (this.formElement) {
|
|
308
|
+
EventHandler.add(this.formElement, 'reset', this.formResetHandler, this);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const localeText: object = { Apply: 'Apply', Cancel: 'Cancel', ModeSwitcher: 'Switch Mode', RecentColors: 'Recent colors' };
|
|
312
|
+
this.l10n = new L10n('colorpicker', localeText, this.locale);
|
|
313
|
+
if (ele.getAttribute('ejs-for') && !ele.getAttribute('name')) {
|
|
314
|
+
ele.setAttribute('name', ele.id);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* To Initialize the component rendering
|
|
320
|
+
*
|
|
321
|
+
* @private
|
|
322
|
+
* @returns {void}
|
|
323
|
+
*/
|
|
324
|
+
public render(): void {
|
|
325
|
+
this.initWrapper();
|
|
326
|
+
if (this.inline) {
|
|
327
|
+
this.createWidget();
|
|
328
|
+
} else {
|
|
329
|
+
this.createSplitBtn();
|
|
330
|
+
}
|
|
331
|
+
if (!this.enableOpacity) {
|
|
332
|
+
addClass([this.container.parentElement], HIDEOPACITY);
|
|
333
|
+
}
|
|
334
|
+
this.renderComplete();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
private initWrapper(): void {
|
|
338
|
+
const wrapper: HTMLElement = this.createElement('div', { className: 'e-' + this.getModuleName() + '-wrapper' });
|
|
339
|
+
this.element.parentNode.insertBefore(wrapper, this.element);
|
|
340
|
+
wrapper.appendChild(this.element);
|
|
341
|
+
attributes(this.element, { 'tabindex': '-1', 'spellcheck': 'false', 'aria-label': 'colorpicker' });
|
|
342
|
+
this.container = this.createElement('div', { className: CONTAINER });
|
|
343
|
+
this.getWrapper().appendChild(this.container);
|
|
344
|
+
let value: string = this.value ? this.roundValue(this.value).toLowerCase() : '#008000ff';
|
|
345
|
+
if (this.noColor && this.mode === 'Palette' && this.value === '') {
|
|
346
|
+
value = '';
|
|
347
|
+
}
|
|
348
|
+
const slicedValue: string = value.slice(0, 7);
|
|
349
|
+
if (isNullOrUndefined(this.initialInputValue)) {
|
|
350
|
+
this.initialInputValue = slicedValue;
|
|
351
|
+
}
|
|
352
|
+
this.element.value = slicedValue;
|
|
353
|
+
if (this.enableOpacity) {
|
|
354
|
+
this.setProperties({ 'value': value }, true);
|
|
355
|
+
} else {
|
|
356
|
+
this.setProperties({ 'value': slicedValue }, true);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (this.enableRtl) {
|
|
360
|
+
wrapper.classList.add(RTL);
|
|
361
|
+
}
|
|
362
|
+
if (this.cssClass) {
|
|
363
|
+
addClass([wrapper], this.cssClass.replace(/\s+/g, ' ').trim().split(' '));
|
|
364
|
+
}
|
|
365
|
+
this.tileRipple = rippleEffect(this.container, { selector: '.' + TILE });
|
|
366
|
+
this.ctrlBtnRipple = rippleEffect(this.container, { selector: '.e-btn' });
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private getWrapper(): HTMLElement {
|
|
370
|
+
return this.element.parentElement;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
private createWidget(): void {
|
|
374
|
+
if (this.mode === 'Palette') {
|
|
375
|
+
this.createPalette();
|
|
376
|
+
if (!this.inline) {
|
|
377
|
+
this.firstPaletteFocus();
|
|
378
|
+
}
|
|
379
|
+
} else {
|
|
380
|
+
this.createPicker();
|
|
381
|
+
if (!this.inline) {
|
|
382
|
+
this.getDragHandler().focus();
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
this.isRgb = true;
|
|
386
|
+
this.createInput();
|
|
387
|
+
this.createCtrlBtn();
|
|
388
|
+
if (!this.disabled) {
|
|
389
|
+
this.wireEvents();
|
|
390
|
+
}
|
|
391
|
+
if (this.inline && this.disabled) {
|
|
392
|
+
this.toggleDisabled(true);
|
|
393
|
+
}
|
|
394
|
+
if (Browser.isDevice) {
|
|
395
|
+
this.refreshPopupPos();
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
private createSplitBtn(): void {
|
|
400
|
+
const splitButton: HTMLButtonElement = this.createElement('button', { className: 'e-split-colorpicker' }) as HTMLButtonElement;
|
|
401
|
+
this.getWrapper().appendChild(splitButton);
|
|
402
|
+
this.splitBtn = new SplitButton(
|
|
403
|
+
{
|
|
404
|
+
iconCss: 'e-selected-color',
|
|
405
|
+
target: this.container,
|
|
406
|
+
disabled: this.disabled,
|
|
407
|
+
enableRtl: this.enableRtl,
|
|
408
|
+
createPopupOnClick: this.createPopupOnClick,
|
|
409
|
+
open: this.onOpen.bind(this),
|
|
410
|
+
click: () => {
|
|
411
|
+
const ev: MouseEvent = new MouseEvent('click', { bubbles: true, cancelable: false });
|
|
412
|
+
this.trigger('change', {
|
|
413
|
+
currentValue: { hex: this.value.slice(0, 7), rgba: this.convertToRgbString(this.hexToRgb(this.value)) },
|
|
414
|
+
previousValue: { hex: null, rgba: null }, value: this.value, event: ev
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
this.splitBtn.createElement = this.createElement;
|
|
419
|
+
this.splitBtn.appendTo(splitButton);
|
|
420
|
+
this.splitBtn.element.setAttribute('aria-label', 'colorpicker');
|
|
421
|
+
const preview: HTMLElement = this.createElement('span', { className: SPLITPREVIEW });
|
|
422
|
+
select('.e-selected-color', splitButton).appendChild(preview);
|
|
423
|
+
preview.style.backgroundColor = this.convertToRgbString(this.hexToRgb(this.value));
|
|
424
|
+
const popupEle: HTMLElement = this.getPopupEle();
|
|
425
|
+
addClass([popupEle], 'e-colorpicker-popup');
|
|
426
|
+
if (this.cssClass) {
|
|
427
|
+
const classes: string[] = this.cssClass.replace(/\s+/g, ' ').trim().split(' ');
|
|
428
|
+
if (popupEle) {
|
|
429
|
+
addClass([popupEle], classes);
|
|
430
|
+
}
|
|
431
|
+
if (this.splitBtn && this.splitBtn.activeElem && this.splitBtn.activeElem[0]) {
|
|
432
|
+
addClass([this.splitBtn.activeElem[0]], classes);
|
|
433
|
+
}
|
|
434
|
+
if (this.splitBtn && this.splitBtn.activeElem && this.splitBtn.activeElem[1]) {
|
|
435
|
+
addClass([this.splitBtn.activeElem[1]], classes);
|
|
436
|
+
}
|
|
437
|
+
if (this.splitBtn && this.splitBtn.element && this.splitBtn.element.parentElement) {
|
|
438
|
+
addClass([this.splitBtn.element.parentElement], classes);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (Browser.isDevice && !this.createPopupOnClick) {
|
|
442
|
+
const popupInst: Popup = this.getPopupInst();
|
|
443
|
+
popupInst.relateTo = document.body;
|
|
444
|
+
popupInst.position = { X: 'center', Y: 'center' };
|
|
445
|
+
popupInst.targetType = 'container';
|
|
446
|
+
popupInst.collision = { X: 'fit', Y: 'fit' };
|
|
447
|
+
popupInst.offsetY = 4;
|
|
448
|
+
popupEle.style.zIndex = getZindexPartial(this.splitBtn.element).toString();
|
|
449
|
+
}
|
|
450
|
+
this.bindCallBackEvent();
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
private onOpen(): void {
|
|
454
|
+
this.trigger('open', <OpenEventArgs>{ element: this.container });
|
|
455
|
+
if (!Browser.isDevice) {
|
|
456
|
+
const popupInst: Popup = this.getPopupInst();
|
|
457
|
+
const collision: string[] = isCollide(popupInst.element);
|
|
458
|
+
if (collision.length > 0) {
|
|
459
|
+
popupInst.collision = { X: 'flip', Y: 'fit' };
|
|
460
|
+
popupInst.position = { X: 'right', Y: 'bottom' };
|
|
461
|
+
popupInst.targetType = 'container';
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
private getPopupInst(): Popup {
|
|
467
|
+
return getInstance(this.getPopupEle(), Popup) as Popup;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
private bindCallBackEvent() : void {
|
|
471
|
+
this.splitBtn.beforeOpen = (args: BeforeOpenCloseMenuEventArgs): Deferred | void => {
|
|
472
|
+
const callBackPromise: Deferred = new Deferred();
|
|
473
|
+
this.trigger('beforeOpen', args, (observeOpenArgs: BeforeOpenCloseMenuEventArgs) => {
|
|
474
|
+
if (!observeOpenArgs.cancel) {
|
|
475
|
+
const popupEle: HTMLElement = this.getPopupEle();
|
|
476
|
+
popupEle.style.top = formatUnit(0 + pageYOffset);
|
|
477
|
+
popupEle.style.left = formatUnit(0 + pageXOffset);
|
|
478
|
+
popupEle.style.display = 'block';
|
|
479
|
+
this.createWidget();
|
|
480
|
+
popupEle.style.display = '';
|
|
481
|
+
if (Browser.isDevice) {
|
|
482
|
+
if (this.createPopupOnClick) {
|
|
483
|
+
const popupInst: Popup = this.getPopupInst();
|
|
484
|
+
popupInst.relateTo = document.body;
|
|
485
|
+
popupInst.position = { X: 'center', Y: 'center' };
|
|
486
|
+
popupInst.targetType = 'container';
|
|
487
|
+
popupInst.collision = { X: 'fit', Y: 'fit' };
|
|
488
|
+
popupInst.offsetY = 4;
|
|
489
|
+
popupEle.style.zIndex = getZindexPartial(this.splitBtn.element).toString();
|
|
490
|
+
}
|
|
491
|
+
this.modal = this.createElement('div');
|
|
492
|
+
this.modal.className = 'e-' + this.getModuleName() + ' e-modal';
|
|
493
|
+
this.modal.style.display = 'none';
|
|
494
|
+
document.body.insertBefore(this.modal, popupEle);
|
|
495
|
+
document.body.className += ' e-colorpicker-overflow';
|
|
496
|
+
this.modal.style.display = 'block';
|
|
497
|
+
this.modal.style.zIndex = (Number(popupEle.style.zIndex) - 1).toString();
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
args.cancel = observeOpenArgs.cancel;
|
|
501
|
+
callBackPromise.resolve(observeOpenArgs);
|
|
502
|
+
});
|
|
503
|
+
return callBackPromise;
|
|
504
|
+
};
|
|
505
|
+
this.splitBtn.beforeClose = (args: BeforeOpenCloseMenuEventArgs): Deferred | void => {
|
|
506
|
+
const callBackPromise: Deferred = new Deferred();
|
|
507
|
+
if (!isNullOrUndefined(args.event)) {
|
|
508
|
+
const beforeCloseArgs: BeforeOpenCloseEventArgs = { element: this.container, event: args.event, cancel: false };
|
|
509
|
+
this.trigger('beforeClose', beforeCloseArgs, (observedCloseArgs: BeforeOpenCloseMenuEventArgs) => {
|
|
510
|
+
if (Browser.isDevice && args.event.target === this.modal) {
|
|
511
|
+
observedCloseArgs.cancel = true;
|
|
512
|
+
}
|
|
513
|
+
if (!observedCloseArgs.cancel) {
|
|
514
|
+
this.onPopupClose();
|
|
515
|
+
if (args.event.type === 'keydown' && (args.event as KeyboardEvent).keyCode === 27) {
|
|
516
|
+
this.splitBtn.element.focus();
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
args.cancel = observedCloseArgs.cancel;
|
|
520
|
+
callBackPromise.resolve(observedCloseArgs);
|
|
521
|
+
});
|
|
522
|
+
} else {
|
|
523
|
+
callBackPromise.resolve(args);
|
|
524
|
+
}
|
|
525
|
+
return callBackPromise;
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
private onPopupClose(): void {
|
|
530
|
+
this.unWireEvents();
|
|
531
|
+
this.destroyOtherComp();
|
|
532
|
+
this.container.style.width = '';
|
|
533
|
+
(select('.' + SPLITPREVIEW, this.splitBtn.element) as HTMLElement).style.backgroundColor
|
|
534
|
+
= this.convertToRgbString(this.hexToRgb(this.value));
|
|
535
|
+
this.container.innerHTML = '';
|
|
536
|
+
removeClass([this.container], [PICKERCONTENT, PALETTECONTENT]);
|
|
537
|
+
if (Browser.isDevice && this.modal) {
|
|
538
|
+
removeClass([document.body], 'e-colorpicker-overflow');
|
|
539
|
+
this.modal.style.display = 'none';
|
|
540
|
+
this.modal.outerHTML = '';
|
|
541
|
+
this.modal = null;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
private createPalette(): void {
|
|
546
|
+
classList(this.container, [PALETTECONTENT], [PICKERCONTENT]);
|
|
547
|
+
if (this.presetColors) {
|
|
548
|
+
const paletteGroup: HTMLElement = this.createElement('div', { className: 'e-custom-palette' });
|
|
549
|
+
this.appendElement(paletteGroup);
|
|
550
|
+
const keys: string[] = Object.keys(this.presetColors as Object);
|
|
551
|
+
if (keys.length === 1) {
|
|
552
|
+
this.appendPalette(this.presetColors[keys[0]], keys[0], paletteGroup);
|
|
553
|
+
} else {
|
|
554
|
+
for (let i: number = 0, len: number = keys.length; i < len; i++) {
|
|
555
|
+
this.appendPalette(this.presetColors[keys[i as number]], keys[i as number], paletteGroup);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (selectAll('.e-row', paletteGroup).length > 10) {
|
|
559
|
+
addClass([paletteGroup], 'e-palette-group');
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
} else {
|
|
563
|
+
this.appendPalette(presets.default, 'default');
|
|
564
|
+
}
|
|
565
|
+
if (this.mode === 'Palette' && !this.modeSwitcher && this.noColor) {
|
|
566
|
+
this.setNoColor();
|
|
567
|
+
}
|
|
568
|
+
if (this.showRecentColors && this.recentColors && this.recentColors.length > 0) {
|
|
569
|
+
this.renderRecentColor();
|
|
570
|
+
}
|
|
571
|
+
const width: number = parseInt(getComputedStyle(this.container).borderBottomWidth, 10);
|
|
572
|
+
this.container.style.width = formatUnit((this.container.children[0] as HTMLElement).offsetWidth + width + width);
|
|
573
|
+
this.rgb = this.hexToRgb(this.roundValue(this.value));
|
|
574
|
+
this.hsv = this.rgbToHsv.apply(this, this.rgb);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
private renderRecentColor(): void {
|
|
578
|
+
const recentClrWpr: HTMLElement = this.container.querySelector('.e-clr-pal-rec-wpr');
|
|
579
|
+
if (recentClrWpr) { detach(recentClrWpr); }
|
|
580
|
+
const recentColorWrapper: HTMLElement = this.createElement('div', { className: 'e-clr-pal-rec-wpr' });
|
|
581
|
+
const refEle: HTMLElement = this.container.querySelector('.e-switch-ctrl-btn');
|
|
582
|
+
if (refEle) {
|
|
583
|
+
this.container.insertBefore(recentColorWrapper, refEle);
|
|
584
|
+
} else {
|
|
585
|
+
this.container.appendChild(recentColorWrapper);
|
|
586
|
+
}
|
|
587
|
+
const recentClrSpan: Element = this.createElement('label', { className: 'e-recent-clr-span' });
|
|
588
|
+
recentClrSpan.textContent = this.l10n.getConstant('RecentColors');
|
|
589
|
+
recentColorWrapper.appendChild(recentClrSpan);
|
|
590
|
+
if (this.recentColors.length > 0) {
|
|
591
|
+
this.recentColors = this.recentColors.filter((item: string, index: number) => this.recentColors.indexOf(item) === index);
|
|
592
|
+
while (this.recentColors.length > 10) {
|
|
593
|
+
this.recentColors.pop();
|
|
594
|
+
}
|
|
595
|
+
this.appendPalette(this.recentColors, 'recent-color', recentColorWrapper);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
private firstPaletteFocus(): void {
|
|
600
|
+
if (!select('.' + SELECT, this.container.children[0])) {
|
|
601
|
+
selectAll('.' + PALETTES, this.container)[0].focus();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
private appendPalette(colors: string[], key: string, refEle?: HTMLElement): void {
|
|
606
|
+
const palette: HTMLElement = this.createElement('div', { className: PALETTES, attrs: { 'tabindex': '0', 'role': 'grid' } });
|
|
607
|
+
if (key === 'recent-color') { palette.classList.add('e-recent-palette'); }
|
|
608
|
+
if (refEle) {
|
|
609
|
+
refEle.appendChild(palette);
|
|
610
|
+
} else {
|
|
611
|
+
this.appendElement(palette);
|
|
612
|
+
}
|
|
613
|
+
let row: HTMLElement; let tile: HTMLElement; let roundedColor: string;
|
|
614
|
+
for (let i: number = 0, len: number = colors.length; i < len; i++) {
|
|
615
|
+
if (i === 0 || i % this.columns === 0) {
|
|
616
|
+
row = this.createElement('div', {
|
|
617
|
+
className: 'e-row', attrs: { 'role': 'row' }
|
|
618
|
+
});
|
|
619
|
+
palette.appendChild(row);
|
|
620
|
+
}
|
|
621
|
+
roundedColor = this.roundValue(colors[i as number]).toLowerCase();
|
|
622
|
+
tile = this.createElement('span', {
|
|
623
|
+
className: TILE, attrs: { 'role': 'gridcell', 'aria-label': roundedColor, 'aria-selected': 'false' }
|
|
624
|
+
});
|
|
625
|
+
this.trigger('beforeTileRender', <PaletteTileEventArgs>{ element: tile, presetName: key, value: colors[i as number] });
|
|
626
|
+
row.appendChild(tile);
|
|
627
|
+
if (this.value === roundedColor && key !== 'recent-color') {
|
|
628
|
+
this.addTileSelection(tile);
|
|
629
|
+
palette.focus();
|
|
630
|
+
}
|
|
631
|
+
tile.style.backgroundColor = this.convertToRgbString(this.hexToRgb(roundedColor));
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
private setNoColor(): void {
|
|
636
|
+
const noColorEle: HTMLElement = this.container.querySelector('.e-row').children[0] as HTMLElement;
|
|
637
|
+
noColorEle.classList.add(NOCOLOR);
|
|
638
|
+
if (!this.value) {
|
|
639
|
+
noColorEle.classList.add(SELECT);
|
|
640
|
+
(closest(noColorEle, '.' + PALETTES) as HTMLElement).focus();
|
|
641
|
+
}
|
|
642
|
+
['aria-selected', 'aria-label'].forEach((attr: string): void => { noColorEle.removeAttribute(attr); });
|
|
643
|
+
noColorEle.style.backgroundColor = '';
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
private appendElement(ele: Element, insertPos: number = 0): void {
|
|
647
|
+
const refEle: Element = this.container.children[insertPos as number];
|
|
648
|
+
if (refEle) {
|
|
649
|
+
this.container.insertBefore(ele, refEle);
|
|
650
|
+
} else {
|
|
651
|
+
this.container.appendChild(ele);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
private addTileSelection(ele: Element): void {
|
|
656
|
+
if (ele) {
|
|
657
|
+
ele.classList.add(SELECT);
|
|
658
|
+
ele.setAttribute('aria-selected', 'true');
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
private createPicker(): void {
|
|
663
|
+
classList(this.container, [PICKERCONTENT], [PALETTECONTENT]);
|
|
664
|
+
const hsvContainer: HTMLElement = this.createElement('div', { className: HSVCONTAINER });
|
|
665
|
+
this.appendElement(hsvContainer);
|
|
666
|
+
hsvContainer.appendChild(this.createElement('div', { className: HSVAREA }));
|
|
667
|
+
const dragHandler: HTMLElement = this.createElement('span', { className: HANDLER, attrs: { 'tabindex': '0' } });
|
|
668
|
+
hsvContainer.appendChild(dragHandler);
|
|
669
|
+
if (this.value === null || this.value === '') {
|
|
670
|
+
this.value = '#008000ff';
|
|
671
|
+
}
|
|
672
|
+
this.rgb = this.hexToRgb(this.value);
|
|
673
|
+
this.hsv = this.rgbToHsv.apply(this, this.rgb);
|
|
674
|
+
this.setHsvContainerBg();
|
|
675
|
+
this.setHandlerPosition();
|
|
676
|
+
this.createSlider();
|
|
677
|
+
this.createDragTooltip();
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
private setHsvContainerBg(h: number = this.hsv[0]): void {
|
|
681
|
+
this.getHsvContainer().style.backgroundColor = this.convertToRgbString(this.hsvToRgb(h, 100, 100, 1));
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
private getHsvContainer(): HTMLElement {
|
|
685
|
+
return select('.' + HSVCONTAINER, this.container) as HTMLElement;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
private setHandlerPosition(): void {
|
|
689
|
+
const dragHandler: HTMLElement = this.getDragHandler();
|
|
690
|
+
const hsvArea: HTMLElement = select('.' + HSVAREA, this.container) as HTMLElement;
|
|
691
|
+
if (this.enableRtl) {
|
|
692
|
+
dragHandler.style.left = formatUnit((hsvArea.offsetWidth - dragHandler.offsetWidth / 2.5) * Math.abs(100 - this.hsv[1]) / 100);
|
|
693
|
+
} else {
|
|
694
|
+
dragHandler.style.left = formatUnit((hsvArea.offsetWidth - dragHandler.offsetWidth / 2.5) * this.hsv[1] / 100);
|
|
695
|
+
}
|
|
696
|
+
dragHandler.style.top = formatUnit((hsvArea.offsetHeight - dragHandler.offsetHeight / 2.5) * (100 - this.hsv[2]) / 100);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
private createSlider(): void {
|
|
700
|
+
const sliderPreviewWrapper: Element = this.createElement('div', { className: 'e-slider-preview' });
|
|
701
|
+
this.appendElement(sliderPreviewWrapper, 1);
|
|
702
|
+
this.createPreview(sliderPreviewWrapper);
|
|
703
|
+
const sliderWrapper: Element = this.createElement('div', { className: 'e-colorpicker-slider' });
|
|
704
|
+
sliderPreviewWrapper.insertBefore(sliderWrapper, sliderPreviewWrapper.children[0]);
|
|
705
|
+
let slider: HTMLElement = this.createElement('div', { className: 'e-hue-slider' });
|
|
706
|
+
sliderWrapper.appendChild(slider);
|
|
707
|
+
this.hueSlider = new Slider(
|
|
708
|
+
{
|
|
709
|
+
value: this.hsv[0],
|
|
710
|
+
min: 0,
|
|
711
|
+
max: 359,
|
|
712
|
+
enableRtl: this.enableRtl,
|
|
713
|
+
enabled: !this.disabled,
|
|
714
|
+
change: this.hueChange.bind(this)
|
|
715
|
+
});
|
|
716
|
+
this.hueSlider.createElement = this.createElement;
|
|
717
|
+
this.hueSlider.appendTo(slider);
|
|
718
|
+
if (this.enableOpacity) {
|
|
719
|
+
slider = this.createElement('div', { className: 'e-opacity-slider' });
|
|
720
|
+
sliderWrapper.appendChild(slider);
|
|
721
|
+
this.createOpacitySlider(slider);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
private createOpacitySlider(slider: HTMLElement): void {
|
|
726
|
+
this.opacitySlider = new Slider(
|
|
727
|
+
{
|
|
728
|
+
value: this.rgb[3] * 100,
|
|
729
|
+
min: 0,
|
|
730
|
+
max: 100,
|
|
731
|
+
enableRtl: this.enableRtl,
|
|
732
|
+
enabled: !this.disabled,
|
|
733
|
+
change: this.opacityChange.bind(this)
|
|
734
|
+
});
|
|
735
|
+
this.opacitySlider.createElement = this.createElement;
|
|
736
|
+
this.opacitySlider.appendTo(slider);
|
|
737
|
+
const opacityBgTrack: HTMLElement = this.createElement('div', { className: 'e-opacity-empty-track' });
|
|
738
|
+
slider.appendChild(opacityBgTrack);
|
|
739
|
+
this.updateOpacitySliderBg();
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
private updateOpacitySliderBg(): void {
|
|
743
|
+
const direction: string = this.enableRtl ? 'to left' : 'to right';
|
|
744
|
+
const opacityEle: HTMLElement = select('.e-opacity-empty-track', this.opacitySlider.element) as HTMLElement;
|
|
745
|
+
if (opacityEle) {
|
|
746
|
+
opacityEle.style.background =
|
|
747
|
+
'linear-gradient(' + direction + ', rgba(' + this.rgb.slice(0, 3) + ', 0) 0%, ' +
|
|
748
|
+
this.convertToRgbString(this.rgb.slice(0, 3)) + ' 100%)';
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
private hueChange(args: SliderChangeEventArgs): void {
|
|
753
|
+
this.hsv[0] = args.value as number;
|
|
754
|
+
this.setHsvContainerBg();
|
|
755
|
+
this.convertToOtherFormat();
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
private opacityChange(args: SliderChangeEventArgs): void {
|
|
759
|
+
const value: number = args.value as number;
|
|
760
|
+
const pValue: string = this.rgbToHex(this.rgb);
|
|
761
|
+
this.hsv[3] = value / 100; this.rgb[3] = value / 100;
|
|
762
|
+
const cValue: string = this.rgbToHex(this.rgb);
|
|
763
|
+
this.updateOpacityInput(value);
|
|
764
|
+
const rgb: string = this.convertToRgbString(this.rgb);
|
|
765
|
+
this.updatePreview(rgb);
|
|
766
|
+
this.triggerEvent(cValue, pValue, rgb);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
private updateOpacityInput(value: number): void {
|
|
770
|
+
if (this.enableOpacity && !this.getWrapper().classList.contains(HIDEVALUE)) {
|
|
771
|
+
const opacityTextBoxInst: NumericTextBox = getInstance(
|
|
772
|
+
select('.' + OPACITY, this.container) as HTMLInputElement, NumericTextBox) as NumericTextBox;
|
|
773
|
+
opacityTextBoxInst.value = value; opacityTextBoxInst.dataBind();
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
private createPreview(parentEle?: Element): void {
|
|
778
|
+
const previewContainer: HTMLElement = this.createElement('div', { className: PREVIEW });
|
|
779
|
+
parentEle.appendChild(previewContainer);
|
|
780
|
+
let preview: HTMLElement = this.createElement('span', { className: 'e-preview ' + CURRENT });
|
|
781
|
+
previewContainer.appendChild(preview);
|
|
782
|
+
const colorValue: string = this.convertToRgbString(this.rgb);
|
|
783
|
+
preview.style.backgroundColor = colorValue;
|
|
784
|
+
preview = this.createElement('span', { className: 'e-preview ' + PREVIOUS });
|
|
785
|
+
previewContainer.appendChild(preview);
|
|
786
|
+
preview.style.backgroundColor = colorValue;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
private isPicker(): boolean {
|
|
790
|
+
return !this.container.classList.contains(PALETTECONTENT);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
private getPopupEle(): HTMLElement {
|
|
794
|
+
return this.container.parentElement;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
private createNumericInput(element: HTMLElement, value: number, label: string, max: number): void {
|
|
798
|
+
const numericInput: NumericTextBox = new NumericTextBox(<NumericTextBoxModel>{
|
|
799
|
+
value: value,
|
|
800
|
+
placeholder: label,
|
|
801
|
+
min: 0,
|
|
802
|
+
max: max,
|
|
803
|
+
format: '###.##',
|
|
804
|
+
showSpinButton: false,
|
|
805
|
+
floatLabelType: 'Always',
|
|
806
|
+
enableRtl: this.enableRtl,
|
|
807
|
+
enabled: !this.disabled,
|
|
808
|
+
readonly: this.isPicker() ? false : true,
|
|
809
|
+
change: (args: ChangeEventArgs) => {
|
|
810
|
+
if (args.event) {
|
|
811
|
+
this.inputHandler(args.event);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
numericInput.createElement = this.createElement;
|
|
816
|
+
numericInput.appendTo(element as HTMLInputElement);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
private createInput(): void {
|
|
820
|
+
const isPicker: boolean = this.isPicker();
|
|
821
|
+
const wrapper: HTMLElement = this.getWrapper();
|
|
822
|
+
if ((isPicker && !wrapper.classList.contains(HIDEVALUE)) || (!isPicker && wrapper.classList.contains(SHOWVALUE))) {
|
|
823
|
+
const inputWrap: HTMLElement = this.createElement('div', { className: INPUTWRAPPER });
|
|
824
|
+
if (isPicker) {
|
|
825
|
+
this.appendElement(inputWrap, 2);
|
|
826
|
+
} else {
|
|
827
|
+
this.appendElement(inputWrap, 1);
|
|
828
|
+
}
|
|
829
|
+
const container: HTMLElement = this.createElement('div', { className: 'e-input-container' });
|
|
830
|
+
inputWrap.appendChild(container);
|
|
831
|
+
if (!wrapper.classList.contains(HIDEVALUESWITCH)) {
|
|
832
|
+
this.appendValueSwitchBtn(inputWrap);
|
|
833
|
+
}
|
|
834
|
+
if (!wrapper.classList.contains(HIDEHEX)) {
|
|
835
|
+
const hexInput: HTMLInputElement = this.createElement('input', {
|
|
836
|
+
className: HEX,
|
|
837
|
+
attrs: { 'maxlength': '7', 'spellcheck': 'false', 'aria-label': 'HEX' }
|
|
838
|
+
}) as HTMLInputElement;
|
|
839
|
+
container.appendChild(hexInput);
|
|
840
|
+
Input.createInput(
|
|
841
|
+
{
|
|
842
|
+
element: hexInput,
|
|
843
|
+
floatLabelType: 'Always',
|
|
844
|
+
properties: {
|
|
845
|
+
placeholder: 'HEX',
|
|
846
|
+
enableRtl: this.enableRtl,
|
|
847
|
+
enabled: !this.disabled,
|
|
848
|
+
readonly: this.isPicker() ? false : true
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
this.createElement);
|
|
852
|
+
Input.setValue(this.value.slice(0, 7), hexInput);
|
|
853
|
+
hexInput.addEventListener('input', this.inputHandler.bind(this));
|
|
854
|
+
}
|
|
855
|
+
if (!wrapper.classList.contains(HIDERGBA)) {
|
|
856
|
+
let label: string;
|
|
857
|
+
let value: number[];
|
|
858
|
+
if (this.isRgb) {
|
|
859
|
+
label = 'RGB';
|
|
860
|
+
value = this.rgb;
|
|
861
|
+
} else {
|
|
862
|
+
label = 'HSV';
|
|
863
|
+
value = this.hsv;
|
|
864
|
+
}
|
|
865
|
+
const clsName: string[] = ['rh', 'gs', 'bv'];
|
|
866
|
+
for (let i: number = 0; i < 3; i++) {
|
|
867
|
+
this.createNumericInput(
|
|
868
|
+
container.appendChild(this.createElement('input', { className: 'e-' + clsName[i as number] + '-value' })),
|
|
869
|
+
value[i as number], label[i as number], 255);
|
|
870
|
+
}
|
|
871
|
+
if (this.enableOpacity) {
|
|
872
|
+
this.appendOpacityValue(container);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
private appendOpacityValue(container: HTMLElement): void {
|
|
879
|
+
this.createNumericInput(
|
|
880
|
+
container.appendChild(this.createElement('input', { className: OPACITY })), this.rgb[3] * 100, 'A', 100);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
private appendValueSwitchBtn(targetEle: Element): void {
|
|
884
|
+
const valueSwitchBtn: HTMLElement = this.createElement('button', {
|
|
885
|
+
className: 'e-icons e-css e-btn e-flat e-icon-btn ' + FORMATSWITCH,
|
|
886
|
+
attrs: { 'title': 'Toggle format' }
|
|
887
|
+
});
|
|
888
|
+
targetEle.appendChild(valueSwitchBtn);
|
|
889
|
+
if (this.isPicker() && !this.getWrapper().classList.contains(HIDERGBA)) {
|
|
890
|
+
valueSwitchBtn.addEventListener('click', this.formatSwitchHandler.bind(this));
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
private createCtrlBtn(): void {
|
|
895
|
+
if (this.modeSwitcher || this.showButtons) {
|
|
896
|
+
this.l10n.setLocale(this.locale);
|
|
897
|
+
const btnWrapper: Element = this.createElement('div', { className: CTRLSWITCH });
|
|
898
|
+
this.container.appendChild(btnWrapper);
|
|
899
|
+
if (this.showButtons) {
|
|
900
|
+
const controlBtnWrapper: Element = this.createElement('div', { className: CTRLBTN });
|
|
901
|
+
btnWrapper.appendChild(controlBtnWrapper);
|
|
902
|
+
const apply: string = this.l10n.getConstant('Apply');
|
|
903
|
+
controlBtnWrapper.appendChild(this.createElement('button', {
|
|
904
|
+
innerHTML: apply,
|
|
905
|
+
className: 'e-btn e-css e-flat e-primary e-small ' + APPLY,
|
|
906
|
+
attrs: { 'title': apply }
|
|
907
|
+
}));
|
|
908
|
+
const cancel: string = this.l10n.getConstant('Cancel');
|
|
909
|
+
controlBtnWrapper.appendChild(this.createElement('button', {
|
|
910
|
+
innerHTML: cancel,
|
|
911
|
+
className: 'e-btn e-css e-flat e-small ' + CANCEL,
|
|
912
|
+
attrs: { 'title': cancel }
|
|
913
|
+
}));
|
|
914
|
+
}
|
|
915
|
+
if (this.modeSwitcher) {
|
|
916
|
+
this.appendModeSwitchBtn();
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
private appendModeSwitchBtn(): void {
|
|
922
|
+
const modeSwitcher: HTMLElement = this.createElement('button', {
|
|
923
|
+
className: 'e-icons e-btn e-flat e-icon-btn ' + MODESWITCH, attrs: { title: this.l10n.getConstant('ModeSwitcher') }
|
|
924
|
+
});
|
|
925
|
+
select('.' + CTRLSWITCH, this.container).insertBefore(modeSwitcher, select('.' + CTRLBTN, this.container));
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
private createDragTooltip(): void {
|
|
929
|
+
const tooltip: Tooltip = new Tooltip({
|
|
930
|
+
opensOn: 'Custom',
|
|
931
|
+
showTipPointer: false,
|
|
932
|
+
cssClass: 'e-color-picker-tooltip',
|
|
933
|
+
htmlAttributes: {title: 'tooltip'},
|
|
934
|
+
beforeOpen: (args: TooltipEventArgs) => {
|
|
935
|
+
this.tooltipEle = args.element;
|
|
936
|
+
},
|
|
937
|
+
animation: { open: { effect: 'None' }, close: { effect: 'None' } }
|
|
938
|
+
});
|
|
939
|
+
tooltip.createElement = this.createElement;
|
|
940
|
+
tooltip.appendTo(this.container);
|
|
941
|
+
tooltip.open(this.container);
|
|
942
|
+
this.tooltipEle.style.zIndex = getZindexPartial(this.tooltipEle).toString();
|
|
943
|
+
this.tooltipEle.setAttribute('aria-label', 'colorpicker-tooltip');
|
|
944
|
+
select('.e-tip-content', this.tooltipEle).appendChild(this.createElement('div', { className: 'e-tip-transparent' }));
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
private getTooltipInst(): Tooltip {
|
|
948
|
+
return getInstance(this.container, Tooltip) as Tooltip;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
private setTooltipOffset(value: number): void {
|
|
952
|
+
this.getTooltipInst().offsetY = value;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
private toggleDisabled(enable: boolean): void {
|
|
956
|
+
if (enable) {
|
|
957
|
+
this.getWrapper().classList.add(DISABLED);
|
|
958
|
+
} else {
|
|
959
|
+
this.getWrapper().classList.remove(DISABLED);
|
|
960
|
+
}
|
|
961
|
+
if (this.showButtons) {
|
|
962
|
+
([].slice.call(selectAll('.e-btn', this.container))).forEach((ele: HTMLElement) => {
|
|
963
|
+
if (enable) {
|
|
964
|
+
attributes(ele, { 'disabled': '' });
|
|
965
|
+
} else {
|
|
966
|
+
ele.removeAttribute('disabled');
|
|
967
|
+
}
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
private convertToRgbString(rgb: number[]): string {
|
|
973
|
+
return rgb.length ? rgb.length === 4 ? 'rgba(' + rgb.join() + ')' : 'rgb(' + rgb.join() + ')' : '';
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
private convertToHsvString(hsv: number[]): string {
|
|
977
|
+
return hsv.length === 4 ? 'hsva(' + hsv.join() + ')' : 'hsv(' + hsv.join() + ')';
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
private updateHsv(): void {
|
|
981
|
+
this.hsv[1] = this.hsv[1] > 100 ? 100 : this.hsv[1];
|
|
982
|
+
this.hsv[2] = this.hsv[2] > 100 ? 100 : this.hsv[2];
|
|
983
|
+
this.setHandlerPosition();
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
private convertToOtherFormat(isKey: boolean = false, e?: MouseEvent | Event): void {
|
|
987
|
+
const pValue: string = this.rgbToHex(this.rgb);
|
|
988
|
+
this.rgb = this.hsvToRgb.apply(this, this.hsv);
|
|
989
|
+
const cValue: string = this.rgbToHex(this.rgb);
|
|
990
|
+
const rgba: string = this.convertToRgbString(this.rgb);
|
|
991
|
+
this.updatePreview(rgba);
|
|
992
|
+
this.updateInput(cValue);
|
|
993
|
+
this.triggerEvent(cValue, pValue, rgba, isKey, e);
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
private updateInput(value: string): void {
|
|
997
|
+
const wrapper: HTMLElement = this.getWrapper();
|
|
998
|
+
if (!wrapper.classList.contains(HIDEVALUE)) {
|
|
999
|
+
if (!wrapper.classList.contains(HIDEHEX)) {
|
|
1000
|
+
Input.setValue(value.substr(0, 7), select('.' + HEX, this.container) as HTMLInputElement);
|
|
1001
|
+
}
|
|
1002
|
+
if (!wrapper.classList.contains(HIDERGBA)) {
|
|
1003
|
+
if (this.isRgb) {
|
|
1004
|
+
this.updateValue(this.rgb, false);
|
|
1005
|
+
} else {
|
|
1006
|
+
this.updateValue(this.hsv, false);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
private updatePreview(value: string): void {
|
|
1013
|
+
if (this.enableOpacity) {
|
|
1014
|
+
this.updateOpacitySliderBg();
|
|
1015
|
+
}
|
|
1016
|
+
(select('.e-tip-transparent', this.tooltipEle) as HTMLElement).style.backgroundColor = value;
|
|
1017
|
+
(select('.' + PREVIEW + ' .' + CURRENT, this.container) as HTMLElement).style.backgroundColor = value;
|
|
1018
|
+
(select('.' + PREVIEW + ' .' + PREVIOUS, this.container) as HTMLElement).style.backgroundColor
|
|
1019
|
+
= this.convertToRgbString(this.hexToRgb(this.value));
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
private getDragHandler(): HTMLElement {
|
|
1023
|
+
return select('.' + HANDLER, this.container) as HTMLElement;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
private removeTileSelection(): void {
|
|
1027
|
+
const selectedEle: Element[] = [].slice.call(selectAll('.' + SELECT, this.container));
|
|
1028
|
+
selectedEle.forEach((ele: Element): void => {
|
|
1029
|
+
ele.classList.remove(SELECT);
|
|
1030
|
+
ele.setAttribute('aria-selected', 'false');
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
private convertRgbToNumberArray(value: string): number[] {
|
|
1035
|
+
return (value.slice(value.indexOf('(') + 1, value.indexOf(')'))).split(',').map(
|
|
1036
|
+
(n: string, i: number) => {
|
|
1037
|
+
return (i !== 3) ? parseInt(n, 10) : parseFloat(n);
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
/**
|
|
1042
|
+
* To get color value in specified type.
|
|
1043
|
+
*
|
|
1044
|
+
* @param {string} value - Specify the color value.
|
|
1045
|
+
* @param {string} type - Specify the type to which the specified color needs to be converted.
|
|
1046
|
+
* @method getValue
|
|
1047
|
+
* @returns {string} - Color value
|
|
1048
|
+
*/
|
|
1049
|
+
public getValue(value?: string, type?: string): string {
|
|
1050
|
+
if (!value) { value = this.value; }
|
|
1051
|
+
type = !type ? 'hex' : type.toLowerCase();
|
|
1052
|
+
if (value[0] === 'r') {
|
|
1053
|
+
const cValue: number[] = this.convertRgbToNumberArray(value);
|
|
1054
|
+
if (type === 'hex' || type === 'hexa') {
|
|
1055
|
+
const hex: string = this.rgbToHex(cValue);
|
|
1056
|
+
return type === 'hex' ? hex.slice(0, 7) : hex;
|
|
1057
|
+
} else {
|
|
1058
|
+
if (type === 'hsv') {
|
|
1059
|
+
return this.convertToHsvString(this.rgbToHsv.apply(this, cValue.slice(0, 3)));
|
|
1060
|
+
} else {
|
|
1061
|
+
if (type === 'hsva') {
|
|
1062
|
+
return this.convertToHsvString(this.rgbToHsv.apply(this, cValue));
|
|
1063
|
+
} else {
|
|
1064
|
+
return 'null';
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
} else {
|
|
1069
|
+
if (value[0] === 'h') {
|
|
1070
|
+
const cValue: number[] = this.hsvToRgb.apply(this, this.convertRgbToNumberArray(value));
|
|
1071
|
+
if (type === 'rgba') {
|
|
1072
|
+
return this.convertToRgbString(cValue);
|
|
1073
|
+
} else {
|
|
1074
|
+
if (type === 'hex' || type === 'hexa') {
|
|
1075
|
+
const hex: string = this.rgbToHex(cValue);
|
|
1076
|
+
return type === 'hex' ? hex.slice(0, 7) : hex;
|
|
1077
|
+
} else {
|
|
1078
|
+
if (type === 'rgb') {
|
|
1079
|
+
return this.convertToRgbString(cValue.slice(0, 3));
|
|
1080
|
+
} else {
|
|
1081
|
+
return 'null';
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
} else {
|
|
1086
|
+
value = this.roundValue(value);
|
|
1087
|
+
let rgb: number[] = this.hexToRgb(value);
|
|
1088
|
+
if (type === 'rgb' || type === 'hsv') {
|
|
1089
|
+
rgb = rgb.slice(0, 3);
|
|
1090
|
+
}
|
|
1091
|
+
if (type === 'rgba' || type === 'rgb') {
|
|
1092
|
+
return this.convertToRgbString(rgb);
|
|
1093
|
+
} else {
|
|
1094
|
+
if (type === 'hsva' || type === 'hsv') {
|
|
1095
|
+
return this.convertToHsvString(this.rgbToHsv.apply(this, rgb));
|
|
1096
|
+
} else {
|
|
1097
|
+
if (type === 'hex') {
|
|
1098
|
+
return value.slice(0, 7);
|
|
1099
|
+
} else {
|
|
1100
|
+
if (type === 'a') {
|
|
1101
|
+
return rgb[3].toString();
|
|
1102
|
+
} else {
|
|
1103
|
+
return 'null';
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* To show/hide ColorPicker popup based on current state of the SplitButton.
|
|
1114
|
+
*
|
|
1115
|
+
* @method toggle
|
|
1116
|
+
* @returns {void}
|
|
1117
|
+
*/
|
|
1118
|
+
public toggle(): void {
|
|
1119
|
+
if (this.container.parentElement.classList.contains('e-popup-close')) {
|
|
1120
|
+
this.splitBtn.toggle();
|
|
1121
|
+
} else {
|
|
1122
|
+
this.closePopup(null);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* Get component name.
|
|
1128
|
+
*
|
|
1129
|
+
* @returns {string} - Module Name
|
|
1130
|
+
* @private
|
|
1131
|
+
*/
|
|
1132
|
+
public getModuleName(): string {
|
|
1133
|
+
return 'colorpicker';
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* Gets the properties to be maintained in the persisted state.
|
|
1138
|
+
*
|
|
1139
|
+
* @returns {string} - Persist data
|
|
1140
|
+
*/
|
|
1141
|
+
public getPersistData(): string {
|
|
1142
|
+
return this.addOnPersist(['value']);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
protected wireEvents(): void {
|
|
1146
|
+
if (this.isPicker()) {
|
|
1147
|
+
const dragHandler: HTMLElement = this.getDragHandler();
|
|
1148
|
+
EventHandler.add(dragHandler, 'keydown', this.pickerKeyDown, this);
|
|
1149
|
+
const ctrlBtn: HTMLElement = select('.' + CTRLBTN, this.container) as HTMLElement;
|
|
1150
|
+
if (ctrlBtn) {
|
|
1151
|
+
EventHandler.add(ctrlBtn, 'keydown', this.ctrlBtnKeyDown, this);
|
|
1152
|
+
}
|
|
1153
|
+
EventHandler.add(this.getHsvContainer(), 'mousedown touchstart', this.handlerDown, this);
|
|
1154
|
+
if (this.modeSwitcher || this.showButtons) {
|
|
1155
|
+
this.addCtrlSwitchEvent();
|
|
1156
|
+
}
|
|
1157
|
+
EventHandler.add(select('.' + PREVIOUS, this.container), 'click', this.previewHandler, this);
|
|
1158
|
+
} else {
|
|
1159
|
+
EventHandler.add(this.container, 'click', this.paletteClickHandler, this);
|
|
1160
|
+
EventHandler.add(this.container, 'keydown', this.paletteKeyDown, this);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
private formResetHandler(): void {
|
|
1165
|
+
this.value = this.initialInputValue;
|
|
1166
|
+
attributes(this.element, { 'value' : this.initialInputValue });
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
private addCtrlSwitchEvent(): void {
|
|
1170
|
+
const ctrlSwitchBtn: Element = select('.' + CTRLSWITCH, this.container);
|
|
1171
|
+
if (ctrlSwitchBtn) { EventHandler.add(ctrlSwitchBtn, 'click', this.btnClickHandler, this); }
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
private ctrlBtnKeyDown(e: KeyboardEvent): void {
|
|
1175
|
+
if (e.keyCode === 13) {
|
|
1176
|
+
const applyBtn: HTMLElement = select('.' + APPLY, this.container) as HTMLElement;
|
|
1177
|
+
if (applyBtn) {
|
|
1178
|
+
const cValue: string = this.rgbToHex(this.rgb);
|
|
1179
|
+
this.triggerChangeEvent(cValue);
|
|
1180
|
+
}
|
|
1181
|
+
this.splitBtn.element.focus();
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
private pickerKeyDown(e: KeyboardEvent): void {
|
|
1186
|
+
switch (e.keyCode) {
|
|
1187
|
+
case 39:
|
|
1188
|
+
this.handlerDragPosition(1, this.enableRtl ? -1 : 1, e);
|
|
1189
|
+
break;
|
|
1190
|
+
case 37:
|
|
1191
|
+
this.handlerDragPosition(1, this.enableRtl ? 1 : -1, e);
|
|
1192
|
+
break;
|
|
1193
|
+
case 38:
|
|
1194
|
+
this.handlerDragPosition(2, 1, e);
|
|
1195
|
+
break;
|
|
1196
|
+
case 40:
|
|
1197
|
+
this.handlerDragPosition(2, -1, e);
|
|
1198
|
+
break;
|
|
1199
|
+
case 13: {
|
|
1200
|
+
e.preventDefault();
|
|
1201
|
+
const cValue: string = this.rgbToHex(this.rgb);
|
|
1202
|
+
this.enterKeyHandler(cValue);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
private enterKeyHandler(value: string): void {
|
|
1208
|
+
this.triggerChangeEvent(value);
|
|
1209
|
+
if (!this.inline) {
|
|
1210
|
+
this.splitBtn.element.focus();
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
private closePopup(e: MouseEvent | KeyboardEvent): void {
|
|
1215
|
+
const beforeCloseArgs: BeforeOpenCloseEventArgs = { element: this.container, event: e, cancel: false };
|
|
1216
|
+
this.trigger('beforeClose', beforeCloseArgs, (observedcloseArgs: BeforeOpenCloseEventArgs) => {
|
|
1217
|
+
if (!observedcloseArgs.cancel) {
|
|
1218
|
+
this.splitBtn.toggle();
|
|
1219
|
+
this.onPopupClose();
|
|
1220
|
+
}
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
private triggerChangeEvent(value: string, e?: MouseEvent): void {
|
|
1225
|
+
const hex: string = value.slice(0, 7);
|
|
1226
|
+
this.trigger('change', {
|
|
1227
|
+
currentValue: { hex: hex, rgba: this.convertToRgbString(this.rgb) }, event: e,
|
|
1228
|
+
previousValue: { hex: this.value.slice(0, 7), rgba: this.convertToRgbString(this.hexToRgb(this.value)) },
|
|
1229
|
+
value: this.enableOpacity ? value : hex
|
|
1230
|
+
});
|
|
1231
|
+
if (this.showRecentColors) {
|
|
1232
|
+
this.recentColors.unshift(hex);
|
|
1233
|
+
if (this.inline) { this.renderRecentColor(); }
|
|
1234
|
+
}
|
|
1235
|
+
if (this.enableOpacity) {
|
|
1236
|
+
this.setProperties({ 'value': value }, true);
|
|
1237
|
+
} else {
|
|
1238
|
+
this.setProperties({ 'value': hex }, true);
|
|
1239
|
+
}
|
|
1240
|
+
this.element.value = hex ? hex : '#000000';
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
private handlerDragPosition(prob: number, value: number, e: KeyboardEvent): void {
|
|
1244
|
+
e.preventDefault();
|
|
1245
|
+
this.hsv[prob as number] += value * (e.ctrlKey ? 1 : 3);
|
|
1246
|
+
if (this.hsv[prob as number] < 0) { this.hsv[prob as number] = 0; }
|
|
1247
|
+
this.updateHsv();
|
|
1248
|
+
this.convertToOtherFormat(true, e);
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
private handlerDown(e: MouseEvent & TouchEvent): void {
|
|
1252
|
+
e.preventDefault();
|
|
1253
|
+
if (e.type === 'mousedown') {
|
|
1254
|
+
this.clientX = Math.abs(e.pageX - pageXOffset); this.clientY = Math.abs(e.pageY - pageYOffset);
|
|
1255
|
+
this.setTooltipOffset(8);
|
|
1256
|
+
} else {
|
|
1257
|
+
this.clientX = Math.abs(e.changedTouches[0].pageX - pageXOffset);
|
|
1258
|
+
this.clientY = Math.abs(e.changedTouches[0].pageY - pageYOffset);
|
|
1259
|
+
this.setTooltipOffset(-8);
|
|
1260
|
+
}
|
|
1261
|
+
this.setHsv(this.clientX, this.clientY);
|
|
1262
|
+
this.getDragHandler().style.transition = 'left .4s cubic-bezier(.25, .8, .25, 1), top .4s cubic-bezier(.25, .8, .25, 1)';
|
|
1263
|
+
this.updateHsv();
|
|
1264
|
+
this.convertToOtherFormat(false, e);
|
|
1265
|
+
this.getDragHandler().focus();
|
|
1266
|
+
EventHandler.add(document, 'mousemove touchmove', this.handlerMove, this);
|
|
1267
|
+
EventHandler.add(document, 'mouseup touchend', this.handlerEnd, this);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
private handlerMove(e: MouseEvent & TouchEvent): void {
|
|
1271
|
+
if (e.type !== 'touchmove') {
|
|
1272
|
+
e.preventDefault();
|
|
1273
|
+
}
|
|
1274
|
+
let x: number; let y: number;
|
|
1275
|
+
if (e.type === 'mousemove') {
|
|
1276
|
+
x = Math.abs(e.pageX - pageXOffset); y = Math.abs(e.pageY - pageYOffset);
|
|
1277
|
+
} else {
|
|
1278
|
+
x = Math.abs(e.changedTouches[0].pageX - pageXOffset); y = Math.abs(e.changedTouches[0].pageY - pageYOffset);
|
|
1279
|
+
}
|
|
1280
|
+
this.setHsv(x, y);
|
|
1281
|
+
const dragHandler: HTMLElement = this.getDragHandler();
|
|
1282
|
+
this.updateHsv();
|
|
1283
|
+
this.convertToOtherFormat(false, e);
|
|
1284
|
+
this.getTooltipInst().refresh(dragHandler);
|
|
1285
|
+
if (!this.tooltipEle.style.transform) {
|
|
1286
|
+
if (Math.abs(this.clientX - x) > 8 || Math.abs(this.clientY - y) > 8) {
|
|
1287
|
+
(select('.' + HSVAREA, this.container) as HTMLElement).style.cursor = 'pointer';
|
|
1288
|
+
dragHandler.style.transition = 'none';
|
|
1289
|
+
if (!this.inline) {
|
|
1290
|
+
this.tooltipEle.style.zIndex = (parseInt(this.getPopupEle().style.zIndex, 10) + 1).toString();
|
|
1291
|
+
}
|
|
1292
|
+
this.tooltipEle.style.transform = 'rotate(45deg)';
|
|
1293
|
+
dragHandler.classList.add('e-hide-handler');
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
private setHsv(clientX: number, clientY: number): void {
|
|
1299
|
+
const ele: HTMLElement = select('.' + HSVAREA, this.container) as HTMLElement;
|
|
1300
|
+
const position: ClientRect = ele.getBoundingClientRect();
|
|
1301
|
+
if (this.enableRtl) {
|
|
1302
|
+
clientX = clientX > position.right ? 0 : Math.abs(clientX - position.right);
|
|
1303
|
+
} else {
|
|
1304
|
+
clientX = clientX > position.left ? Math.abs(clientX - position.left) : 0;
|
|
1305
|
+
}
|
|
1306
|
+
clientY = clientY > position.top ? Math.abs(clientY - position.top) : 0;
|
|
1307
|
+
this.hsv[2] = Math.round(Number(100 * (ele.offsetHeight -
|
|
1308
|
+
Math.max(0, Math.min(ele.offsetHeight, (clientY - ele.offsetTop)))) / ele.offsetHeight) * 10) / 10;
|
|
1309
|
+
this.hsv[1] =
|
|
1310
|
+
Math.round(Number(100 * (Math.max(0, Math.min(ele.offsetWidth, (clientX - ele.offsetLeft)))) / ele.offsetWidth) * 10) / 10;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
private handlerEnd(e: MouseEvent & TouchEvent): void {
|
|
1314
|
+
if (e.type !== 'touchend') {
|
|
1315
|
+
e.preventDefault();
|
|
1316
|
+
}
|
|
1317
|
+
EventHandler.remove(document, 'mousemove touchmove', this.handlerMove);
|
|
1318
|
+
EventHandler.remove(document, 'mouseup touchend', this.handlerEnd);
|
|
1319
|
+
const dragHandler: HTMLElement = this.getDragHandler();
|
|
1320
|
+
(select('.' + HSVAREA, this.container) as HTMLElement).style.cursor = '';
|
|
1321
|
+
if (this.tooltipEle.style.transform) {
|
|
1322
|
+
this.tooltipEle.style.transform = '';
|
|
1323
|
+
dragHandler.classList.remove('e-hide-handler');
|
|
1324
|
+
}
|
|
1325
|
+
if (!this.inline && !this.showButtons) {
|
|
1326
|
+
this.closePopup(e);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
private btnClickHandler(e: MouseEvent): void {
|
|
1331
|
+
const target: HTMLElement = (e.target as HTMLElement);
|
|
1332
|
+
if (closest(target, '.' + MODESWITCH)) {
|
|
1333
|
+
e.stopPropagation();
|
|
1334
|
+
this.switchToPalette();
|
|
1335
|
+
} else {
|
|
1336
|
+
if (target.classList.contains(APPLY) || target.classList.contains(CANCEL)) {
|
|
1337
|
+
this.ctrlBtnClick(target, e);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
private switchToPalette(): void {
|
|
1343
|
+
this.trigger('beforeModeSwitch', <ModeSwitchEventArgs>{ element: this.container, mode: 'Palette' });
|
|
1344
|
+
this.unWireEvents();
|
|
1345
|
+
this.destroyOtherComp();
|
|
1346
|
+
detach(select('.e-slider-preview', this.container));
|
|
1347
|
+
if (!this.getWrapper().classList.contains(HIDEVALUE)) {
|
|
1348
|
+
remove(select('.' + INPUTWRAPPER, this.container));
|
|
1349
|
+
}
|
|
1350
|
+
detach(this.getHsvContainer());
|
|
1351
|
+
this.createPalette();
|
|
1352
|
+
this.firstPaletteFocus();
|
|
1353
|
+
this.createInput();
|
|
1354
|
+
this.refreshPopupPos();
|
|
1355
|
+
//for image editor popup position refreshing
|
|
1356
|
+
if (this.element.parentElement && this.element.parentElement.parentElement && this.element.parentElement.parentElement.classList.contains('e-ie-ddb-popup')) {
|
|
1357
|
+
this.refreshImageEditorPopupPos();
|
|
1358
|
+
}
|
|
1359
|
+
this.wireEvents();
|
|
1360
|
+
this.trigger('onModeSwitch', <ModeSwitchEventArgs>{ element: this.container, mode: 'Palette'});
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
//for image editor popup position refreshing
|
|
1364
|
+
private refreshImageEditorPopupPos(): void {
|
|
1365
|
+
if (Browser.isDevice) {
|
|
1366
|
+
const popupEle: HTMLElement = this.getPopupEle();
|
|
1367
|
+
popupEle.style.left = formatUnit(0 + pageXOffset);
|
|
1368
|
+
popupEle.style.top = formatUnit(0 + pageYOffset);
|
|
1369
|
+
const btnElem: HTMLElement = document.querySelector(`#${this.element.parentElement.parentElement.id.split('-popup')[0]}`);
|
|
1370
|
+
if (btnElem) {
|
|
1371
|
+
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1372
|
+
(popupEle.parentElement as any).ej2_instances[0].refreshPosition(btnElem);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
private refreshPopupPos(): void {
|
|
1378
|
+
if (!this.inline) {
|
|
1379
|
+
const popupEle: HTMLElement = this.getPopupEle();
|
|
1380
|
+
popupEle.style.left = formatUnit(0 + pageXOffset);
|
|
1381
|
+
popupEle.style.top = formatUnit(0 + pageYOffset);
|
|
1382
|
+
this.getPopupInst().refreshPosition(this.splitBtn.element.parentElement);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
private formatSwitchHandler(): void {
|
|
1387
|
+
if (this.isRgb) {
|
|
1388
|
+
this.updateValue(this.hsv, true, 3, [360, 100, 100]);
|
|
1389
|
+
this.isRgb = false;
|
|
1390
|
+
} else {
|
|
1391
|
+
this.updateValue(this.rgb, true, 2);
|
|
1392
|
+
this.isRgb = true;
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
private updateValue(value: number[], format: boolean, idx?: number, max?: number[]): void {
|
|
1397
|
+
const clsName: string[] = ['e-rh-value', 'e-gs-value', 'e-bv-value'];
|
|
1398
|
+
let inst: NumericTextBox;
|
|
1399
|
+
for (let i: number = 0, len: number = clsName.length; i < len; i++) {
|
|
1400
|
+
inst = getInstance(select('.' + clsName[i as number], this.container) as HTMLInputElement, NumericTextBox) as NumericTextBox;
|
|
1401
|
+
inst.value = Math.round(value[i as number]);
|
|
1402
|
+
if (format) {
|
|
1403
|
+
inst.placeholder = clsName[i as number].substr(idx, 1).toUpperCase();
|
|
1404
|
+
inst.max = max ? max[i as number] : 255;
|
|
1405
|
+
}
|
|
1406
|
+
inst.dataBind();
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
private previewHandler(e: MouseEvent): void {
|
|
1411
|
+
const target: HTMLElement = e.target as HTMLElement;
|
|
1412
|
+
const pValue: string = this.rgbToHex(this.rgb);
|
|
1413
|
+
this.rgb = this.convertRgbToNumberArray(target.style.backgroundColor);
|
|
1414
|
+
if (!this.rgb[3]) {
|
|
1415
|
+
this.rgb[3] = 1;
|
|
1416
|
+
}
|
|
1417
|
+
const cValue: string = this.rgbToHex(this.rgb);
|
|
1418
|
+
|
|
1419
|
+
const hsv: number[] = this.rgbToHsv.apply(this, this.rgb);
|
|
1420
|
+
if (hsv[0] !== this.hsv[0]) {
|
|
1421
|
+
this.hueSlider.setProperties({ 'value': hsv[0] }, true);
|
|
1422
|
+
this.hueSlider.refresh();
|
|
1423
|
+
}
|
|
1424
|
+
this.setHsvContainerBg(hsv[0]);
|
|
1425
|
+
if (this.enableOpacity && hsv[3] !== this.hsv[3]) {
|
|
1426
|
+
this.opacitySlider.setProperties({ 'value': hsv[3] * 100 }, true);
|
|
1427
|
+
this.opacitySlider.refresh();
|
|
1428
|
+
this.updateOpacitySliderBg();
|
|
1429
|
+
}
|
|
1430
|
+
this.hsv = hsv;
|
|
1431
|
+
this.setHandlerPosition();
|
|
1432
|
+
this.updateInput(cValue);
|
|
1433
|
+
(select('.' + PREVIEW + ' .' + CURRENT, this.container) as HTMLElement).style.backgroundColor = this.convertToRgbString(this.rgb);
|
|
1434
|
+
this.triggerEvent(cValue, pValue, this.convertToRgbString(this.rgb), false, e);
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
private paletteClickHandler(e: MouseEvent): void {
|
|
1438
|
+
e.preventDefault();
|
|
1439
|
+
const target: HTMLElement = e.target as HTMLElement;
|
|
1440
|
+
if (target.classList.contains(TILE)) {
|
|
1441
|
+
this.removeTileSelection();
|
|
1442
|
+
this.addTileSelection(target);
|
|
1443
|
+
if (target.classList.contains(NOCOLOR)) {
|
|
1444
|
+
this.noColorTile();
|
|
1445
|
+
} else {
|
|
1446
|
+
const cValue: string = target.getAttribute('aria-label');
|
|
1447
|
+
const pValue: string = this.rgbToHex(this.rgb);
|
|
1448
|
+
this.rgb = this.hexToRgb(this.roundValue(cValue));
|
|
1449
|
+
this.hsv = this.rgbToHsv.apply(this, this.rgb);
|
|
1450
|
+
if (this.getWrapper().classList.contains(SHOWVALUE)) {
|
|
1451
|
+
this.updateInput(cValue);
|
|
1452
|
+
}
|
|
1453
|
+
this.triggerEvent(cValue, pValue, this.convertToRgbString(this.rgb), false, e);
|
|
1454
|
+
}
|
|
1455
|
+
if (!this.inline && !this.showButtons) {
|
|
1456
|
+
this.closePopup(e);
|
|
1457
|
+
}
|
|
1458
|
+
} else {
|
|
1459
|
+
if (closest(target, '.' + MODESWITCH)) {
|
|
1460
|
+
this.switchToPicker();
|
|
1461
|
+
} else {
|
|
1462
|
+
if (target.classList.contains(APPLY) || target.classList.contains(CANCEL)) {
|
|
1463
|
+
this.ctrlBtnClick(target, e);
|
|
1464
|
+
} else {
|
|
1465
|
+
if (this.getWrapper().classList.contains(SHOWVALUE) && closest(target, '.' + FORMATSWITCH)) {
|
|
1466
|
+
this.formatSwitchHandler();
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
private noColorTile(isKey: boolean = false): void {
|
|
1474
|
+
const pValue: string = this.rgbToHex(this.rgb);
|
|
1475
|
+
this.rgb = [];
|
|
1476
|
+
this.hsv = [];
|
|
1477
|
+
this.triggerEvent('', pValue, '', isKey);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
private switchToPicker(): void {
|
|
1481
|
+
const wrapper: Element = this.getWrapper();
|
|
1482
|
+
this.trigger('beforeModeSwitch', <ModeSwitchEventArgs>{ element: this.container, mode: 'Picker' });
|
|
1483
|
+
this.unWireEvents();
|
|
1484
|
+
([].slice.call(selectAll('.' + PALETTES, this.container))).forEach((ele: HTMLElement) => {
|
|
1485
|
+
detach(ele);
|
|
1486
|
+
});
|
|
1487
|
+
if (this.container.querySelector('.e-clr-pal-rec-wpr')) {
|
|
1488
|
+
detach(this.container.querySelector('.e-clr-pal-rec-wpr'));
|
|
1489
|
+
}
|
|
1490
|
+
if (wrapper.classList.contains(SHOWVALUE)) {
|
|
1491
|
+
detach(select('.' + INPUTWRAPPER, this.container));
|
|
1492
|
+
}
|
|
1493
|
+
this.container.style.width = '';
|
|
1494
|
+
const grpEle: Element = select('.e-custom-palette', this.container);
|
|
1495
|
+
if (this.presetColors) {
|
|
1496
|
+
remove(grpEle);
|
|
1497
|
+
}
|
|
1498
|
+
this.createPicker();
|
|
1499
|
+
this.getDragHandler().focus();
|
|
1500
|
+
this.createInput();
|
|
1501
|
+
this.refreshPopupPos();
|
|
1502
|
+
//for image editor popup position refreshing
|
|
1503
|
+
if (this.element.parentElement && this.element.parentElement.parentElement && this.element.parentElement.parentElement.classList.contains('e-ie-ddb-popup')) {
|
|
1504
|
+
this.refreshImageEditorPopupPos();
|
|
1505
|
+
}
|
|
1506
|
+
this.wireEvents();
|
|
1507
|
+
this.trigger('onModeSwitch', <ModeSwitchEventArgs>{ element: this.container, mode: 'Picker'});
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
private ctrlBtnClick(ele: HTMLElement, e: MouseEvent): void {
|
|
1511
|
+
if (ele.classList.contains(APPLY)) {
|
|
1512
|
+
const cValue: string = this.rgbToHex(this.rgb);
|
|
1513
|
+
this.triggerChangeEvent(cValue, e);
|
|
1514
|
+
}
|
|
1515
|
+
if (!this.inline) {
|
|
1516
|
+
this.closePopup(e);
|
|
1517
|
+
this.splitBtn.element.focus();
|
|
1518
|
+
} else if (ele.classList.contains(CANCEL)) {
|
|
1519
|
+
const beforeCloseArgs: BeforeOpenCloseEventArgs = { element: this.container, event: e, cancel: false };
|
|
1520
|
+
this.trigger('beforeClose', beforeCloseArgs);
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
private paletteKeyDown(e: KeyboardEvent): void {
|
|
1525
|
+
const target: HTMLElement = e.target as HTMLElement;
|
|
1526
|
+
if (!target.classList.contains(PALETTES)) {
|
|
1527
|
+
return;
|
|
1528
|
+
}
|
|
1529
|
+
let selectedEle: Element;
|
|
1530
|
+
let idx: number;
|
|
1531
|
+
const tiles: Element[] = [].slice.call(selectAll('.' + TILE, target));
|
|
1532
|
+
const prevSelectedEle: Element = (tiles.filter((tile: Element) => tile.classList.contains('e-selected'))).pop();
|
|
1533
|
+
switch (!e.altKey && e.keyCode) {
|
|
1534
|
+
case 39:
|
|
1535
|
+
e.preventDefault();
|
|
1536
|
+
selectedEle = prevSelectedEle ? tiles[this.tilePosition(tiles, prevSelectedEle, this.enableRtl ? -1 : 1)]
|
|
1537
|
+
: tiles[this.enableRtl ? tiles.length - 1 : 0];
|
|
1538
|
+
this.keySelectionChanges(selectedEle);
|
|
1539
|
+
break;
|
|
1540
|
+
case 37:
|
|
1541
|
+
e.preventDefault();
|
|
1542
|
+
selectedEle = prevSelectedEle ? tiles[this.tilePosition(tiles, prevSelectedEle, this.enableRtl ? 1 : -1)]
|
|
1543
|
+
: tiles[this.enableRtl ? 0 : tiles.length - 1];
|
|
1544
|
+
this.keySelectionChanges(selectedEle);
|
|
1545
|
+
break;
|
|
1546
|
+
case 38:
|
|
1547
|
+
e.preventDefault();
|
|
1548
|
+
idx = prevSelectedEle ? this.tilePosition(tiles, prevSelectedEle, -this.columns) : 0;
|
|
1549
|
+
selectedEle = tiles[idx as number] ? tiles[idx as number] : tiles[idx - this.columns];
|
|
1550
|
+
this.keySelectionChanges(selectedEle);
|
|
1551
|
+
break;
|
|
1552
|
+
case 40:
|
|
1553
|
+
e.preventDefault();
|
|
1554
|
+
idx = prevSelectedEle ? this.tilePosition(tiles, prevSelectedEle, this.columns) : tiles.length - 1;
|
|
1555
|
+
if (tiles[idx as number]) {
|
|
1556
|
+
selectedEle = tiles[idx as number];
|
|
1557
|
+
} else {
|
|
1558
|
+
idx %= tiles.length;
|
|
1559
|
+
idx += tiles[tiles.length - 1].parentElement.childElementCount;
|
|
1560
|
+
selectedEle = tiles[idx as number];
|
|
1561
|
+
}
|
|
1562
|
+
this.keySelectionChanges(selectedEle);
|
|
1563
|
+
break;
|
|
1564
|
+
case 13:
|
|
1565
|
+
e.preventDefault();
|
|
1566
|
+
if (prevSelectedEle) {
|
|
1567
|
+
const cValue: string = prevSelectedEle.getAttribute('aria-label');
|
|
1568
|
+
this.enterKeyHandler(cValue ? cValue : '');
|
|
1569
|
+
}
|
|
1570
|
+
break;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
private keySelectionChanges(newEle: Element): void {
|
|
1575
|
+
this.removeTileSelection();
|
|
1576
|
+
this.addTileSelection(newEle);
|
|
1577
|
+
if (newEle.classList.contains(NOCOLOR)) {
|
|
1578
|
+
this.noColorTile(true);
|
|
1579
|
+
} else {
|
|
1580
|
+
const cValue: string = newEle.getAttribute('aria-label');
|
|
1581
|
+
const pValue: string = this.rgbToHex(this.rgb);
|
|
1582
|
+
this.rgb = this.hexToRgb(cValue);
|
|
1583
|
+
this.hsv = this.rgbToHsv.apply(this, this.rgb);
|
|
1584
|
+
if (this.getWrapper().classList.contains(SHOWVALUE)) {
|
|
1585
|
+
this.updateInput(cValue);
|
|
1586
|
+
}
|
|
1587
|
+
this.triggerEvent(cValue, pValue, this.convertToRgbString(this.rgb), true);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
private tilePosition(items: Element[], element: Element, cIdx: number): number {
|
|
1592
|
+
items = Array.prototype.slice.call(items);
|
|
1593
|
+
const n: number = items.length;
|
|
1594
|
+
const emptyCount: number = this.columns - items[n - 1].parentElement.childElementCount;
|
|
1595
|
+
let idx: number = items.indexOf(element);
|
|
1596
|
+
idx += cIdx;
|
|
1597
|
+
if (idx < 0) {
|
|
1598
|
+
idx += n + emptyCount;
|
|
1599
|
+
} else {
|
|
1600
|
+
idx %= n + emptyCount;
|
|
1601
|
+
}
|
|
1602
|
+
return idx;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
private inputHandler(e: MouseEvent | Event): void {
|
|
1606
|
+
const target: HTMLInputElement = e.target as HTMLInputElement;
|
|
1607
|
+
if (!target.value.length) {
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1610
|
+
let hsv: number[]; let pValue: string;
|
|
1611
|
+
const label: string = select('.e-float-text', target.parentElement).textContent;
|
|
1612
|
+
switch (label) {
|
|
1613
|
+
case 'HEX': {
|
|
1614
|
+
let value: string = '';
|
|
1615
|
+
if ((target.value[0] === '#' && target.value.length !== 5) || (target.value[0] !== '#' && target.value.length !== 4)) {
|
|
1616
|
+
value = this.roundValue(target.value);
|
|
1617
|
+
}
|
|
1618
|
+
if (value.length === 9) {
|
|
1619
|
+
pValue = this.rgbToHex(this.rgb);
|
|
1620
|
+
this.rgb = this.hexToRgb(value + value.substr(-2));
|
|
1621
|
+
this.inputValueChange(this.rgbToHsv.apply(this, this.rgb), pValue, target.value, e);
|
|
1622
|
+
} else {
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
break;
|
|
1626
|
+
}
|
|
1627
|
+
case 'R':
|
|
1628
|
+
if (this.rgb[0] !== Number(target.value)) {
|
|
1629
|
+
pValue = this.rgbToHex(this.rgb);
|
|
1630
|
+
this.rgb[0] = Number(target.value);
|
|
1631
|
+
hsv = this.rgbToHsv.apply(this, this.rgb);
|
|
1632
|
+
this.inputValueChange(hsv, pValue, null, e);
|
|
1633
|
+
}
|
|
1634
|
+
break;
|
|
1635
|
+
case 'G':
|
|
1636
|
+
if (this.rgb[1] !== Number(target.value)) {
|
|
1637
|
+
pValue = this.rgbToHex(this.rgb);
|
|
1638
|
+
this.rgb[1] = Number(target.value);
|
|
1639
|
+
hsv = this.rgbToHsv.apply(this, this.rgb);
|
|
1640
|
+
this.inputValueChange(hsv, pValue, null, e);
|
|
1641
|
+
}
|
|
1642
|
+
break;
|
|
1643
|
+
case 'B':
|
|
1644
|
+
if (this.rgb[2] !== Number(target.value)) {
|
|
1645
|
+
pValue = this.rgbToHex(this.rgb);
|
|
1646
|
+
this.rgb[2] = Number(target.value);
|
|
1647
|
+
hsv = this.rgbToHsv.apply(this, this.rgb);
|
|
1648
|
+
this.inputValueChange(hsv, pValue, null, e);
|
|
1649
|
+
}
|
|
1650
|
+
break;
|
|
1651
|
+
case 'H':
|
|
1652
|
+
this.hueSlider.value = Number(target.value);
|
|
1653
|
+
break;
|
|
1654
|
+
case 'S':
|
|
1655
|
+
if (this.hsv[1] !== Number(target.value)) {
|
|
1656
|
+
this.hsv[1] = Number(target.value);
|
|
1657
|
+
this.updateHsv();
|
|
1658
|
+
this.convertToOtherFormat(false, e);
|
|
1659
|
+
}
|
|
1660
|
+
break;
|
|
1661
|
+
case 'V':
|
|
1662
|
+
if (this.hsv[2] !== Number(target.value)) {
|
|
1663
|
+
this.hsv[2] = Number(target.value);
|
|
1664
|
+
this.updateHsv();
|
|
1665
|
+
this.convertToOtherFormat(false, e);
|
|
1666
|
+
}
|
|
1667
|
+
break;
|
|
1668
|
+
case 'A':
|
|
1669
|
+
this.opacitySlider.value = Number(target.value);
|
|
1670
|
+
break;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
private inputValueChange(hsv: number[], pValue: string, value?: string, e?: MouseEvent | Event): void {
|
|
1676
|
+
if (hsv[0] !== this.hsv[0]) {
|
|
1677
|
+
this.hueSlider.setProperties({ 'value': hsv[0] }, true);
|
|
1678
|
+
this.hueSlider.refresh();
|
|
1679
|
+
this.setHsvContainerBg(hsv[0]);
|
|
1680
|
+
}
|
|
1681
|
+
this.hsv = hsv;
|
|
1682
|
+
const cValue: string = this.rgbToHex(this.rgb);
|
|
1683
|
+
this.setHandlerPosition();
|
|
1684
|
+
this.updateInput(value ? value : cValue);
|
|
1685
|
+
const rgba: string = this.convertToRgbString(this.rgb);
|
|
1686
|
+
this.updatePreview(rgba);
|
|
1687
|
+
this.triggerEvent(cValue, pValue, rgba, false, e);
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
private triggerEvent(cValue: string, pValue: string, rgba: string, isKey: boolean = false, e?: MouseEvent | Event): void {
|
|
1691
|
+
const hex: string = cValue.slice(0, 7);
|
|
1692
|
+
if (isNullOrUndefined(e)) {
|
|
1693
|
+
e = new MouseEvent('click', { bubbles: true, cancelable: false });
|
|
1694
|
+
}
|
|
1695
|
+
if (!this.showButtons && !isKey) {
|
|
1696
|
+
this.trigger('change', { currentValue: { hex: hex, rgba: rgba }, event: e,
|
|
1697
|
+
previousValue: { hex: this.value.slice(0, 7), rgba: this.convertToRgbString(this.hexToRgb(this.value)) }, value: cValue });
|
|
1698
|
+
if (this.showRecentColors) {
|
|
1699
|
+
this.recentColors.unshift(hex);
|
|
1700
|
+
if (this.inline) { this.renderRecentColor(); }
|
|
1701
|
+
}
|
|
1702
|
+
if (this.enableOpacity) {
|
|
1703
|
+
this.setProperties({ 'value': cValue }, true);
|
|
1704
|
+
} else {
|
|
1705
|
+
this.setProperties({ 'value': hex }, true);
|
|
1706
|
+
}
|
|
1707
|
+
this.element.value = hex ? hex : '#000000';
|
|
1708
|
+
} else {
|
|
1709
|
+
this.trigger('select', {
|
|
1710
|
+
currentValue: { hex: hex, rgba: rgba }, event: e,
|
|
1711
|
+
previousValue: { hex: pValue.slice(0, 7), rgba: this.convertToRgbString(this.hexToRgb(pValue)) }
|
|
1712
|
+
});
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
/**
|
|
1717
|
+
* Removes the component from the DOM and detaches all its related event handlers.
|
|
1718
|
+
* Also it maintains the initial input element from the DOM.
|
|
1719
|
+
*
|
|
1720
|
+
* @method destroy
|
|
1721
|
+
* @returns {void}
|
|
1722
|
+
*/
|
|
1723
|
+
public destroy(): void {
|
|
1724
|
+
const wrapper: Element = this.getWrapper();
|
|
1725
|
+
super.destroy();
|
|
1726
|
+
['tabindex', 'spellcheck'].forEach((attr: string): void => { this.element.removeAttribute(attr); });
|
|
1727
|
+
if (this.inline) {
|
|
1728
|
+
this.unWireEvents();
|
|
1729
|
+
this.destroyOtherComp();
|
|
1730
|
+
} else {
|
|
1731
|
+
if (this.isPopupOpen()) {
|
|
1732
|
+
this.unWireEvents();
|
|
1733
|
+
this.destroyOtherComp();
|
|
1734
|
+
}
|
|
1735
|
+
this.splitBtn.destroy();
|
|
1736
|
+
this.splitBtn = null;
|
|
1737
|
+
}
|
|
1738
|
+
this.tileRipple();
|
|
1739
|
+
this.tileRipple = null;
|
|
1740
|
+
this.ctrlBtnRipple();
|
|
1741
|
+
this.ctrlBtnRipple = null;
|
|
1742
|
+
if (this.element.nextElementSibling) {
|
|
1743
|
+
detach(this.element.nextElementSibling);
|
|
1744
|
+
}
|
|
1745
|
+
if (wrapper) {
|
|
1746
|
+
wrapper.parentElement.insertBefore(this.element, wrapper);
|
|
1747
|
+
detach(wrapper);
|
|
1748
|
+
}
|
|
1749
|
+
this.container = null;
|
|
1750
|
+
if (this.formElement) {
|
|
1751
|
+
EventHandler.remove(this.formElement, 'reset', this.formResetHandler);
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
private destroyOtherComp(): void {
|
|
1756
|
+
if (this.isPicker()) {
|
|
1757
|
+
const popup: HTMLElement = closest(this.hueSlider.element, '.e-color-picker') as HTMLElement;
|
|
1758
|
+
const numericElemColl: NodeListOf<HTMLElement> = popup.querySelectorAll('.e-numerictextbox');
|
|
1759
|
+
for (let i: number = 0; i < numericElemColl.length; i++) {
|
|
1760
|
+
(getInstance(numericElemColl[i as number], NumericTextBox) as NumericTextBox).destroy();
|
|
1761
|
+
}
|
|
1762
|
+
this.hueSlider.destroy();
|
|
1763
|
+
if (this.enableOpacity) { this.opacitySlider.destroy(); this.opacitySlider = null; }
|
|
1764
|
+
this.hueSlider = null;
|
|
1765
|
+
const tooltipInst: Tooltip = this.getTooltipInst();
|
|
1766
|
+
tooltipInst.close();
|
|
1767
|
+
tooltipInst.destroy();
|
|
1768
|
+
this.tooltipEle = null;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
private isPopupOpen(): boolean {
|
|
1773
|
+
return this.getPopupEle().classList.contains('e-popup-open');
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
protected unWireEvents(): void {
|
|
1777
|
+
if (this.isPicker()) {
|
|
1778
|
+
const dragHandler: HTMLElement = this.getDragHandler();
|
|
1779
|
+
EventHandler.remove(dragHandler, 'keydown', this.pickerKeyDown);
|
|
1780
|
+
const ctrlBtn: HTMLElement = select('.' + CTRLBTN, this.container) as HTMLElement;
|
|
1781
|
+
if (ctrlBtn) {
|
|
1782
|
+
EventHandler.remove(ctrlBtn, 'keydown', this.ctrlBtnKeyDown);
|
|
1783
|
+
}
|
|
1784
|
+
EventHandler.remove(this.getHsvContainer(), 'mousedown touchstart', this.handlerDown);
|
|
1785
|
+
if (this.modeSwitcher || this.showButtons) {
|
|
1786
|
+
EventHandler.remove(select('.' + CTRLSWITCH, this.container), 'click', this.btnClickHandler);
|
|
1787
|
+
}
|
|
1788
|
+
EventHandler.remove(select('.' + PREVIOUS, this.container), 'click', this.previewHandler);
|
|
1789
|
+
} else {
|
|
1790
|
+
EventHandler.remove(this.container, 'click', this.paletteClickHandler);
|
|
1791
|
+
EventHandler.remove(this.container, 'keydown', this.paletteKeyDown);
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
private roundValue(value: string): string {
|
|
1796
|
+
if (!value) { return ''; }
|
|
1797
|
+
if (value[0] !== '#') {
|
|
1798
|
+
value = '#' + value;
|
|
1799
|
+
}
|
|
1800
|
+
let len: number = value.length;
|
|
1801
|
+
if (len === 4) {
|
|
1802
|
+
value += 'f';
|
|
1803
|
+
len = 5;
|
|
1804
|
+
}
|
|
1805
|
+
if (len === 5) {
|
|
1806
|
+
let tempValue: string = '';
|
|
1807
|
+
for (let i: number = 1, len: number = value.length; i < len; i++) {
|
|
1808
|
+
tempValue += (value.charAt(i) + value.charAt(i));
|
|
1809
|
+
}
|
|
1810
|
+
value = '#' + tempValue;
|
|
1811
|
+
len = 9;
|
|
1812
|
+
}
|
|
1813
|
+
if (len === 7) {
|
|
1814
|
+
value += 'ff';
|
|
1815
|
+
}
|
|
1816
|
+
return value;
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
private hexToRgb(hex: string): number[] {
|
|
1820
|
+
if (!hex) { return []; }
|
|
1821
|
+
hex = hex.trim();
|
|
1822
|
+
if (hex.length !== 9) {
|
|
1823
|
+
hex = this.roundValue(hex);
|
|
1824
|
+
}
|
|
1825
|
+
const opacity: number = Number((parseInt(hex.slice(-2), 16) / 255).toFixed(2));
|
|
1826
|
+
hex = hex.slice(1, 7);
|
|
1827
|
+
const bigInt: number = parseInt(hex, 16); const h: number[] = [];
|
|
1828
|
+
h.push((bigInt >> 16) & 255);
|
|
1829
|
+
h.push((bigInt >> 8) & 255);
|
|
1830
|
+
h.push(bigInt & 255);
|
|
1831
|
+
h.push(opacity);
|
|
1832
|
+
return h;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
private rgbToHsv(r: number, g: number, b: number, opacity?: number): number[] {
|
|
1836
|
+
if (this.rgb && !this.rgb.length) { return []; }
|
|
1837
|
+
r /= 255; g /= 255; b /= 255;
|
|
1838
|
+
const max: number = Math.max(r, g, b); const min: number = Math.min(r, g, b);
|
|
1839
|
+
let h: number; const v: number = max;
|
|
1840
|
+
|
|
1841
|
+
const d: number = max - min;
|
|
1842
|
+
const s: number = max === 0 ? 0 : d / max;
|
|
1843
|
+
|
|
1844
|
+
if (max === min) {
|
|
1845
|
+
h = 0;
|
|
1846
|
+
} else {
|
|
1847
|
+
switch (max) {
|
|
1848
|
+
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
|
1849
|
+
case g: h = (b - r) / d + 2; break;
|
|
1850
|
+
case b: h = (r - g) / d + 4; break;
|
|
1851
|
+
}
|
|
1852
|
+
h /= 6;
|
|
1853
|
+
}
|
|
1854
|
+
const hsv: number[] = [Math.round(h * 360), Math.round(s * 1000) / 10, Math.round(v * 1000) / 10];
|
|
1855
|
+
if (!isNullOrUndefined(opacity)) {
|
|
1856
|
+
hsv.push(opacity);
|
|
1857
|
+
}
|
|
1858
|
+
return hsv;
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
private hsvToRgb(h: number, s: number, v: number, opacity?: number): number[] {
|
|
1862
|
+
let r: number; let g: number; let b: number;
|
|
1863
|
+
s /= 100; v /= 100;
|
|
1864
|
+
if (s === 0) {
|
|
1865
|
+
r = g = b = v;
|
|
1866
|
+
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), opacity];
|
|
1867
|
+
}
|
|
1868
|
+
h /= 60;
|
|
1869
|
+
const i: number = Math.floor(h);
|
|
1870
|
+
const f: number = h - i;
|
|
1871
|
+
const p: number = v * (1 - s);
|
|
1872
|
+
const q: number = v * (1 - s * f);
|
|
1873
|
+
const t: number = v * (1 - s * (1 - f));
|
|
1874
|
+
switch (i) {
|
|
1875
|
+
case 0: r = v; g = t; b = p; break;
|
|
1876
|
+
case 1: r = q; g = v; b = p; break;
|
|
1877
|
+
case 2: r = p; g = v; b = t; break;
|
|
1878
|
+
case 3: r = p; g = q; b = v; break;
|
|
1879
|
+
case 4: r = t; g = p; b = v; break;
|
|
1880
|
+
default: r = v; g = p; b = q;
|
|
1881
|
+
}
|
|
1882
|
+
const rgb: number[] = [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
|
|
1883
|
+
if (!isNullOrUndefined(opacity)) {
|
|
1884
|
+
rgb.push(opacity);
|
|
1885
|
+
}
|
|
1886
|
+
return rgb;
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
private rgbToHex(rgb: number[]): string {
|
|
1890
|
+
return rgb.length ? ('#' + this.hex(rgb[0]) + this.hex(rgb[1]) + this.hex(rgb[2]) +
|
|
1891
|
+
(!isNullOrUndefined(rgb[3]) ? (rgb[3] !== 0 ? (Math.round(rgb[3] * 255) + 0x10000).toString(16).substr(-2) : '00') : '')) : '';
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
private hex(x: number): string {
|
|
1895
|
+
return ('0' + x.toString(16)).slice(-2);
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
private changeModeSwitcherProp(prop: boolean): void {
|
|
1899
|
+
const ctrlSwitchWrapper: Element = select('.' + CTRLSWITCH, this.container);
|
|
1900
|
+
if (prop) {
|
|
1901
|
+
if (ctrlSwitchWrapper) {
|
|
1902
|
+
this.appendModeSwitchBtn();
|
|
1903
|
+
} else {
|
|
1904
|
+
this.createCtrlBtn();
|
|
1905
|
+
if (this.isPicker() && !this.disabled) {
|
|
1906
|
+
this.addCtrlSwitchEvent();
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
} else {
|
|
1910
|
+
if (ctrlSwitchWrapper) {
|
|
1911
|
+
if (this.showButtons) {
|
|
1912
|
+
detach(select('.' + MODESWITCH, ctrlSwitchWrapper));
|
|
1913
|
+
} else {
|
|
1914
|
+
remove(ctrlSwitchWrapper);
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
private changeShowBtnProps(prop: boolean): void {
|
|
1921
|
+
const ctrlBtnWrapper: Element = select('.' + CTRLSWITCH, this.container);
|
|
1922
|
+
if (prop) {
|
|
1923
|
+
if (ctrlBtnWrapper) {
|
|
1924
|
+
remove(ctrlBtnWrapper);
|
|
1925
|
+
}
|
|
1926
|
+
this.createCtrlBtn();
|
|
1927
|
+
if (this.isPicker() && !this.disabled) {
|
|
1928
|
+
this.addCtrlSwitchEvent();
|
|
1929
|
+
}
|
|
1930
|
+
} else {
|
|
1931
|
+
if (this.modeSwitcher) {
|
|
1932
|
+
detach(select('.' + CTRLBTN, ctrlBtnWrapper));
|
|
1933
|
+
} else {
|
|
1934
|
+
remove(ctrlBtnWrapper);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
private changeValueProp(newProp: string): void {
|
|
1940
|
+
if (this.isPicker()) {
|
|
1941
|
+
this.rgb = this.hexToRgb(newProp);
|
|
1942
|
+
this.hsv = this.rgbToHsv.apply(this, this.rgb);
|
|
1943
|
+
this.setHandlerPosition();
|
|
1944
|
+
detach(closest(this.hueSlider.element, '.e-slider-preview'));
|
|
1945
|
+
this.createSlider();
|
|
1946
|
+
this.setHsvContainerBg();
|
|
1947
|
+
this.updateInput(newProp);
|
|
1948
|
+
if (this.rgb.length === 4) { this.updateOpacityInput(this.rgb[3] * 100); }
|
|
1949
|
+
} else {
|
|
1950
|
+
this.removeTileSelection();
|
|
1951
|
+
const ele: Element = this.container.querySelector('span[aria-label="' + this.roundValue(newProp) + '"]');
|
|
1952
|
+
if (ele) { this.addTileSelection(ele); }
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
private setInputEleProps(): void {
|
|
1957
|
+
remove(select('.' + INPUTWRAPPER, this.container));
|
|
1958
|
+
this.createInput();
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
private changeDisabledProp(newProp: boolean): void {
|
|
1962
|
+
if (this.isPicker()) {
|
|
1963
|
+
this.hueSlider.enabled = !newProp;
|
|
1964
|
+
this.opacitySlider.enabled = !newProp;
|
|
1965
|
+
this.setInputEleProps();
|
|
1966
|
+
}
|
|
1967
|
+
if (newProp) {
|
|
1968
|
+
this.toggleDisabled(true);
|
|
1969
|
+
this.unWireEvents();
|
|
1970
|
+
} else {
|
|
1971
|
+
this.toggleDisabled(false);
|
|
1972
|
+
this.wireEvents();
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
private changeCssClassProps(newProp: string, oldProp: string): void {
|
|
1977
|
+
const wrapper: Element = this.getWrapper();
|
|
1978
|
+
const popupWrapper: HTMLElement = this.getPopupEle();
|
|
1979
|
+
if (oldProp) {
|
|
1980
|
+
removeClass([wrapper, popupWrapper], oldProp.split(' '));
|
|
1981
|
+
if (this.splitBtn && this.splitBtn.activeElem && this.splitBtn.activeElem[0] && this.splitBtn.activeElem[1]) {
|
|
1982
|
+
removeClass([this.splitBtn.activeElem[0], this.splitBtn.activeElem[1]], oldProp.split(' '));
|
|
1983
|
+
}
|
|
1984
|
+
if (this.splitBtn && this.splitBtn.element && this.splitBtn.element.parentElement) {
|
|
1985
|
+
removeClass([this.splitBtn.element.parentElement], oldProp.split(' '));
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
}
|
|
1989
|
+
if (newProp) {
|
|
1990
|
+
addClass([wrapper, popupWrapper], newProp.replace(/\s+/g, ' ').trim().split(' '));
|
|
1991
|
+
if (this.splitBtn && this.splitBtn.activeElem && this.splitBtn.activeElem[0] && this.splitBtn.activeElem[1]) {
|
|
1992
|
+
addClass([this.splitBtn.activeElem[0], this.splitBtn.activeElem[1]], newProp.replace(/\s+/g, ' ').trim().split(' '));
|
|
1993
|
+
}
|
|
1994
|
+
if (this.splitBtn && this.splitBtn.element && this.splitBtn.element.parentElement) {
|
|
1995
|
+
addClass([this.splitBtn.element.parentElement], newProp.replace(/\s+/g, ' ').trim().split(' '));
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
private changeRtlProps(newProp: boolean): void {
|
|
2001
|
+
if (newProp) {
|
|
2002
|
+
addClass([this.getWrapper()], 'e-rtl');
|
|
2003
|
+
} else {
|
|
2004
|
+
removeClass([this.getWrapper()], 'e-rtl');
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
private changePaletteProps(): void {
|
|
2009
|
+
detach(this.container.children[0]);
|
|
2010
|
+
this.container.style.width = '';
|
|
2011
|
+
this.createPalette();
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
private changeOpacityProps(newProp: boolean): void {
|
|
2015
|
+
const wrapper: HTMLElement = this.getWrapper();
|
|
2016
|
+
if (newProp) {
|
|
2017
|
+
removeClass([this.container.parentElement], HIDEOPACITY);
|
|
2018
|
+
this.createOpacitySlider(
|
|
2019
|
+
select('.e-colorpicker-slider', this.container).appendChild(this.createElement('div', { className: 'e-opacity-slider' })));
|
|
2020
|
+
if (!wrapper.classList.contains(HIDEVALUE) && !wrapper.classList.contains(HIDERGBA)) {
|
|
2021
|
+
this.appendOpacityValue(select('.e-input-container', this.container) as HTMLElement);
|
|
2022
|
+
}
|
|
2023
|
+
} else {
|
|
2024
|
+
addClass([this.container.parentElement], HIDEOPACITY);
|
|
2025
|
+
this.opacitySlider.destroy();
|
|
2026
|
+
remove(this.opacitySlider.element);
|
|
2027
|
+
this.opacitySlider = null;
|
|
2028
|
+
if (!wrapper.classList.contains(HIDEVALUE) && !wrapper.classList.contains(HIDERGBA)) {
|
|
2029
|
+
remove(select('.' + OPACITY, this.container).parentElement);
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
/**
|
|
2035
|
+
* Called internally if any of the property value changed.
|
|
2036
|
+
*
|
|
2037
|
+
* @param {ColorPickerModel} newProp - Specifies new properties
|
|
2038
|
+
* @param {ColorPickerModel} oldProp - Specifies old properties
|
|
2039
|
+
* @returns {void}
|
|
2040
|
+
* @private
|
|
2041
|
+
*/
|
|
2042
|
+
public onPropertyChanged(newProp: ColorPickerModel, oldProp: ColorPickerModel): void {
|
|
2043
|
+
if (!isNullOrUndefined(newProp.value)) {
|
|
2044
|
+
const value: string = this.roundValue(newProp.value);
|
|
2045
|
+
if (value.length === 9) {
|
|
2046
|
+
this.element.value = this.roundValue(value).slice(0, 7);
|
|
2047
|
+
const preview: HTMLElement = this.splitBtn && select('.' + SPLITPREVIEW, this.splitBtn.element) as HTMLElement;
|
|
2048
|
+
if (preview) {
|
|
2049
|
+
preview.style.backgroundColor = this.convertToRgbString(this.hexToRgb(newProp.value));
|
|
2050
|
+
}
|
|
2051
|
+
} else if (this.noColor && this.mode === 'Palette' && this.value === '') {
|
|
2052
|
+
const preview: HTMLElement = this.splitBtn && select('.' + SPLITPREVIEW, this.splitBtn.element) as HTMLElement;
|
|
2053
|
+
preview.style.backgroundColor = '';
|
|
2054
|
+
} else {
|
|
2055
|
+
this.value = oldProp.value;
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
if (!this.inline && isNullOrUndefined(newProp.inline)) {
|
|
2059
|
+
const otherCompModel: string[] = ['disabled', 'enableRtl'];
|
|
2060
|
+
this.splitBtn.setProperties(getModel(newProp, otherCompModel));
|
|
2061
|
+
if (!this.isPopupOpen()) {
|
|
2062
|
+
this.changeCssClassProps(newProp.cssClass, oldProp.cssClass);
|
|
2063
|
+
this.changeRtlProps(newProp.enableRtl);
|
|
2064
|
+
return;
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
for (const prop of Object.keys(newProp)) {
|
|
2068
|
+
switch (prop) {
|
|
2069
|
+
case 'inline':
|
|
2070
|
+
if (newProp.inline) {
|
|
2071
|
+
this.getWrapper().appendChild(this.container);
|
|
2072
|
+
this.splitBtn.destroy();
|
|
2073
|
+
detach(this.element.nextElementSibling);
|
|
2074
|
+
if (!this.container.children.length) {
|
|
2075
|
+
this.createWidget();
|
|
2076
|
+
}
|
|
2077
|
+
} else {
|
|
2078
|
+
this.destroyOtherComp();
|
|
2079
|
+
this.unWireEvents();
|
|
2080
|
+
this.container.innerHTML = '';
|
|
2081
|
+
this.createSplitBtn();
|
|
2082
|
+
}
|
|
2083
|
+
break;
|
|
2084
|
+
case 'cssClass': {
|
|
2085
|
+
this.changeCssClassProps(newProp.cssClass, oldProp.cssClass);
|
|
2086
|
+
let props: string[] = newProp.cssClass.split(' ').concat(oldProp.cssClass.split(' '));
|
|
2087
|
+
props = props.reduce((a: string[], b: string): string[] => { if (a.indexOf(b) < 0) { a.push(b); } return a; }, []);
|
|
2088
|
+
let count: number = 0;
|
|
2089
|
+
props.forEach((cls: string) => {
|
|
2090
|
+
if (count === 0 &&
|
|
2091
|
+
(cls === HIDEVALUE || cls === HIDEVALUESWITCH || cls === SHOWVALUE || cls === HIDEHEX || cls === HIDERGBA)) {
|
|
2092
|
+
const inputWrap: Element = select('.' + INPUTWRAPPER, this.container);
|
|
2093
|
+
if (inputWrap) { remove(select('.' + INPUTWRAPPER, this.container)); }
|
|
2094
|
+
this.createInput();
|
|
2095
|
+
count++;
|
|
2096
|
+
}
|
|
2097
|
+
});
|
|
2098
|
+
break;
|
|
2099
|
+
}
|
|
2100
|
+
case 'enableRtl':
|
|
2101
|
+
if (this.isPicker()) {
|
|
2102
|
+
this.hueSlider.enableRtl = newProp.enableRtl;
|
|
2103
|
+
if (this.enableOpacity) { this.opacitySlider.enableRtl = newProp.enableRtl; }
|
|
2104
|
+
this.setInputEleProps();
|
|
2105
|
+
}
|
|
2106
|
+
this.changeRtlProps(newProp.enableRtl);
|
|
2107
|
+
break;
|
|
2108
|
+
case 'disabled':
|
|
2109
|
+
this.changeDisabledProp(newProp.disabled);
|
|
2110
|
+
break;
|
|
2111
|
+
case 'value':
|
|
2112
|
+
if (this.value !== oldProp.value) { this.changeValueProp(newProp.value); }
|
|
2113
|
+
break;
|
|
2114
|
+
case 'showButtons':
|
|
2115
|
+
this.changeShowBtnProps(newProp.showButtons);
|
|
2116
|
+
break;
|
|
2117
|
+
case 'mode':
|
|
2118
|
+
if (newProp.mode === 'Picker') {
|
|
2119
|
+
this.switchToPicker();
|
|
2120
|
+
} else {
|
|
2121
|
+
this.switchToPalette();
|
|
2122
|
+
}
|
|
2123
|
+
break;
|
|
2124
|
+
case 'modeSwitcher':
|
|
2125
|
+
this.changeModeSwitcherProp(newProp.modeSwitcher);
|
|
2126
|
+
break;
|
|
2127
|
+
case 'columns':
|
|
2128
|
+
case 'presetColors':
|
|
2129
|
+
if (!this.isPicker()) {
|
|
2130
|
+
this.changePaletteProps();
|
|
2131
|
+
}
|
|
2132
|
+
break;
|
|
2133
|
+
case 'noColor':
|
|
2134
|
+
if (newProp.noColor) {
|
|
2135
|
+
if (this.mode === 'Palette' && !this.modeSwitcher) {
|
|
2136
|
+
this.setNoColor();
|
|
2137
|
+
}
|
|
2138
|
+
} else {
|
|
2139
|
+
this.changePaletteProps();
|
|
2140
|
+
}
|
|
2141
|
+
break;
|
|
2142
|
+
case 'enableOpacity':
|
|
2143
|
+
this.changeOpacityProps(newProp.enableOpacity);
|
|
2144
|
+
break;
|
|
2145
|
+
case 'showRecentColors':
|
|
2146
|
+
if (!newProp.showRecentColors) {
|
|
2147
|
+
const recentClrWpr: HTMLElement = this.container.querySelector('.e-clr-pal-rec-wpr');
|
|
2148
|
+
if (recentClrWpr) { detach(recentClrWpr); }
|
|
2149
|
+
}
|
|
2150
|
+
this.recentColors = [];
|
|
2151
|
+
break;
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
/**
|
|
2157
|
+
* Sets the focus to Colorpicker
|
|
2158
|
+
* its native method
|
|
2159
|
+
*
|
|
2160
|
+
* @public
|
|
2161
|
+
* @returns {void}
|
|
2162
|
+
*/
|
|
2163
|
+
public focusIn(): void {
|
|
2164
|
+
this.element.parentElement.focus();
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
/**
|
|
2169
|
+
* Interface for change / select event.
|
|
2170
|
+
*/
|
|
2171
|
+
export interface ColorPickerEventArgs extends BaseEventArgs {
|
|
2172
|
+
currentValue: { hex: string, rgba: string };
|
|
2173
|
+
previousValue: { hex: string, rgba: string };
|
|
2174
|
+
value?: string;
|
|
2175
|
+
event?: Event;
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
/**
|
|
2179
|
+
* Interface for before change event.
|
|
2180
|
+
*/
|
|
2181
|
+
export interface PaletteTileEventArgs extends BaseEventArgs {
|
|
2182
|
+
element: HTMLElement;
|
|
2183
|
+
presetName: string;
|
|
2184
|
+
value: string;
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
/**
|
|
2188
|
+
* Interface for before open / close event.
|
|
2189
|
+
*/
|
|
2190
|
+
export interface BeforeOpenCloseEventArgs extends BaseEventArgs {
|
|
2191
|
+
element: HTMLElement;
|
|
2192
|
+
event: Event;
|
|
2193
|
+
cancel: boolean;
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
/**
|
|
2197
|
+
* Interface for open event.
|
|
2198
|
+
*/
|
|
2199
|
+
export interface OpenEventArgs extends BaseEventArgs {
|
|
2200
|
+
element: HTMLElement;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
/**
|
|
2204
|
+
* Interface for mode switching event.
|
|
2205
|
+
*/
|
|
2206
|
+
export interface ModeSwitchEventArgs extends BaseEventArgs {
|
|
2207
|
+
element: HTMLElement;
|
|
2208
|
+
mode: string;
|
|
2209
|
+
}
|