1
+ import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDate.js" ;
1
2
import RenderScheduler from "@ui5/webcomponents-base/dist/RenderScheduler.js" ;
2
3
import {
3
4
isF4 ,
4
5
isF4Shift ,
5
6
} from "@ui5/webcomponents-base/dist/Keys.js" ;
7
+ import * as CalendarDateComponent from "./CalendarDate.js" ;
6
8
import CalendarPart from "./CalendarPart.js" ;
7
9
import CalendarHeader from "./CalendarHeader.js" ;
8
10
import DayPicker from "./DayPicker.js" ;
@@ -73,16 +75,36 @@ const metadata = {
73
75
type : Boolean ,
74
76
} ,
75
77
} ,
78
+ managedSlots : true ,
79
+ slots : /** @lends sap.ui.webcomponents.main.Calendar.prototype */ {
80
+ /**
81
+ * Defines the selected date or dates (depending on the <code>selectionMode</code> property) for this calendar as instances of <code>ui5-date</code>
82
+ *
83
+ * @type {HTMLElement[] }
84
+ * @slot
85
+ * @public
86
+ */
87
+ "default" : {
88
+ propertyName : "dates" ,
89
+ type : HTMLElement ,
90
+ invalidateOnChildChange : true ,
91
+ } ,
92
+ } ,
76
93
events : /** @lends sap.ui.webcomponents.main.Calendar.prototype */ {
77
94
/**
78
- * Fired when the selected dates changed.
95
+ * Fired when the selected dates change.
96
+ * <b>Note:</b> If you call <code>preventDefault()</code> for this event, <code>ui5-calendar</code> will not
97
+ * create instances of <code>ui5-date</code> for the newly selected dates. In that case you should do this manually.
98
+ *
79
99
* @event sap.ui.webcomponents.main.Calendar#selected-dates-change
80
- * @param {Array } dates The selected dates timestamps
100
+ * @param {Array } values The selected dates
101
+ * @param {Array } dates The selected dates as UTC timestamps
81
102
* @public
82
103
*/
83
104
"selected-dates-change" : {
84
105
detail : {
85
106
dates : { type : Array } ,
107
+ values : { type : Array } ,
86
108
} ,
87
109
} ,
88
110
} ,
@@ -93,7 +115,14 @@ const metadata = {
93
115
*
94
116
* <h3 class="comment-api-title">Overview</h3>
95
117
*
96
- * The <code>ui5-calendar</code> can be used stand alone to display the years, months, weeks and days
118
+ * The <code>ui5-calendar</code> component allows users to select one or more dates.
119
+ * <br><br>
120
+ * Currently selected dates are represented with instances of <code>ui5-date</code> as
121
+ * children of the <code>ui5-calendar</code>. The value property of each <code>ui5-date</code> must be a
122
+ * date string, correctly formatted according to the <code>ui5-calendar</code>'s <code>formatPattern</code> property.
123
+ * Whenever the user changes the date selection, <code>ui5-calendar</code> will automatically create/remove instances
124
+ * of <code>ui5-date</code> in itself, unless you prevent this behavior by calling <code>preventDefault()</code> for the
125
+ * <code>selected-dates-change</code> event. This is useful if you want to control the selected dates externally.
97
126
* <br><br>
98
127
*
99
128
* <h3>Usage</h3>
@@ -105,7 +134,7 @@ const metadata = {
105
134
* <li>Pressing over an year inside the years view</li>
106
135
* </ul>
107
136
* <br>
108
- * The user can comfirm a date selection by pressing over a date inside the days view.
137
+ * The user can confirm a date selection by pressing over a date inside the days view.
109
138
* <br><br>
110
139
*
111
140
* <h3>Keyboard Handling</h3>
@@ -159,6 +188,7 @@ const metadata = {
159
188
* @alias sap.ui.webcomponents.main.Calendar
160
189
* @extends CalendarPart
161
190
* @tagname ui5-calendar
191
+ * @appenddocs CalendarDate
162
192
* @public
163
193
* @since 1.0.0-rc.11
164
194
*/
@@ -175,6 +205,36 @@ class Calendar extends CalendarPart {
175
205
return calendarCSS ;
176
206
}
177
207
208
+ /**
209
+ * @private
210
+ */
211
+ get _selectedDatesTimestamps ( ) {
212
+ return this . dates . map ( date => {
213
+ const value = date . value ;
214
+ return value && ! ! this . getFormat ( ) . parse ( value ) ? this . _getTimeStampFromString ( value ) / 1000 : undefined ;
215
+ } ) . filter ( date => ! ! date ) ;
216
+ }
217
+
218
+ /**
219
+ * @private
220
+ */
221
+ _setSelectedDates ( selectedDates ) {
222
+ const selectedValues = selectedDates . map ( timestamp => this . getFormat ( ) . format ( new Date ( timestamp * 1000 ) , true ) ) ; // Format as UTC
223
+ const valuesInDOM = [ ...this . dates ] . map ( dateElement => dateElement . value ) ;
224
+
225
+ // Remove all elements for dates that are no longer selected
226
+ this . dates . filter ( dateElement => ! selectedValues . includes ( dateElement . value ) ) . forEach ( dateElement => {
227
+ this . removeChild ( dateElement ) ;
228
+ } ) ;
229
+
230
+ // Create tags for the selected dates that don't already exist in DOM
231
+ selectedValues . filter ( value => ! valuesInDOM . includes ( value ) ) . forEach ( value => {
232
+ const dateElement = document . createElement ( "ui5-date" ) ;
233
+ dateElement . value = value ;
234
+ this . appendChild ( dateElement ) ;
235
+ } ) ;
236
+ }
237
+
178
238
async onAfterRendering ( ) {
179
239
await RenderScheduler . whenFinished ( ) ; // Await for the current picker to render and then ask if it has previous/next pages
180
240
this . _previousButtonDisabled = ! this . _currentPickerDOM . _hasPreviousPage ( ) ;
@@ -237,10 +297,16 @@ class Calendar extends CalendarPart {
237
297
onSelectedDatesChange ( event ) {
238
298
const timestamp = event . detail . timestamp ;
239
299
const selectedDates = event . detail . dates ;
300
+ const datesValues = selectedDates . map ( ts => {
301
+ const calendarDate = CalendarDate . fromTimestamp ( ts * 1000 , this . _primaryCalendarType ) ;
302
+ return this . getFormat ( ) . format ( calendarDate . toUTCJSDate ( ) , true ) ;
303
+ } ) ;
240
304
241
305
this . timestamp = timestamp ;
242
- this . selectedDates = selectedDates ;
243
- this . fireEvent ( "selected-dates-change" , { timestamp, dates : [ ...selectedDates ] } ) ;
306
+ const defaultPrevented = ! this . fireEvent ( "selected-dates-change" , { timestamp, dates : [ ...selectedDates ] , values : datesValues } , true ) ;
307
+ if ( ! defaultPrevented ) {
308
+ this . _setSelectedDates ( selectedDates ) ;
309
+ }
244
310
}
245
311
246
312
onSelectedMonthChange ( event ) {
@@ -267,8 +333,28 @@ class Calendar extends CalendarPart {
267
333
}
268
334
}
269
335
336
+ /**
337
+ * Returns an array of UTC timestamps, representing the selected dates.
338
+ * @protected
339
+ * @deprecated
340
+ */
341
+ get selectedDates ( ) {
342
+ return this . _selectedDatesTimestamps ;
343
+ }
344
+
345
+ /**
346
+ * Creates instances of <code>ui5-date</code> inside this <code>ui5-calendar</code> with values, equal to the provided UTC timestamps
347
+ * @protected
348
+ * @deprecated
349
+ * @param selectedDates Array of UTC timestamps
350
+ */
351
+ set selectedDates ( selectedDates ) {
352
+ this . _setSelectedDates ( selectedDates ) ;
353
+ }
354
+
270
355
static get dependencies ( ) {
271
356
return [
357
+ CalendarDateComponent . default ,
272
358
CalendarHeader ,
273
359
DayPicker ,
274
360
MonthPicker ,
0 commit comments