@@ -4,9 +4,13 @@ import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18
4
4
import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js" ;
5
5
import CSSColor from "@ui5/webcomponents-base/dist/types/CSSColor.js" ;
6
6
import ItemNavigationBehavior from "@ui5/webcomponents-base/dist/types/ItemNavigationBehavior.js" ;
7
+ import { isPhone } from "@ui5/webcomponents-base/dist/Device.js" ;
7
8
import {
8
9
isSpace ,
9
10
isEnter ,
11
+ isDown ,
12
+ isUp ,
13
+ isTabNext ,
10
14
} from "@ui5/webcomponents-base/dist/Keys.js" ;
11
15
import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js" ;
12
16
import ColorPaletteTemplate from "./generated/templates/ColorPaletteTemplate.lit.js" ;
@@ -50,6 +54,28 @@ const metadata = {
50
54
type : Boolean ,
51
55
} ,
52
56
57
+ /**
58
+ * Defines whether the user can choose the default color from a button.
59
+ * @type {boolean }
60
+ * @defaultvalue false
61
+ * @private
62
+ * @since 1.0.0-rc.16
63
+ */
64
+ showDefaultColor : {
65
+ type : Boolean ,
66
+ } ,
67
+
68
+ /**
69
+ * Defines the default color of the color palette
70
+ * <b>Note:</b> The default color should be a part of the ColorPalette colors</code>
71
+ * @type {CSSColor }
72
+ * @private
73
+ * @since 1.0.0-rc.16
74
+ */
75
+ defaultColor : {
76
+ type : CSSColor ,
77
+ } ,
78
+
53
79
/**
54
80
* Defines the selected color.
55
81
* @type {CSSColor }
@@ -58,6 +84,15 @@ const metadata = {
58
84
_selectedColor : {
59
85
type : CSSColor ,
60
86
} ,
87
+
88
+ /**
89
+ * Defines if the palette is in Popup or Embeded mode.
90
+ * @type {CSSColor }
91
+ * @private
92
+ */
93
+ popupMode : {
94
+ type : Boolean ,
95
+ } ,
61
96
} ,
62
97
slots : /** @lends sap.ui.webcomponents.main.ColorPalette.prototype */ {
63
98
/**
@@ -155,10 +190,16 @@ class ColorPalette extends UI5Element {
155
190
this . i18nBundle = getI18nBundle ( "@ui5/webcomponents" ) ;
156
191
this . _itemNavigation = new ItemNavigation ( this , {
157
192
getItemsCallback : ( ) => this . displayedColors ,
158
- rowSize : 5 ,
193
+ rowSize : this . rowSize ,
159
194
behavior : ItemNavigationBehavior . Cyclic ,
160
195
} ) ;
161
196
197
+ this . _itemNavigationRecentColors = new ItemNavigation ( this , {
198
+ getItemsCallback : ( ) => this . recentColorsElements ,
199
+ rowSize : this . rowSize ,
200
+ behavior : ItemNavigationBehavior . Static ,
201
+ } ) ;
202
+
162
203
this . _recentColors = [ ] ;
163
204
}
164
205
@@ -178,6 +219,10 @@ class ColorPalette extends UI5Element {
178
219
}
179
220
180
221
selectColor ( item ) {
222
+ if ( ! item . value ) {
223
+ return ;
224
+ }
225
+
181
226
item . focus ( ) ;
182
227
183
228
if ( this . displayedColors . includes ( item ) ) {
@@ -209,18 +254,122 @@ class ColorPalette extends UI5Element {
209
254
}
210
255
211
256
_onkeyup ( event ) {
212
- if ( isSpace ( event ) ) {
257
+ if ( isSpace ( event ) && event . target . localName === "ui5-color-palette-item" ) {
213
258
event . preventDefault ( ) ;
214
259
this . selectColor ( event . target ) ;
215
260
}
216
261
}
217
262
218
263
_onkeydown ( event ) {
219
- if ( isEnter ( event ) ) {
264
+ if ( isEnter ( event ) && event . target . localName === "ui5-color-palette-item" ) {
220
265
this . selectColor ( event . target ) ;
221
266
}
222
267
}
223
268
269
+ _onDefaultColorKeyDown ( event ) {
270
+ if ( isTabNext ( event ) && this . popupMode ) {
271
+ event . preventDefault ( ) ;
272
+ this . _onDefaultColorClick ( ) ;
273
+ }
274
+
275
+ if ( isDown ( event ) ) {
276
+ event . stopPropagation ( ) ;
277
+
278
+ this . focusColorElement ( this . colorPaletteNavigationElements [ 1 ] , this . _itemNavigation ) ;
279
+ } else if ( isUp ( event ) ) {
280
+ event . stopPropagation ( ) ;
281
+ const lastElementInNavigation = this . colorPaletteNavigationElements [ this . colorPaletteNavigationElements . length - 1 ] ;
282
+
283
+ if ( this . hasRecentColors ) {
284
+ this . focusColorElement ( lastElementInNavigation , this . _itemNavigationRecentColors ) ;
285
+ } else if ( this . showMoreColors ) {
286
+ lastElementInNavigation . focus ( ) ;
287
+ } else {
288
+ const colorPaletteFocusIndex = ( this . displayedColors . length % this . rowSize ) * this . rowSize ;
289
+
290
+ this . focusColorElement ( this . displayedColors [ colorPaletteFocusIndex ] , this . _itemNavigation ) ;
291
+ }
292
+ }
293
+ }
294
+
295
+ _onMoreColorsKeyDown ( event ) {
296
+ const index = this . colorPaletteNavigationElements . indexOf ( event . target ) ;
297
+ const colorPaletteFocusIndex = ( this . displayedColors . length % this . rowSize ) * this . rowSize ;
298
+
299
+ if ( isUp ( event ) ) {
300
+ event . stopPropagation ( ) ;
301
+
302
+ this . focusColorElement ( this . displayedColors [ colorPaletteFocusIndex ] , this . _itemNavigation ) ;
303
+ } else if ( isDown ( event ) ) {
304
+ event . stopPropagation ( ) ;
305
+
306
+ if ( this . hasRecentColors ) {
307
+ this . focusColorElement ( this . colorPaletteNavigationElements [ index + 1 ] , this . _itemNavigationRecentColors ) ;
308
+ } else if ( this . showDefaultColor ) {
309
+ this . colorPaletteNavigationElements [ 0 ] . focus ( ) ;
310
+ } else {
311
+ this . focusColorElement ( this . displayedColors [ 0 ] , this . _itemNavigation ) ;
312
+ }
313
+ }
314
+ }
315
+
316
+ _onColorContainerKeyDown ( event ) {
317
+ const lastElementInNavigation = this . colorPaletteNavigationElements [ this . colorPaletteNavigationElements . length - 1 ] ;
318
+ if ( isTabNext ( event ) && this . popupMode ) {
319
+ event . preventDefault ( ) ;
320
+ this . selectColor ( event . target ) ;
321
+ }
322
+
323
+ if ( isUp ( event ) && event . target === this . displayedColors [ 0 ] && this . colorPaletteNavigationElements . length > 1 ) {
324
+ event . stopPropagation ( ) ;
325
+ if ( this . showDefaultColor ) {
326
+ this . colorPaletteNavigationElements [ 0 ] . focus ( ) ;
327
+ } else if ( ! this . showDefaultColor && this . hasRecentColors ) {
328
+ this . focusColorElement ( lastElementInNavigation , this . _itemNavigationRecentColors ) ;
329
+ } else if ( ! this . showDefaultColor && this . showMoreColors ) {
330
+ lastElementInNavigation . focus ( ) ;
331
+ }
332
+ } else if ( isDown ( event ) && event . target === this . displayedColors [ this . displayedColors . length - 1 ] && this . colorPaletteNavigationElements . length > 1 ) {
333
+ event . stopPropagation ( ) ;
334
+ const isRecentColorsNextElement = ( this . showDefaultColor && ! this . showMoreColors && this . hasRecentColors ) || ( ! this . showDefaultColor && ! this . showMoreColors && this . hasRecentColors ) ;
335
+
336
+ if ( this . showDefaultColor && this . showMoreColors ) {
337
+ this . colorPaletteNavigationElements [ 2 ] . focus ( ) ;
338
+ } else if ( this . showDefaultColor && ! this . showMoreColors && ( ! this . showRecentColors || ! this . recentColors [ 0 ] ) ) {
339
+ this . colorPaletteNavigationElements [ 0 ] . focus ( ) ;
340
+ } else if ( isRecentColorsNextElement ) {
341
+ this . focusColorElement ( lastElementInNavigation , this . _itemNavigationRecentColors ) ;
342
+ } else if ( ! this . showDefaultColor && this . showMoreColors ) {
343
+ this . colorPaletteNavigationElements [ 1 ] . focus ( ) ;
344
+ }
345
+ }
346
+ }
347
+
348
+ _onRecentColorsContainerKeyDown ( event ) {
349
+ if ( isUp ( event ) ) {
350
+ if ( this . showMoreColors ) {
351
+ this . colorPaletteNavigationElements [ 1 + this . showDefaultColor ] . focus ( ) ;
352
+ } else if ( ! this . showMoreColors && this . colorPaletteNavigationElements . length > 1 ) {
353
+ const colorPaletteFocusIndex = ( this . displayedColors . length % this . rowSize ) * this . rowSize ;
354
+ event . stopPropagation ( ) ;
355
+
356
+ this . focusColorElement ( this . displayedColors [ colorPaletteFocusIndex ] , this . _itemNavigation ) ;
357
+ }
358
+ } else if ( isDown ( event ) ) {
359
+ if ( this . showDefaultColor ) {
360
+ this . colorPaletteNavigationElements [ 0 ] . focus ( ) ;
361
+ } else {
362
+ event . stopPropagation ( ) ;
363
+ this . focusColorElement ( this . displayedColors [ 0 ] , this . _itemNavigation ) ;
364
+ }
365
+ }
366
+ }
367
+
368
+ focusColorElement ( element , itemNavigation ) {
369
+ itemNavigation . setCurrentItem ( element ) ;
370
+ itemNavigation . _focusCurrentItem ( ) ;
371
+ }
372
+
224
373
async _chooseCustomColor ( ) {
225
374
const colorPicker = await this . getColorPicker ( ) ;
226
375
this . _setColor ( colorPicker . color ) ;
@@ -237,6 +386,12 @@ class ColorPalette extends UI5Element {
237
386
dialog . show ( ) ;
238
387
}
239
388
389
+ _onDefaultColorClick ( ) {
390
+ if ( this . defaultColor ) {
391
+ this . _setColor ( this . defaultColor ) ;
392
+ }
393
+ }
394
+
240
395
/**
241
396
* Returns the selected color.
242
397
*/
@@ -245,7 +400,7 @@ class ColorPalette extends UI5Element {
245
400
}
246
401
247
402
get displayedColors ( ) {
248
- return this . colors . filter ( item => item . value ) . slice ( 0 , 15 ) ;
403
+ return this . getSlottedNodes ( " colors" ) . filter ( item => item . value ) . slice ( 0 , 15 ) ;
249
404
}
250
405
251
406
get colorContainerLabel ( ) {
@@ -260,18 +415,64 @@ class ColorPalette extends UI5Element {
260
415
return this . showMoreColors && this . moreColorsFeature ;
261
416
}
262
417
418
+ get rowSize ( ) {
419
+ return 5 ;
420
+ }
421
+
422
+ get hasRecentColors ( ) {
423
+ return this . showRecentColors && this . recentColors [ 0 ] ;
424
+ }
425
+
263
426
get recentColors ( ) {
264
- if ( this . _recentColors . length > 5 ) {
265
- this . _recentColors = this . _recentColors . slice ( 0 , 5 ) ;
427
+ if ( this . _recentColors . length > this . rowSize ) {
428
+ this . _recentColors = this . _recentColors . slice ( 0 , this . rowSize ) ;
266
429
}
267
430
268
- while ( this . _recentColors . length < 5 ) {
431
+ while ( this . _recentColors . length < this . rowSize ) {
269
432
this . _recentColors . push ( "" ) ;
270
433
}
271
434
272
435
return this . _recentColors ;
273
436
}
274
437
438
+ get recentColorsElements ( ) {
439
+ if ( this . getDomRef ( ) ) {
440
+ return Array . from ( this . getDomRef ( ) . querySelectorAll ( ".ui5-cp-recent-colors-wrapper [ui5-color-palette-item]" ) ) . filter ( x => x . value !== "" ) ;
441
+ }
442
+
443
+ return [ ] ;
444
+ }
445
+
446
+ get colorPaletteNavigationElements ( ) {
447
+ const navigationElements = [ ] ;
448
+ const rootElement = this . shadowRoot . querySelector ( ".ui5-cp-root" ) ;
449
+
450
+ if ( this . showDefaultColor ) {
451
+ navigationElements . push ( rootElement . querySelector ( ".ui5-cp-default-color-button" ) ) ;
452
+ }
453
+
454
+ navigationElements . push ( this . displayedColors [ 0 ] ) ;
455
+
456
+ if ( this . showMoreColors ) {
457
+ navigationElements . push ( rootElement . querySelector ( ".ui5-cp-more-colors" ) ) ;
458
+ }
459
+
460
+ if ( this . showRecentColors && ! ! this . recentColorsElements . length ) {
461
+ navigationElements . push ( this . recentColorsElements [ 0 ] ) ;
462
+ }
463
+
464
+ return navigationElements ;
465
+ }
466
+
467
+ get classes ( ) {
468
+ return {
469
+ colorPaletteRoot : {
470
+ "ui5-cp-root" : true ,
471
+ "ui5-cp-root-phone" : isPhone ( ) ,
472
+ } ,
473
+ } ;
474
+ }
475
+
275
476
async _getDialog ( ) {
276
477
const staticAreaItem = await this . getStaticAreaItemDomRef ( ) ;
277
478
return staticAreaItem . querySelector ( "[ui5-dialog]" ) ;
0 commit comments